База данных панели управления СУДС

Для поддержки информационной панели непрерывной интеграции, которая является масштабируемой, производительной и гибкой, серверная часть панели мониторинга VTS должна быть тщательно спроектирована с глубоким пониманием функциональности базы данных. Google Cloud Datastore — это база данных NoSQL, которая предлагает транзакционные гарантии ACID и конечную согласованность, а также строгую согласованность внутри групп сущностей. Однако структура сильно отличается от структуры баз данных SQL (и даже от Cloud Bigtable); вместо таблиц, строк и ячеек есть виды, сущности и свойства.

В следующих разделах описывается структура данных и шаблоны запросов для создания эффективной серверной части веб-службы панели мониторинга VTS.

Сущности

Следующие объекты хранят сводные данные и ресурсы из тестовых запусков VTS:

  • Тестовая сущность . Хранит метаданные о запусках конкретного теста. Его ключом является имя теста, а его свойства включают количество ошибок, число прохождений и список сбоев в тестовых случаях, когда задания оповещений обновляют его.
  • Объект тестового запуска . Содержит метаданные из запусков определенного теста. Он должен хранить временные метки начала и окончания теста, идентификатор тестовой сборки, количество пройденных и неуспешных тестовых случаев, тип запуска (например, перед отправкой, после отправки или локальный), список ссылок на журналы, хост имя машины и сводные данные о покрытии.
  • Информационный объект об устройстве . Содержит сведения об устройствах, использованных во время тестового запуска. Он включает идентификатор сборки устройства, название продукта, цель сборки, ветвь и информацию ABI. Он хранится отдельно от объекта запуска теста для поддержки запуска тестов на нескольких устройствах по принципу «один ко многим».
  • Объект выполнения точки профилирования . Обобщает данные, собранные для конкретной точки профилирования в ходе выполнения теста. Он описывает метки осей, имя точки профилирования, значения, тип и режим регрессии данных профилирования.
  • Объект покрытия . Описывает данные о покрытии, собранные для одного файла. Он содержит информацию о проекте Git, путь к файлу и список счетчиков покрытия в каждой строке исходного файла.
  • Объект выполнения тестового набора . Описывает результат выполнения конкретного тестового сценария, включая имя тестового примера и его результат.
  • Объект «Избранное пользователя» . Каждую пользовательскую подписку можно представить в виде сущности, содержащей ссылку на тест и идентификатор пользователя, сгенерированный пользовательской службой App Engine. Это обеспечивает эффективный двунаправленный запрос (т.е. для всех пользователей, подписавшихся на тест, и для всех тестов, избранных пользователем).

Группировка сущностей

Каждый тестовый модуль представляет собой корень группы сущностей. Объекты запуска теста являются одновременно дочерними элементами этой группы и родительскими объектами для объектов устройств, объектов точек профилирования и объектов покрытия, соответствующих соответствующему предку теста и запуска теста.

Рисунок 1 . Тестирование происхождения объекта.

Ключевой момент: при проектировании отношений происхождения необходимо сбалансировать необходимость предоставления эффективных и согласованных механизмов запросов с ограничениями, налагаемыми базой данных.

Преимущества

Требование согласованности гарантирует, что будущие операции не увидят последствий транзакции до тех пор, пока она не будет зафиксирована, и что транзакции в прошлом будут видны текущим операциям. В Cloud Datastore группировка сущностей создает островки строгой согласованности чтения и записи внутри группы, которая в данном случае представляет собой все тестовые запуски и данные, относящиеся к тестовому модулю. Это дает следующие преимущества:

  • Чтение и обновление состояния тестового модуля с помощью заданий оповещения можно рассматривать как атомарные.
  • Гарантированное единообразное представление результатов тестовых случаев в тестовых модулях.
  • Более быстрый запрос в деревьях предков

Ограничения

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

В конечном счете, ограничение одной записи на тестовый модуль в секунду является разумным, поскольку выполнение тестов обычно занимает не менее одной минуты, включая накладные расходы инфраструктуры VTS; если тест не выполняется последовательно одновременно на более чем 60 различных хостах, не может быть узкого места при записи. Это становится еще более маловероятным, если учесть, что каждый модуль является частью плана тестирования, который часто занимает более одного часа. Аномалии можно легко устранить, если хосты запускают тесты одновременно, вызывая короткие всплески записи на одни и те же хосты (например, путем обнаружения ошибок записи и повторной попытки).

