Banco de dados do painel VTS

Para oferecer suporte a um painel de integração contínua que seja escalável, de alto desempenho e flexível, o back-end do Painel VTS deve ser cuidadosamente projetado com um forte entendimento da funcionalidade do banco de dados. O Google Cloud Datastore é um banco de dados NoSQL que oferece garantias ACID transacionais e consistência eventual, bem como forte consistência dentro de grupos de entidades. No entanto, a estrutura é muito diferente dos bancos de dados SQL (e até mesmo do Cloud Bigtable); em vez de tabelas, linhas e células, existem tipos, entidades e propriedades.

As seções a seguir descrevem a estrutura de dados e os padrões de consulta para criar um back-end eficaz para o serviço da web VTS Dashboard.

Entidades

As seguintes entidades armazenam resumos e recursos de execuções de teste VTS:

  • Entidade de teste . Armazena metadados sobre execuções de teste de um teste específico. Sua chave é o nome do teste e suas propriedades incluem a contagem de falhas, a contagem de aprovações e a lista de quebras de casos de teste a partir do momento em que os trabalhos de alerta o atualizam.
  • Entidade de execução de teste . Contém metadados de execuções de um teste específico. Ele deve armazenar os carimbos de data e hora de início e término do teste, o ID da construção do teste, o número de casos de teste aprovados e reprovados, o tipo de execução (por exemplo, pré-envio, pós-envio ou local), uma lista de links de log, o host nome da máquina e contagens de resumo de cobertura.
  • Entidade de informações do dispositivo . Contém detalhes sobre os dispositivos usados ​​durante a execução do teste. Inclui o ID de compilação do dispositivo, nome do produto, destino de compilação, ramificação e informações de ABI. Isso é armazenado separadamente da entidade de execução de teste para oferecer suporte a execuções de teste em vários dispositivos de maneira um para muitos.
  • Criação de perfil de entidade de execução de ponto . Resume os dados coletados para um determinado ponto de criação de perfil em uma execução de teste. Ele descreve os rótulos dos eixos, o nome do ponto de criação de perfil, os valores, o tipo e o modo de regressão dos dados de criação de perfil.
  • Entidade de Cobertura . Descreve os dados de cobertura coletados para um arquivo. Ele contém as informações do projeto Git, o caminho do arquivo e a lista de contagens de cobertura por linha no arquivo de origem.
  • Entidade de execução de caso de teste . Descreve o resultado de um caso de teste específico de uma execução de teste, incluindo o nome do caso de teste e seu resultado.
  • Entidade Favoritos do Usuário . Cada assinatura de usuário pode ser representada em uma entidade que contém uma referência ao teste e o ID do usuário gerado pelo serviço de usuário do App Engine. Isto permite consultas bidirecionais eficientes (ou seja, para todos os usuários inscritos em um teste e para todos os testes favoritos de um usuário).

Agrupamento de entidades

Cada módulo de teste representa a raiz de um grupo de entidades. As entidades de execução de teste são filhas deste grupo e pais de entidades de dispositivo, entidades de ponto de criação de perfil e entidades de cobertura relevantes para o respectivo teste e ancestral de execução de teste.

Figura 1 . Testar ancestralidade da entidade.

Ponto-chave: Ao projetar relacionamentos de ancestralidade, você deve equilibrar a necessidade de fornecer mecanismos de consulta eficazes e consistentes com as limitações impostas pelo banco de dados.

Benefícios

O requisito de consistência garante que as operações futuras não verão os efeitos de uma transação até que ela seja confirmada e que as transações do passado sejam visíveis para as operações presentes. No Cloud Datastore, o agrupamento de entidades cria ilhas de forte consistência de leitura e gravação dentro do grupo, que neste caso são todas as execuções de teste e dados relacionados a um módulo de teste. Isso oferece os seguintes benefícios:

  • Leituras e atualizações para testar o estado do módulo por trabalhos de alerta podem ser tratadas como atômicas
  • Visão consistente garantida dos resultados dos casos de teste nos módulos de teste
  • Consulta mais rápida em árvores ancestrais

Limitações

Não é aconselhável gravar em um grupo de entidades a uma taxa superior a uma entidade por segundo, pois algumas gravações podem ser rejeitadas. Desde que os trabalhos de alerta e o upload não ocorram a uma taxa superior a uma gravação por segundo, a estrutura é sólida e garante forte consistência.

Em última análise, o limite de uma gravação por módulo de teste por segundo é razoável porque as execuções de teste geralmente levam pelo menos um minuto, incluindo a sobrecarga da estrutura VTS; a menos que um teste seja executado de forma consistente e simultânea em mais de 60 hosts diferentes, não pode haver um gargalo de gravação. Isto torna-se ainda mais improvável dado que cada módulo faz parte de um plano de teste que muitas vezes demora mais de uma hora. As anomalias podem ser facilmente tratadas se os hosts executarem os testes ao mesmo tempo, causando pequenos surtos de escrita nos mesmos hosts (por exemplo, detectando erros de escrita e tentando novamente).

