Pull to refresh

Comments 9

Все началось с того, что я в очередной раз немного поменял...

Лучшее начало статьи - сохраню себе в памятку! очень открывательная строка. Уверен, что с этого начинаются все увлекательные приключения!.. Пардонюсь за оффтопик, тесты еще надкусываю, тут две статьи подряд погрызть.

Чтобы не мучаться с перезаписью кода в памяти уже работающего приложения, я попробовал другой метод: сделать копию бинарника, в котором тело (даже не всё, хватило самого начала) "оригинальной" функции поменять на JMP в ту, на которую подменяем и запустить уже его с дополнительной переменной. Это делается существенно проще, однако теряется возможность вызвать оригинал. Даже библиотеку написал под это.

Для моей задачи это не годится. Во-первых, это лишает возможности тестировать в один шаг, например, прямо из VS Code - надо сначала вызвать go test -c, пропатчить бинарник, и потом его запустить. Во-вторых, тогда надо сразу все пропатчить, и тогда нет возможности контролировать правильный порядок вызова моков.

Я подобное предусматривал: запуск пропатченного бинарника происходит силами библиотеки, все аргументы пробрасываются без изменений, дополнительно делать ничего не требуется.

Почему бы не сделать интеграционные тесты вместо моков БД? Это немного дольше в плане прогона тестов. Однако вы не будете ловить таких проблем при миграциях и сэкономите много человеческого ресурса, т.к. не придется делать/менять моки. Можно запустить докер контейнер с нужной БД, если нет желания ставить в систему. CI докер-контейнеры тоже умеет запускать

Интеграционные тесты - не замена unit-тестам, это разные инструменты. Unit-тесты позволяют быстро убедиться, что новая функциональность ничего не сломала, они отрабатывают быстро и не требуют никакой особой среды, у меня это уже на уровне рефлексов - поменял что-то, запустил unit-тесты. И с помощью unit-тестов намного легче тестировать какие-то ненормальные ситуации, которые при нормальной эксплуатации случаться не должны. По поводу ресурса - для интеграционного тестирования тоже надо писать кейсы, и не факт, что они будут проще моков, особенно когда надо проверить какие-то вещи с параллельной обработкой

Неплохо! Я для интереса тоже как-то делал очень похожее, но чтобы было на уровне исходного кода: https://habr.com/ru/articles/328620/

Мой подход, к сожалению, не работает с go modules начиная с 1.11, но это должно быть можно исправить :). Поддерживаются любые операционные системы, но go нужно запускать через враппер, который добавляет в каждую функцию проверки, а-ля unconditional jump инструкция, но без привязки к конкретной архитектуре процессора.

Always call sys_icache_invalidate(::) before you execute the machine instructions on a recently updated memory page.

Вообще, отсутствие автоматической связи здесь и есть если не норма, то по крайней мере то, что надо всегда предполагать. X86 с его TSO и кучей моментов неявной автопомощи программисту здесь исключение (во многом себе во вред) даже для мира CISC.

Я исходил из предположения, что поскольку для data cache'ей это работает (а иначе в принципе многопроцессорная/многоядерная обработка была бы невозможна, ну только если всегда пинить ядра на процессы), то и для instruction cache'а оно тоже так, то есть раз механизм инвалидации кэша есть, почему бы его не использовать везде. Но я действительно слабо знаком с другими архитектурами (когда-то работал с PowerPC и PA-RISC'ами, но не на таком низком уровне), возможно, я испорчен X86

Sign up to leave a comment.

Articles