[hw-2] add tests, coverage, benchmarks

This commit is contained in:
Никита Шубин
2025-05-31 10:47:47 +00:00
parent 1a3d4892a8
commit a0e36639ca
22 changed files with 3058 additions and 48 deletions

View File

@@ -2,7 +2,7 @@
## Введение
В рамках учебного проекта предстоит реализовать систему, состоящую из нескольких сервисов, которая
В рамках учебного проекта предстоит реализовать систему, состоящую из нескольких сервисов, которая
будет моделировать работу простого интернет магазина включая такие бизнес процессы как:
- добавление товаров в корзину и их удаление из нее
@@ -15,4 +15,4 @@
## Содержание
1. [Основы Go](./homework-1)
2. [Тестирование в Go](./homework-2)

View File

@@ -4,13 +4,13 @@
## Основное задание
Необходимо имплементировать сервис, отвечающий за работу с корзиной пользователя (сервис Cart). Логика работы методов
Необходимо имплементировать сервис, отвечающий за работу с корзиной пользователя (сервис Cart). Логика работы методов
и их контракты описаны ниже.
Требования к решению:
1. Используем HTTP, на основе стандартной библиотеки Go 1.23
2. Для определения существования товара делаем поход в сервис `products`
2. Для определения существования товара делаем поход в сервис `product-service`
3. Состояние храним в in-memory, персистентное хранилище на данный момент не требуется
4. Никакого резерва стоков не делаем, логика простейшая
@@ -19,13 +19,13 @@
1. Делаем Middleware, который будет логировать поступающие запросы
2. Делаем валидацию входящих структур на основе любой Open Source библиотеки (можно подсмотреть
тут - https://awesome-go.com/validation/)
3. Делаем ретраи в `products` на 420/429 статус в виде Client Middleware. 3 ретрая, потом ошибка
3. Делаем ретраи в `product-service` на 420/429 статус в виде Client Middleware. 3 ретрая, потом ошибка
## Спецификация
### Добавить товар в корзину
Идентификатором товара является числовой идентификатор SKU. Метод добавляет указанный товар в корзину
Идентификатором товара является числовой идентификатор SKU. Метод добавляет указанный товар в корзину
определенного пользователя. Каждый пользователь имеет числовой идентификатор userID. При добавлении в корзину
проверяем, что товар существует в специальном сервисе.
@@ -54,7 +54,7 @@
| Добавление валидного SKU для пользователя (user_id) с нулевым или отрицательным значением | 400 | Идентификатор пользователя должен быть натуральным числом (больше нуля) |
| Добавление SKU с нулевым или отрицательным значением | 400 | SKU должен быть натуральным числом (больше нуля) |
| Добавление SKU с нулевым или отрицательным количеством (count) | 400 | Количество должно быть натуральным числом (больше нуля) |
| Добавление несуществующего SKU в корзину | 412 | SKU должен существовать в сервисе `products` |
| Добавление несуществующего SKU в корзину | 412 | SKU должен существовать в сервисе `product-service` |
**Диаграмма последовательности:**
@@ -63,7 +63,7 @@
### Удалить товар из корзины
Метод полностью удаляет все количество товара из корзины пользователя. Если у пользователя вовсе нет данной позиции,
Метод полностью удаляет все количество товара из корзины пользователя. Если у пользователя вовсе нет данной позиции,
то возвращается такой же ответ, как будто бы все позиции данного sku были успешно удалены.
| Метод | URI |
@@ -95,7 +95,7 @@
### Очистить корзину пользователя
Метод полностью очищает корзину пользователя. Если у пользователя нет корзины или она пуста, то, как и при успешной
Метод полностью очищает корзину пользователя. Если у пользователя нет корзины или она пуста, то, как и при успешной
очистке корзины, необходимо вернуть код ответа 204 No Content.
| Метод | URI |
@@ -125,7 +125,7 @@
### Получить содержимое корзины
Метод возвращает содержимое корзины пользователя на текущий момент. Если корзины у переданного пользователя нет,
Метод возвращает содержимое корзины пользователя на текущий момент. Если корзины у переданного пользователя нет,
либо она пуста, следует вернуть 404 код ответа. Товары в корзине упорядочены в порядке возрастания sku.
| Метод | URI |
@@ -188,14 +188,14 @@
Если, вызвав `make run-all`, развернуть деплоймент, swagger этого сервиса
можно увидеть локально по адресу: [http://localhost:8082/docs/](http://localhost:8082/docs/)
Сервис поддерживает следующие операции:
Сервис поддерживает следующие операции:
#### GET /product?count=10&start_after_sku=0
Эта операция имеет два необязательных параметра:
- `count` — сколько элементов вернуть и
- `start_after_sku` — после какого элемента начать вывод.
Эта операция имеет два необязательных параметра:
- `count` — сколько элементов вернуть и
- `start_after_sku` — после какого элемента начать вывод.
Response:
```
@@ -221,25 +221,25 @@ Response:
}
```
Обратите внимание, сервис `products` отдаёт цены в `int32` формате.
Обратите внимание, сервис `product-service` отдаёт цены в `int32` формате.
В JSON нет беззнаковых целых, поэтому `int32`.
Вам же, внутри своих сервисов, для совместимости их между собой
следует использовать беззнаковый тип `uint32`.
следует использовать беззнаковый тип `uint32`.
Также следует обратить внимание на то, что он выведен на `localhost:8082` лишь
для вашего удобства работы с данными.
для вашего удобства работы с данными.
Ваш сервис `cart`, запущенный докер-контейнером, сможет подключиться к `products`
по адресу `products:8082` — заниматься маршрутизацией будет сам докер.
Ваш сервис `cart`, запущенный докер-контейнером, сможет подключиться к `product-service`
по адресу `product-service:8082` — заниматься маршрутизацией будет сам докер.
Авторизация на запрос выполняется с помощью заголовка `X-API-KEY` и токена `testToken`.
Авторизация на запрос выполняется с помощью заголовка `X-API-KEY` и токена `testToken`.
## Makefile
В рамках данного задания необходимо имплементировать следующие таргеты:
- run-all — запускает сервисы. На данный момент их должно стать два:
- `products` — уже реализован
- run-all — запускает сервисы. На данный момент их должно стать два:
- `product-service` — уже реализован
- `cart` — разрабатываемый вами в качестве домашнего задания
## Ожидаемый результат
@@ -270,5 +270,5 @@ Response:
Сценарий тестирования следует описать в [cart.http](./cart.http)
### Дедлайны сдачи и проверки задания:
### Дедлайны сдачи и проверки задания:
- 24 мая 23:59 (сдача) / 27 мая, 23:59 (проверка)

View File

@@ -66,7 +66,7 @@ Content-Type: application/json
### delete whole sku from cart
DELETE http://localhost:8080/user/31337/cart/1076963
Content-Type: application/json
### expected {} 200 OK; must delete item from cart
### expected {} 204 No Content; must delete item from cart
### delete whole cart
DELETE http://localhost:8080/user/31337/cart

33
docs/homework-2/README.md Normal file
View File

@@ -0,0 +1,33 @@
# Домашнее задание по модулю "Тестирование в Go"
Необходимо покрыть Unit-тестами слой `UseCase` для всех запросов сервиса Cart. Покрыть Unit-тестами репозиторий сервиса Cart (in-memory)
## Основное задание
1. Написаны Unit-тесты слоя `UseCase` для каждого запроса
2. Написаны Unit-тесты слоя `Repository` сервиса Cart
3. Процент покрытия тестируемых слоев должен быть не менее 60%
4. Использовать библиотеку `minimock` для создания моков (библиотека minimock — https://github.com/gojuno/minimock)
5. В `Makefile` создать команду для расчета coverage
## Дополнительное задание
1. Написать два позитивных e2e теста: для хендлеров `DELETE /user/<user_id>/cart/<sku_id>` и `GET /user/<user_id>/cart`
2. Настроить линтер для проверки цикломатической и когнитивной сложности (https://github.com/fzipp/gocyclo и https://github.com/uudashr/gocognit)
3. Написать бенчмарк для `In-memory Storage` сервиса Cart (хотя бы одну операцию — добавление/удаление и т.д.)
## Автоматические проверки
Ваше решение должно проходить автоматические проверки:
- Компиляция
- Линтер
- Unit-тесты
- Code coverage >40%
- Автотесты
Прохождение автоматических проверок влияет на итоговую оценку за домашнюю работу.
### Дедлайны сдачи и проверки задания:
- 31 мая 23:59 (сдача) / 3 июня, 23:59 (проверка)