Рекомендации по масштабированию

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

Тестовые случаи

Еще одним потенциальным узким местом являются большие тесты с множеством тестовых примеров. Двумя оперативными ограничениями являются максимальная пропускная способность записи в группе объектов (один объект в секунду), а также максимальный размер транзакции в 500 объектов.

Один из подходов заключается в том, чтобы указать тестовый пример, в котором в качестве предка используется тестовый запуск (аналогично тому, как хранятся данные покрытия, данные профилирования и информация об устройстве):

Фигура 2 . Тестовые случаи происходят из тестовых прогонов (НЕ РЕКОМЕНДУЕТСЯ).

Хотя этот подход обеспечивает атомарность и согласованность, он накладывает строгие ограничения на тесты: если транзакция ограничена 500 сущностями, то тест может иметь не более 498 тестовых случаев (при условии отсутствия данных о покрытии или профилировании). Если тест превысит это значение, то одна транзакция не сможет записать все результаты тестового набора одновременно, а разделение тестовых случаев на отдельные транзакции может превысить максимальную пропускную способность записи группы сущностей, равную одной итерации в секунду. Поскольку это решение не будет хорошо масштабироваться без ущерба для производительности, использовать его не рекомендуется.

Однако вместо того, чтобы хранить результаты тестового набора как дочерние элементы тестового запуска, тестовые примеры могут храниться независимо, а их ключи предоставляться для тестового запуска (тестовый запуск содержит список идентификаторов для своих объектов тестовых сценариев):

Рисунок 3 . Тестовые случаи хранятся независимо (РЕКОМЕНДУЕТСЯ).

На первый взгляд может показаться, что это нарушает строгую гарантию согласованности. Однако если у клиента есть объект тестового запуска и список идентификаторов тестовых случаев, ему не нужно создавать запрос; вместо этого он может напрямую получать тестовые примеры по их идентификаторам, что всегда гарантирует согласованность. Этот подход значительно снижает ограничение на количество тестовых случаев, которые может иметь тестовый прогон, обеспечивая при этом строгую согласованность без угрозы чрезмерного написания внутри группы сущностей.

Шаблоны доступа к данным

Панель управления VTS использует следующие шаблоны доступа к данным:

  • Избранное пользователей . Можно запросить с помощью фильтра равенства для сущностей избранного пользователя, имеющих в качестве свойства конкретный объект "Пользователь App Engine".
  • Тестовый листинг . Простой запрос тестовых объектов. Чтобы уменьшить пропускную способность для отображения домашней страницы, можно использовать проекцию количества пройденных и неуспешных тестов, чтобы исключить потенциально длинный список идентификаторов неудачных тестовых случаев и других метаданных, используемых заданиями оповещения.
  • Тестовые запуски . Запрос объектов тестового запуска требует сортировки по ключу (метке времени) и возможной фильтрации по свойствам тестового запуска, таким как идентификатор сборки, количество проходов и т. д. Выполняя запрос предка с ключом тестового объекта, чтение становится строго согласованным. На этом этапе все результаты тестового примера можно получить с помощью списка идентификаторов, хранящегося в свойстве запуска теста; это также гарантированно будет строго согласованным результатом в силу характера операций получения данных из хранилища.
  • Данные профилирования и охвата . Запрос данных профилирования или покрытия, связанных с тестом, можно выполнить без получения каких-либо других данных запуска теста (например, других данных профилирования/покрытия, данных тестовых примеров и т. д.). Запрос к предку с использованием ключей объекта тестового теста и тестового запуска позволит получить все точки профилирования, записанные во время тестового запуска; путем фильтрации по имени точки профилирования или имени файла можно получить один объект профилирования или покрытия. По характеру запросов к предкам эта операция строго согласована.

Подробные сведения о пользовательском интерфейсе и снимки экрана с этими шаблонами данных в действии см. в разделе Пользовательский интерфейс панели управления VTS .