Ссылка на оригинал тестового задания
- OS: Linux
- Дистрибутив: Arch Linux
- Язык программирования: Go v1.22.1
- БД: Postgres v16.2
- Сторонние библиотеки:
- google uuid - реализация UUID для Golang
- godotenv - загрузчик переменных окружения
- lib/pq - драйвер PostgreSQL для Golang пакета
database/sql
- testify - набор утилит для упрощения тестирования. Одной из причин использования этой библиотеки было тестирование с использованием mock объектов, реализация которых зависит от testify
- Утилиты:
- Docker - приложение собирается в контейнер (об этом ниже), в качестве базы данных используется готовый docker-образ Postgres
В приложении присутствуют две сущности, разбитые по соответствующим точкам входа
Команда из себя представляет bash-скрипт, точнее код скрипта, который в дальнейшем может быть исполнен. Доступны действия:
- Сохранение новой команды
- Получение списка уже сохраненных команд
- Получение конкретной команды по
id
- Удаление конкретной команды по
id
.
После сохранения команды, ее можно исполнить. Таким образом будет порожден процесс - исполняемая сохраненная команда. Пользователь отправляет id
команды, которую он хочет исполнить. Если при запуске команды не произошло ошибок, то вернется идентификатор процесса - UUID. По этому идентификатору можно отслеживать информацию о запущенной команде:
- Вывод команды (stdout)
- Ошибки команды (stderr)
- Статус команды (выполняется, завершена, завершена с ошибкой)
- Код ошибки
Процесс можно остановить вместе с удалением всего результата работы. Это сделано с целью сохранения идемпотентности метода DELETE
. Для остановки и удаления процесса достаточно знать его id
. Если процесс был уже завершен, то удалится результат его работы.
Сборка и запуск проекта будут осуществляться с помощью Makefile
. Список всех доступных команд и их описание можно посмотреть при помощи команды make
:
make env
- запустить скрипт задания переменных окружения (используются как в docker, так и для локального запуска)- Для запуска локально (не рекомендуется):
make docker/compose/up/db
- запустить контейнер с postgresmake migrate/up
, либоmake docker/compose/up/migrate
- применить миграции к базе данных: локально (нужны правильно заданные переменные окруженияPOSTGRES_HOST
иPOSTGRES_PORT
), либо с помощью контейнераmake run
- запустить приложение
- Для запуска в контейнере:
make docker/build
- собрать приложение, запустить все тесты, скопировать файлы (конфиги, переменные окружения), подготовить образmake docker/compose/up
илиdocker compose -f docker-compose.yml up
- создать все контейнеры на основеdocker-compose.yml
- Подождать несколько секунд (обычно не более 7), пока применятся миграции и запустится приложение (это нужно потому, что и приложение, и контейнер с миграциями ждут пока проинициализируется база данных, чтобы не завершиться с ошибкой
connection refused
)
Приложение покрыто двумя видами тестов: модульные и интеграционные
Все модульные тесты находятся рядом с кодом, который они тестируют. Для генерации mock-объектов использовалась библиотека mockery. Все mock-объекты находятся в отдельном пакете с названием mocks тоже рядом с тестируемым кодом.
Модульными тестами покрыты обработчики и сервисы.
Запуск модульных тестов происходит автоматически при создании docker-образа проекта. Также их можно запустить самостоятельно с помощью команды make test/unit
Интеграционные тесты находятся в директории tests
. Так как интеграционное тестирование подразумевает использование запущенной сущности приложения, то данный вид тестирования не происходит автоматически. Для корректного выполнения тестов база данных должна быть пустой
Запуск интеграционных тестов происходит при помощи команды make test/integration
Для получения дополнительной информации о проекте можно посмотреть:
- ADR - Architecture Decision Records - архитектурные решения в проекте с пояснениями
- Схему запросов Postman
- .http файлы - новый способ задания клиентских запросов от JetBrains
P.S. ADR появилось так поздно только потому, что с утилитой для их разметки я познакомился только недавно, хотя наброски были уже давно
Список проблем, которые можно исправить:
- Полная свобода пользователя внутри контейнера (внутри контейнера пользователь может вводить любые команды, включая
rm /bin/bash
)
Список того, что можно добавить в проект, но не получилось по разным причинам:
- Добавление swagger ui (была попытка с помощью
swaggo/swag
, но он не смог найти файлы в корне проекта)