# README
Исполнитель команд (bash-скриптов)
postgres-command-executor
Ссылка на оригинал тестового задания
Используемые технологии:
- 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
Функционал
В приложении присутствуют две сущности, разбитые по соответствующим точкам входа
Команды (commands)
Команда из себя представляет bash-скрипт, точнее код скрипта, который в дальнейшем может быть исполнен. Доступны действия:
- Сохранение новой команды
- Получение списка уже сохраненных команд
- Получение конкретной команды по
id
- Удаление конкретной команды по
id
.
Процессы (processes)
После сохранения команды, ее можно исполнить. Таким образом будет порожден процесс - исполняемая сохраненная команда. Пользователь отправляет 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
, но он не смог найти файлы в корне проекта)