# Автоматический запуск тестов

Автоматический запуск тестов происходит при проверке пулл-реквестов перед их вливанием в единый репозиторий. Процесс сборки исходных кодов и выполнения тестов при проверке пулл-реквестов называется **автоматической сборкой** или **автосборкой**.

## Автосборка { #pr-checks }

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

* **[Arcanum](https://a.yandex-team.ru/)** - веб-интерфейс единого репозитория, отображающий состояние проверки пулл-реквестов.
* **[Sandbox](https://sandbox.yandex-team.ru/)** - среда распределенного исполнения произвольных  задач. При работе с пулл-реквестами используется для запуска команды `ya make` на каждый пулл-реквест и вливания уже проверенных пулл-реквестов в единый репозиторий.
* **Distbuild** - специальный сервис, ускоряющий процесс сборки, за счет её параллельного выполнения по частям на множестве независимых серверов и кеширования результатов сборки.
* **[CI](https://ci.yandex-team.ru/)** - позволяет добавить дополнительные проверки ваших пулл-реквестов. Например, проверку того, что сервис успешно выкладывается и работает в тестовом окружении.

Также в работе участвуют различные вспомогательные сервисы (например, для работы с ревизиями единого репозитория или для обработки событий, возникающих для каждого пулл-реквеста) и базы данных.

## Вычислительные ресурсы { #computing-resource }

Несмотря на то, что внутренние процессы автоматической сборки в значительной мере скрыты от пользователя, у пользователя есть возможность влиять на некоторые важные параметры. Например, при выполнении тестов можно указывать **вычислительные ресурсы** (процессорные ядра, память, размер жесткого диска и т.п.). По-умолчанию каждому тесту доступно **1 процессорное ядро и 32 Гб оперативной памяти**. При необходимости можно менять эти значения на одно из приведенных в таблице:

Размер теста | Число процессорных ядер | Размер оперативной памяти, Гб
:--- | :--- | :---
SMALL | 1 - 4 | 1, 2, 4, 8, 16, 32
MEDIUM | 1 - 4 (планируется увеличение) | 1, 2, 4, 8, 16, 32
LARGE | 1 - 4 (планируется увеличение) | 1, 2, 4, 8, 16, 32

Для того, чтобы явно задать требуемые вычислительные ресурсы, используется макрос `REQUIREMENTS`:

```yamake
OWNER(g:my-group)

JUNIT5()

SIZE(MEDIUM)

JAVA_SRCS(SRCDIR java **/*)
JAVA_SRCS(SRCDIR resources **/*)

REQUIREMENTS( # Требуемые вычислительные ресурсы
    cpu:2 # Число требуемых процессорных ядер
    ram:8 # Размер оперативной памяти, Гб
    disk_usage:20 # Минимальный доступный размер дискового пространства, Гб
    ram_disk:2 # Размер RAM-диска, Гб
    container:12345678 # Идентификатор ресурса контейнера, в котором будет исполняться тест
    network:full # Тип доступа по сети: restricted (по-умолчанию) - доступен только localhost, full - есть доступ во внешнюю сеть.
)

END()
```

{% note info %}

1. Параметр `disk_usage` и `container` работают только для LARGE тестов.
2. Параметр `container` позволяет запускать тесты в заранее подготовленном [окружении](https://docs.yandex-team.ru/sandbox/dev/environment) в виде образа LXC или Porto контейнера.
3. Поскольку [RAM-диск](https://en.wikipedia.org/wiki/RAM_drive) использует оперативную память, суммарное значение полей `ram` и `ram_disk` не может превышать максимально возможное значение размера оперативной памяти для тестов данного размера.
4. Тесты, запускаемые с `network:full` находятся в сетевом макросе `_DISTBUILDNETS_`

{% endnote %}

## Таймаут { #timeout }

Существует возможность явно указать таймаут на выполнение всех тестов, определенных в конкретном файле **ya.make**:

```yamake
OWNER(g:my-group)

JUNIT5()

SIZE(MEDIUM)

JAVA_SRCS(SRCDIR java **/*)
JAVA_SRCS(SRCDIR resources **/*)

TIMEOUT(500) # Таймаут в секундах

END()
```

{% note warning %}

1. Значение таймаута не может быть больше, чем максимальная длительность выполнения теста данного [размера](https://docs.yandex-team.ru/ya-make/usage/ya_make/tests#size).
2. Если тесты выполняются параллельно в несколько потоков, то таймаут отсчитывается для каждого потока независимо.

{% endnote %}

## Системные теги { #system-tags }

В [предыдущем разделе](manual.md#tags) мы уже упоминали про возможность разметки тестов пользовательскими тегами. Система автоматической сборки также имеет набор предопределенных **системных тегов**, которые влияют на процесс выполнения тестов:

Название | Описание
:--- | :---
`sb:XXXX` | Позволяет задать набор [тегов](https://docs.yandex-team.ru/sandbox/agents#tags) для выбора агента [Sandbox](https://sandbox.yandex-team.ru/). При указании нескольких тегов `sb:`, они соединяются через логическое `ИЛИ`.
`sb:ttl=X` | Позволяет задать ttl для создаваемого в таске `YA_MAKE` ресурса `BUILD_OUTPUT`. Тег следует использовать, если автозапуск LARGE тестов от лица вашего робота потребляет много дисковой квоты из-за больших выходных данных в этом ресурсе. ttl по умолчанию - 14 дней.
`ya:external` | Уведомляет систему, что тест использует внешние системы (сеть, базы данных и т.д.). Это значит, что такой тест может потенциально работать нестабильно. Поэтому уведомления о поломках таких тестов будут приходить только владельцам теста и не будут приходить авторам коммита, на котором тест сломался.
`ya:always_minimize` | Приводит к постоянной минимизации корпуса после фаззинга, см подробности в документации к [fuzzing](https://docs.yandex-team.ru/ya-make/manual/tests/fuzzing).
`ya:fat` | Помечает тест как LARGE.
`ya:force_distbuild` | Запускает тест в сервисе Distbuild в независимости от его размера.
`ya:force_sandbox` | Запускает тест в сервисе Sandbox. Используется только вместе с тегом `ya:fat`.
`ya:full_logs` | Приводит к падению тестов, если размер лога превысил **100 Мб**.
`ya:huge_logs` | Поднимает ограничение на максимальный размер лога тестов до **1 Гб**.
`ya:manual`| Тест не будет запускаться, если явно не [указано](manual.md#tags) запускать тесты с этим тегом.
`ya:norestart` | Отключает перезапуск теста при определенных ошибках.
`ya:not_autocheck` | Не запускать тест в при проверке пулл-реквестов.
`ya:no_graceful_shutdown` | Завершает выполнение процесса с тестами при помощи [сигнала](https://en.wikipedia.org/wiki/Signal_(IPC)) SIGQUIT вместо SIGTERM Это позволяет, например, поймать стектрейс состояния, в котором находится тест.
`ya:noretries` | Не запускать упавший LARGE-тест повторно при проверке пулл-реквеста (почему только LARGE см. [пост](https://clubs.at.yandex-team.ru/arcadia/23033)). Повторный запуск используется для определения нестабильности теста. В случае тестов, использующих внешние сервисы перезапуск теста может приводить к ошибкам повторного запуска этих сервисов (пересечение по портам).
`ya:notags` | Используется для фильтрации тестов, не имеющих тегов.
`ya:privileged` | Запускает тесты в Sandbox в контейнере [от имени root](https://docs.yandex-team.ru/sandbox/dev/requirements).
`ya:sys_info` | Добавляет вывод системной информации в лог до и после выполнения тестов.
`ya:trace_output` | Включить логирование создаваемых файлов и их размеров при помощи системного вызова [ptrace](https://en.wikipedia.org/wiki/Ptrace). Работает только под Linux. Может замедлять тестирование.

Пример объявления системных тегов:

```yamake
OWNER(g:my-group)

JUNIT5()

SIZE(MEDIUM)

JAVA_SRCS(SRCDIR java **/*)
JAVA_SRCS(SRCDIR resources **/*)

TAG(sb:ssd sb:~man ya:huge_logs) # Системные теги

END()
```
