Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 103 additions & 17 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,34 +179,120 @@ jobs:
go test -count=1 ./...

- name: Снимок содержит числа, а не прочерки
# ЯЗЫК СНИМКА ЗАДАЁТСЯ, А НЕ НАСЛЕДУЕТСЯ, и это не мелочь оформления.
#
# Прежняя редакция шага брала снимок на языке машины и искала в нём
# РУССКИЕ слова с АНГЛИЙСКОЙ десятичной точкой («занято ЦП 10.7%») —
# сочетание, которого инструмент не печатает ни на одном языке с тех
# пор, как заговорил на двух: слова стали зависеть от языка, а
# разделитель дробной части — тоже (10,7% против 10.7%). На маковском
# бегунке LANG не задан, язык по умолчанию английский, и шаг три дня
# докладывал «НЕТ ЧИСЛА» о числах, стоявших в той же строке журнала.
# Числа при этом снимались и снимаются: их проверяет шаг выше,
# TestProcessesAreMeasured на живой машине.
#
# Поэтому здесь `--lang`, и обе редакции сразу: дерево обещает полный
# перевод, и снимок, полный по-русски и пустой по-английски, —
# сломанный снимок.
#
# Образцы ниже сверяются с печатью на Linux: host/snapshot_numbers_test.go
# читает ЭТОТ файл, печатает снимок, в котором всё замерено, и валится,
# если хоть один образец отсюда в нём не находится. Так строка здесь не
# разойдётся с переводом молча ещё раз.
run: |
cd host
go build -o "$RUNNER_TEMP/digitdisk" .
"$RUNNER_TEMP/digitdisk" status --sample 300 | tee "$RUNNER_TEMP/status.txt"
fail=0
mkdir -p "$RUNNER_TEMP/snapshot" "$RUNNER_TEMP/nothing"
for l in ru en; do
# Без трубы нарочно: `| tee` отдаёт код возврата tee, и упавший
# снимок доехал бы сюда пустым файлом и молчаливым нулём.
"$RUNNER_TEMP/digitdisk" status --sample 300 --lang "$l" > "$RUNNER_TEMP/snapshot/status.$l.txt"
cat "$RUNNER_TEMP/snapshot/status.$l.txt"
: > "$RUNNER_TEMP/nothing/status.$l.txt"
done

