среда, 28 февраля 2018 г.

Python: история как VSCode "сломал" Pytest внутри docker контейнера.

Свежий детектив из жизни программиста о "магии" и ее разоблачении

Место преступления

Окружение рабочего проекта для разработки представляет собой docker-compose проект поднимающий набор контейнеров, главный из которых это разрабатываемое веб приложение. На этот контейнер прокидывается директория с проектом из основной машины. Таким образом, код пишется в редакторе на хост машине, а выполняется в контейнере. Соответственно используемый для тестирования фреймворк pytest запускается внутри контейнера.

Преступление

В очередной раз работая над проектом я создал новый тест, запустил его, убедился что все работает хорошо. Далее я, по неосторожности, забыв что тесты выполняются в контейнере, а не на хост машине, решил настроить VSCode на запуск тестов (не столько даже забыл сколько перепутал, так как другие проекты не используют докер в разработке). Увидев результат я быстро понял что сглупил и отключил запуск тестов. 
Однако, вернувшись в контейнер я обнаружил что pytest не смог запустить тесты, так как не нашел корневой conftest.py файл. Разумеется сам файл никуда не делся, однако тесты не запускаются совсем.
Внимательнее посмотрев на трейсбек ошибки становится понятно, что при определении пути до файла pytest трансформировал путь (условно) с уровня ФС контейнера /srv/src/app  в уровень ФС хост машины /Users/john_16/app. 
То есть, каким то образом pytest внутри контейнера начинает знать о хост машине. Такого быть не должно. Понимая что что-то пошло не так после  манипуляций VSCode продолжаю разбираться.

Расследование

Осмотр на предмет каких либо модифицированных конфигов и тп результатов не дал. Результат не изменился и после сброс всех изменений в git.Получается проект в нормальном рабочем состоянии, но тесты не запускаются. 
Идём дальше. Очищаю все контейнеры, пересобираю проект с нуля. Результат тот же. А давай ка вспомню классику IT сферы и выражение "пробовали выключить и включить снова" - перегружаю макбук. Результат тот же. 
Подключаю к мозговому штурму опытного тимлида. Все опробованные варианты отметаем; еще какая то пачка манипуляций результата не дала.
Соглашаемся что какая то магия. Я создаю на хост машине свежую папку с проектом и поднимаю контейнеры. Заработало! То есть, что бы это за магия не была, она живет именно в директории проекта.
Открываю редактор, проделываю те же операции и тесты снова не запускаются! Проблема воспроизведена! Это хороший знак. Появляется некий спортивный интерес найти и разобраться. Начинаем на пару думать дальше и смотрим еще раз внимательно на файлы внутри директории с проектом которые поменялись за последние пару минут (временная граница между рабочим и не рабочим запуском тестов). Ничего такого find казалось бы не нашел, только уведомил про бинарные файлы в __pycache__ директориях. Стоп. Кэш? Удаляем эти файлы и все работает. Win! Победа над магией.

Что же произошло?

Когда  VSCode запустил pytest на хостовой машине, последний прошелся по всему проекту и нагенерил питонячий кэш. Pytest внутри докера при запуске увидел кэш и воспользовался им. Факт разных ОС не смутил никого, так как питоний байт код оказался прямо совместим в виду платформо независимости. Содержимое кэша имело некие данные в которых были абсолютные пути, которые отличаются в зависимости от окружения. Вот тут и произошло падение.

Выводы

Убийца садовник  В жизни порой случаются необычные и загадочные вещи, но сколь не была таинственна их природа, все познается. И магия окажется лишь ловкостью рук неординарной совокупностью известных фактов.

0 коммент.:

Отправить комментарий