Considerações de dimensionamento

Uma execução de teste não precisa necessariamente ter o teste como pai (por exemplo, pode receber alguma outra chave e ter o nome do teste e a hora de início do teste como propriedades); no entanto, isso trocará uma consistência forte por uma consistência eventual. Por exemplo, o trabalho de alerta pode não ver um instantâneo mutuamente consistente das execuções de teste mais recentes dentro de um módulo de teste, o que significa que o estado global pode não representar uma representação totalmente precisa da sequência de execuções de teste. Isso também pode afetar a exibição de execuções de teste em um único módulo de teste, que pode não ser necessariamente um instantâneo consistente da sequência de execução. Eventualmente, o instantâneo será consistente, mas não há garantias de que os dados mais recentes serão.

Casos de teste

Outro gargalo potencial são os testes grandes com muitos casos de teste. As duas restrições operacionais são a taxa de transferência máxima de gravação dentro de um grupo de entidades de uma por segundo, juntamente com um tamanho máximo de transação de 500 entidades.

Uma abordagem seria especificar um caso de teste que tenha uma execução de teste como ancestral (semelhante à forma como os dados de cobertura, dados de perfil e informações do dispositivo são armazenados):

Figura 2 . Os casos de teste descendem de execuções de teste (NÃO RECOMENDADO).

Embora esta abordagem ofereça atomicidade e consistência, ela impõe fortes limitações aos testes: se uma transação estiver limitada a 500 entidades, então um teste não poderá ter mais de 498 casos de teste (assumindo que não há cobertura ou dados de perfil). Se um teste excedesse isso, uma única transação não poderia gravar todos os resultados do caso de teste de uma só vez, e dividir os casos de teste em transações separadas poderia exceder o rendimento máximo de gravação do grupo de entidades de uma iteração por segundo. Como esta solução não será bem dimensionada sem sacrificar o desempenho, ela não é recomendada.

No entanto, em vez de armazenar os resultados dos casos de teste como filhos da execução de teste, os casos de teste podem ser armazenados de forma independente e suas chaves fornecidas para a execução de teste (uma execução de teste contém uma lista de identificadores para suas entidades de casos de teste):

Figura 3 . Casos de teste armazenados de forma independente (RECOMENDADO).

À primeira vista, isto pode parecer quebrar a forte garantia de consistência. Entretanto, se o cliente tiver uma entidade de execução de teste e uma lista de identificadores de caso de teste, ele não precisará construir uma consulta; em vez disso, ele pode obter diretamente os casos de teste por seus identificadores, o que é sempre garantido como consistente. Essa abordagem alivia enormemente a restrição do número de casos de teste que uma execução de teste pode ter, ao mesmo tempo que ganha forte consistência sem ameaçar gravação excessiva dentro de um grupo de entidades.

Padrões de acesso a dados

O Painel VTS usa os seguintes padrões de acesso a dados:

  • Favoritos do usuário . Pode ser consultado usando um filtro de igualdade em entidades favoritas do usuário que tenham o objeto Usuário específico do App Engine como propriedade.
  • Listagem de teste . Consulta simples de entidades de teste. Para reduzir a largura de banda para renderizar a página inicial, uma projeção pode ser usada nas contagens de aprovação e falha, de modo a omitir a lista potencialmente longa de IDs de casos de teste com falha e outros metadados usados ​​pelas tarefas de alerta.
  • Execuções de teste . A consulta de entidades de execução de teste requer uma classificação na chave (carimbo de data/hora) e possível filtragem nas propriedades de execução de teste, como ID de construção, contagem de aprovação, etc. Ao executar uma consulta ancestral com uma chave de entidade de teste, a leitura é fortemente consistente. Neste ponto, todos os resultados do caso de teste podem ser recuperados usando a lista de IDs armazenados em uma propriedade de execução de teste; isso também garante um resultado fortemente consistente pela natureza das operações de obtenção do armazenamento de dados.
  • Dados de perfil e cobertura . A consulta de dados de criação de perfil ou cobertura associados a um teste pode ser feita sem também recuperar quaisquer outros dados de execução de teste (como outros dados de criação de perfil/cobertura, dados de caso de teste, etc.). Uma consulta ancestral usando as chaves de entidade test test e test run recuperará todos os pontos de criação de perfil registrados durante a execução do teste; filtrando também o nome do ponto de criação de perfil ou nome do arquivo, uma única entidade de criação de perfil ou cobertura pode ser recuperada. Pela natureza das consultas aos ancestrais, esta operação é fortemente consistente.

Para obter detalhes sobre a UI e capturas de tela desses padrões de dados em ação, consulte UI do painel VTS .