# need — строка ОБЯЗАНА нести число: это то, что на маке снимается.
# named — строка ОБЯЗАНА назвать словом то, чего на маке взять нечем:
# непокрытое называется, а не выдаётся за поломку.
# Обе смотрят в $WHERE, чтобы одного и того же сторожа можно было
# натравить и на снимок, и на заведомо пустой файл.
need() {
grep -qE "$1" "$RUNNER_TEMP/status.txt" || { echo "НЕТ ЧИСЛА: $2" >&2; fail=1; }
total=$((total + 1))
grep -qE "$2" "$WHERE/status.$1.txt" || { echo "НЕТ ЧИСЛА [$1]: $3" >&2; bad=$((bad + 1)); }
}
named() {
total=$((total + 1))
grep -qE "$2" "$WHERE/status.$1.txt" || { echo "НЕ НАЗВАНО [$1]: $3" >&2; bad=$((bad + 1)); }
}
need 'занято ЦП [0-9]+\.[0-9]%' 'доля занятого процессора'
need 'свободно [0-9]' 'свободная память'
need 'кэш/буферы [0-9]' 'файловый кэш'
need 'доступно [0-9]' 'доступная память'
need 'закреплённая [0-9]' 'закреплённая память'
need 'сжатая [0-9]' 'сжатая память'
need 'потоков [0-9]' 'число потоков'
need 'выполняется [0-9]' 'сколько процессов работает'
need 'десятка по памяти' 'десятка по памяти'
need 'десятка по процессору' 'десятка по процессору'
exit $fail
guard() {
total=0
bad=0
need ru 'занято ЦП [0-9]+,[0-9]%' 'доля занятого процессора'
need ru 'свободно [0-9]' 'свободная память'
need ru 'кэш/буферы [0-9]' 'файловый кэш'
need ru 'доступно [0-9]' 'доступная память'
need ru 'закреплённая [0-9]' 'закреплённая память'
need ru 'сжатая [0-9]' 'сжатая память'
need ru 'потоков [0-9]' 'число потоков'
need ru 'выполняется [0-9]' 'сколько процессов работает'
need ru ' десятка по памяти:' 'десятка по памяти'
need ru '^ +[0-9]+ [^ ]+ +[0-9]+,[0-9] [КМГТ]иБ ' 'в десятке по памяти стоит размер'
need ru ' десятка по процессору:' 'десятка по процессору'
need ru '^ +[0-9]+ [^ ]+ +[0-9]+,[0-9]% ' 'в десятке по процессору стоит доля'
need en 'CPU busy [0-9]+\.[0-9]%' 'доля занятого процессора'
need en 'free [0-9]' 'свободная память'
need en 'cache/buffers [0-9]' 'файловый кэш'
need en 'available [0-9]' 'доступная память'
need en 'wired [0-9]' 'закреплённая память'
need en 'compressed [0-9]' 'сжатая память'
need en 'threads [0-9]' 'число потоков'
need en 'running [0-9]' 'сколько процессов работает'
need en ' top ten by memory:' 'десятка по памяти'
need en '^ +[0-9]+ [^ ]+ +[0-9]+\.[0-9] [KMGT]iB ' 'в десятке по памяти стоит размер'
need en ' top ten by processor:' 'десятка по процессору'
need en '^ +[0-9]+ [^ ]+ +[0-9]+\.[0-9]% ' 'в десятке по процессору стоит доля'
named ru 'НЕ ИЗМЕРЕНО .*заблокированные процессы' 'заблокированные процессы'
named ru 'НЕ ИЗМЕРЕНО .*датчики температуры' 'датчики температуры'
named en 'NOT MEASURED .*blocked processes' 'заблокированные процессы'
named en 'NOT MEASURED .*temperature sensors' 'датчики температуры'
# Приговор выносится по $bad ниже, а не кодом возврата: шаг идёт
# под `bash -e`, и сторож, который вернул бы ненулевой код на
# отрицательном контроле, оборвал бы прогон до самой проверки.
return 0
}

# ОТРИЦАТЕЛЬНЫЙ КОНТРОЛЬ, и он здесь ровно потому, что беда была
# именно такой: сторож, который не умеет упасть, три дня выглядел
# работающим. На пустом снимке обязан заругаться КАЖДЫЙ образец —
# не «хотя бы один»: образец, срабатывающий на пустоте, проверяет
# не число, а собственную формулировку.
WHERE="$RUNNER_TEMP/nothing"
guard 2>/dev/null
if [ "$bad" -ne "$total" ]; then
echo "На пустом снимке смолчали $((total - bad)) образцов из $total." >&2
echo "Эти образцы ничего не проверяют — их надо чинить, а не зеленить." >&2
exit 1
fi
echo "отрицательный контроль: на пустом снимке ругаются все $total образцов"

# А теперь приговор — по настоящему снимку.
WHERE="$RUNNER_TEMP/snapshot"
guard
echo "проверено образцов: $total, не нашлось: $bad"
exit $(( bad > 0 ))

- name: В выводе нет инженерного дневника
# Сторож против того, ради чего всё это и переписано: пользователю —
# число или прочерк, а объяснения — только по `--why`.
# число или прочерк, а объяснения — только по `--why`. Смотрит в ОБЕ
# редакции: имя системного вызова одинаково выглядит на любом языке, а
# приехать в снимок может через любую из двух половин словаря.
run: |
cd host
if grep -nE 'Mach|cgo|sysctl|IOKit|libproc|host_statistics|proc_pidinfo|kinfo_proc|KERN_PROCARGS' "$RUNNER_TEMP/status.txt"; then
if grep -nE 'Mach|cgo|sysctl|IOKit|libproc|host_statistics|proc_pidinfo|kinfo_proc|KERN_PROCARGS' \
"$RUNNER_TEMP/snapshot/status.ru.txt" "$RUNNER_TEMP/snapshot/status.en.txt"; then
echo "В снимке снова объяснения вместо чисел." >&2
exit 1
fi
"$RUNNER_TEMP/digitdisk" status --why
"$RUNNER_TEMP/digitdisk" status --why --lang ru
"$RUNNER_TEMP/digitdisk" status --why --lang en
"$RUNNER_TEMP/digitdisk" status --json > /dev/null
Loading
Loading