Todos os anos, milhares de milhões de utilizadores interagem com os produtos e os serviços Google. As principais ofertas, como a Pesquisa, o Gmail, o Maps, o YouTube, o Chrome e, agora, também o Google Cloud, estão tão perfeitamente integradas na vida moderna que ajudam a definir a experiência do século XXI. Este impacto à escala global é o resultado da qualidade comprovada das nossas ofertas e da expetativa de que o Google está sempre disponível.
Na Google Cloud, introduzimos continuamente alterações ao código dos nossos produtos e serviços para garantir que oferecemos a melhor experiência do utilizador possível, melhoramos a segurança e a fiabilidade, e cumprimos os requisitos regulamentares e de conformidade. No entanto, qualquer alteração, por maior ou menor que seja, pode, por vezes, danificar as coisas. Para resolver esse risco, damos prioridade à segurança das alterações durante todo o ciclo de vida de uma alteração.
Este documento explica como as Google Cloud equipas tiram partido dos investimentos da Google ao longo de décadas na excelência do desenvolvimento para implementar práticas recomendadas de fiabilidade e normas de engenharia que cumprem as expectativas dos clientes em termos de velocidade e fiabilidade do desenvolvimento. Google Cloud
O ciclo de vida de uma alteração em Google Cloud
Google Cloud As equipas de produtos partilham grande parte do processo de gestão e ferramentas com outras equipas de engenharia na Google. Implementamos uma abordagem de programação de software padrão para a gestão de alterações que dá prioridade à integração contínua (IC) e à entrega contínua (EC). A CI inclui propor, testar e enviar alterações com frequência, muitas vezes várias vezes por dia para qualquer produto ou serviço. A CD é uma extensão da CI em que os engenheiros preparam continuamente candidatos a lançamentos com base na versão estável mais recente de uma base de código.
Esta abordagem dá prioridade à criação e implementação de alterações em fases para Google Cloud os clientes o mais rapidamente possível, mas também da forma mais segura possível. Consideramos a segurança das alterações antes de escrever qualquer código e continuamos a focar-nos na segurança mesmo depois de implementarmos alterações na produção. Existem quatro fases gerais no nosso modelo de gestão de alterações: conceção, desenvolvimento, qualificação e implementação. Estas quatro fases são apresentadas no diagrama seguinte e são abordadas mais detalhadamente ao longo deste documento:
Seguro desde a conceção
Reconhecemos que, mesmo pequenos erros no início do processo de desenvolvimento, podem causar grandes problemas mais tarde que afetam significativamente as experiências dos clientes. Como tal, exigimos que todas as alterações importantes comecem com um documento de design aprovado. Temos um modelo de documento de design comum para as equipas de engenharia proporem alterações importantes. Este documento de design comum ajuda-nos a avaliar as principais alterações nos Google Cloud produtos de forma consistente. O diagrama seguinte mostra o aspeto do nosso processo de design padrão para uma alteração importante:
A fase de design começa quando um programador de software propõe uma alteração que satisfaz os requisitos empresariais, técnicos, de custos e de manutenção. Após o envio dessa alteração, é iniciado um processo de revisão e aprovação abrangente com especialistas séniores, incluindo especialistas em fiabilidade e segurança, e responsáveis técnicos. O trabalho de implementação da alteração só pode avançar depois de o engenheiro que propôs o design resolver todo o feedback dos especialistas e cada especialista aprovar o design. Este processo de conceção e revisão reduz a probabilidade de as equipas de produtos começarem a trabalhar em alterações que possam ter um impacto negativo nos clientes em produção.Google Cloud
Seguro conforme desenvolvido
O nosso processo de desenvolvimento de código aumenta a qualidade e a fiabilidade do nosso código. Após a aprovação de uma alteração proposta, o processo de desenvolvimento começa com uma incorporação abrangente para novos engenheiros, incluindo formação, orientação e feedback detalhado sobre as alterações de código propostas. Uma abordagem de desenvolvimento e testes de várias camadas com testes manuais e automáticos valida continuamente o código em todas as fases de desenvolvimento. Cada alteração ao código é revista minuciosamente para garantir que cumpre os elevados padrões da Google.
O diagrama seguinte apresenta um fluxo de trabalho que ilustra aproximadamente o aspeto do nosso processo de desenvolvimento:
A fase de desenvolvimento começa quando um engenheiro começa a escrever código e testes de integração e de unidades correspondentes. Durante esta fase, o engenheiro pode executar testes que escreveu e um conjunto de testes de pré-envio para garantir que as adições e as alterações ao código são válidas. Depois de concluir as alterações ao código e executar os testes, o engenheiro pede uma revisão manual a outra pessoa que esteja familiarizada com o código. Este processo de revisão humana é frequentemente iterativo e pode resultar em revisões de código adicionais. Quando o autor e o revisor chegam a um consenso, o autor envia o código.
As normas de programação garantem alterações de alta qualidade
A cultura, as práticas e as ferramentas de engenharia da Google foram concebidas para garantir que o nosso código é correto, claro, conciso e eficiente. O desenvolvimento de código na Google ocorre no nosso monorepo, o maior repositório de código integrado do mundo. O monorepo contém milhões de ficheiros de origem, milhares de milhões de linhas de código e tem um histórico de centenas de milhões de commits denominados listas de alterações. Continua a crescer rapidamente, com dezenas de milhares de novas listas de alterações adicionadas todos os dias úteis. As principais vantagens do monorepo são que facilita a reutilização de código, simplifica a gestão de dependências e aplica fluxos de trabalho de programadores consistentes em produtos e serviços.
A reutilização de código é útil porque já temos uma boa ideia sobre o desempenho do código reutilizado em produção. Ao tirar partido de código de alta qualidade já existente, as alterações são inerentemente mais robustas e fáceis de manter ao nível do padrão necessário. Esta prática não só poupa tempo e esforço, como também garante que a saúde geral da base de código permanece elevada, o que resulta em produtos mais fiáveis.
Google Cloud Os serviços baseados em software de código aberto de alta qualidade podem complementar o monorepo com outro repositório, normalmente o Git, para usar ramificações para gerir o software de código aberto.
Uma nota sobre a preparação
O investimento na qualidade do código começa quando um engenheiro entra numa equipa. Se o engenheiro for novo na Google ou tiver menos familiaridade com a infraestrutura e a arquitetura da equipa, passa por um processo de integração exaustivo. Como parte desta integração, estudam guias de estilo, práticas recomendadas e guias de desenvolvimento, e realizam manualmente exercícios práticos. Além disso, os novos engenheiros requerem um nível de aprovação adicional para cada envio de lista de alterações individual. A aprovação de alterações num determinado idioma de programação é concedida por engenheiros que cumpriram um conjunto rigoroso de expetativas com base na respetiva experiência e que obtiveram legibilidade nesse idioma de programação. Qualquer engenheiro pode ganhar legibilidade para uma linguagem de programação. A maioria das equipas tem vários aprovadores para as linguagens de programação em que programam.
A mudança para a esquerda melhora a velocidade em segurança
A mudança para a esquerda é um princípio que move os testes e a validação para uma fase anterior do processo de desenvolvimento. Este princípio baseia-se na nossa observação de que os custos aumentam drasticamente quanto mais tarde no processo de lançamento encontrarmos e corrigirmos um erro. Num caso extremo, considere um erro que um cliente encontra na produção. Este erro pode afetar negativamente as cargas de trabalho e as aplicações do cliente, e o cliente também pode ter de passar pelo processo de apoio técnico ao cliente do Google Cloud antes de a equipa de engenharia relevante poder mitigar o erro. Se um engenheiro atribuído para resolver o problema for uma pessoa diferente da que introduziu originalmente a alteração que continha o erro, o novo engenheiro tem de se familiarizar com as alterações ao código, o que provavelmente aumenta o tempo necessário para reproduzir e, eventualmente, corrigir o erro. Todo este processo exige muito tempo aos clientes e ao apoio técnico da Google Cloud, e exige que os engenheiros deixem de lado o que estão a fazer para corrigir algo.
Por outro lado, considere um erro que uma falha de teste automatizada deteta enquanto um engenheiro está a trabalhar numa alteração em desenvolvimento. Quando o engenheiro vê a falha no teste, pode corrigi-la imediatamente. Devido às nossas normas de programação, o engenheiro nem sequer conseguiria enviar a alteração com a falha no teste. Esta deteção precoce significa que o engenheiro pode corrigir o erro sem impacto no cliente e que não existe sobrecarga de comutação de contexto.
O último cenário é infinitamente preferível para todos os envolvidos. Como resultado, ao longo dos anos,a Google Cloud investiu fortemente neste princípio de mudança para a esquerda, movendo os testes tradicionalmente realizados durante as fases de qualificação e implementação de alterações diretamente para o ciclo de desenvolvimento. Atualmente, todos os testes de unidades, todos os testes de integração, exceto os maiores, e as análises estáticas e dinâmicas extensivas são concluídos em paralelo enquanto um engenheiro propõe alterações ao código.
Os testes de pré-envio automatizados aplicam as normas de programação
Os testes de pré-envio são verificações executadas antes de quaisquer alterações serem enviadas num determinado diretório. Os testes de pré-envio podem ser testes de unidades e de integração específicos de uma alteração ou testes gerais (por exemplo, análise estática e dinâmica) que são executados para qualquer alteração. Historicamente, os testes de pré-envio eram executados como o último passo antes de alguém enviar uma alteração a uma base de código. Atualmente, em parte devido ao princípio de mudança para a esquerda e à nossa implementação da CI, executamos testes de pré-envio de forma contínua enquanto um engenheiro faz alterações ao código num ambiente de desenvolvimento e antes de unir as alterações ao nosso monorepo. Um engenheiro também pode executar manualmente um conjunto de testes de pré-envio com um único clique na IU de desenvolvimento, e cada teste de pré-envio é executado automaticamente para cada lista de alterações antes de uma revisão de código humana.
Geralmente, o conjunto de testes de pré-envio abrange testes unitários, testes de fuzz (fuzzing), testes de integração herméticos, bem como análise de código estática e dinâmica. Para alterações às bibliotecas ou ao código principais usados amplamente no Google, os programadores executam uma pré-confirmação global. Um teste de pré-envio global testa a alteração em toda a base de código da Google, minimizando o risco de que uma alteração proposta afete negativamente outros projetos ou sistemas.
Testes de unidades e de integração
Os testes exaustivos são parte integrante do processo de desenvolvimento de código. Todos os programadores têm de escrever testes de unidades para as alterações de código e acompanhamos continuamente a cobertura do código ao nível do projeto para garantir que estamos a validar o comportamento esperado. Além disso, exigimos que qualquer percurso do utilizador crítico tenha testes de integração nos quais validamos a funcionalidade de todos os componentes e dependências necessários.
Os testes de unidades e todos os testes de integração, exceto os maiores, são concebidos para serem concluídos rapidamente e são executados de forma incremental com um elevado paralelismo num ambiente distribuído, o que resulta num feedback de desenvolvimento automatizado rápido e contínuo.
Fuzzing
Enquanto os testes unitários e de integração nos ajudam a validar o comportamento esperado com entradas e saídas predeterminadas, o fuzzing é uma técnica que bombardeia uma aplicação com entradas aleatórias, com o objetivo de expor falhas ou fraquezas ocultas que possam levar a vulnerabilidades de segurança ou falhas de sistema. Os testes de fuzzing permitem-nos identificar e resolver proativamente potenciais fragilidades no nosso software, melhorando a segurança e a fiabilidade gerais dos nossos produtos antes de os clientes interagirem com as alterações. A aleatoriedade destes testes é particularmente útil porque, por vezes, os utilizadores interagem com os nossos produtos de formas interessantes que não esperamos, e o fuzzing ajuda-nos a ter em conta cenários que não consideramos manualmente.
Análise estática
As ferramentas de análise estática desempenham um papel fundamental na manutenção da qualidade do código nos nossos fluxos de trabalho de desenvolvimento. A análise estática evoluiu significativamente desde os seus primórdios de análise com expressões regulares para identificar padrões de código C++ problemáticos. Atualmente, a análise estática abrange todos os idiomas de produção e encontra padrões de código erróneos, ineficientes ou descontinuados. Google Cloud
Com front-ends de compiladores avançados e MDIs, podemos propor automaticamente melhorias enquanto os engenheiros escrevem código. Cada alteração de código proposta é validada com análises estáticas. À medida que adicionamos novas verificações estáticas ao longo do tempo, toda a base de código é constantemente analisada quanto à conformidade, e as correções são geradas e enviadas automaticamente para revisão.
Análise dinâmica
Embora a análise estática se foque na identificação de padrões de código conhecidos que podem originar problemas, a análise dinâmica adota uma abordagem diferente. Envolve a compilação e a execução de código para descobrir problemas que só surgem durante a execução, como violações de memória e condições de corrida. A Google tem um vasto histórico de utilização da análise dinâmica e até partilhou várias das suas ferramentas com a comunidade de programadores em geral, incluindo o seguinte:
- AddressSanitizer: Deteta erros de memória, como buffer overflows e use-after-free
- ThreadSanitizer (C++, Go): Encontra conflitos de dados e outros erros de processamento
- MemorySanitizer: Deteta a utilização de memória não inicializada
Estas ferramentas e outras semelhantes são essenciais para detetar erros complexos que não podem ser detetados apenas através da análise estática. Ao usar a análise estática e dinâmica, a Google esforça-se por garantir que o respetivo código está bem estruturado, livre de problemas conhecidos e funciona como esperado em cenários do mundo real.
As revisões de código humanas validam as alterações e os resultados dos testes
Quando um engenheiro atinge um marco crítico no seu código e quer integrá-lo no repositório principal, inicia uma revisão de código propondo uma lista de alterações. Uma solicitação de revisão de código consiste no seguinte:
- Uma descrição que capta a finalidade das alterações e qualquer contexto adicional
- O código modificado real
- Testes unitários e de integração para o código modificado
- Resultados dos testes de pré-envio automatizados
É neste ponto do processo de desenvolvimento que outra pessoa intervém. Um ou mais revisores designados examinam cuidadosamente a lista de alterações para verificar a correção e a clareza, usando os testes anexos e os resultados de pré-envio como guia. Cada diretório de código tem um conjunto de revisores designados responsáveis por garantir a qualidade desse subconjunto da base de código e cuja aprovação é necessária para fazer alterações nesse diretório. Os revisores e os engenheiros colaboram para detetar e resolver quaisquer problemas que possam surgir com uma alteração de código proposta. Quando a lista de alterações cumpre os nossos padrões, um revisor dá a sua aprovação ("LGTM", abreviatura de "looks good to me"). No entanto, se o engenheiro ainda estiver em formação para a linguagem de programação usada, precisa de aprovação adicional de um especialista que tenha obtido legibilidade na linguagem de programação.
Depois de uma lista de alterações passar nos testes e nas verificações automáticas e receber um LGTM, o engenheiro que propôs a alteração só pode fazer alterações mínimas ao código. Quaisquer alterações substanciais invalidam a aprovação e requerem outra ronda de revisão. Mesmo as pequenas alterações são automaticamente sinalizadas aos revisores originais. Assim que o engenheiro envia o código finalizado, este passa por outra ronda completa de testes de pré-envio antes de a lista de alterações ser unida no repositório único. Se algum teste falhar, o envio é rejeitado, e o programador e os revisores recebem um alerta para tomarem medidas corretivas antes de tentarem enviar novamente as alterações.
Qualificação para libertação segura
Embora os testes de pré-envio sejam abrangentes, não são o fim do processo de testes na Google. As equipas têm frequentemente testes adicionais, como testes de integração em grande escala, que não são viáveis para execução durante a revisão de código inicial (podem demorar mais tempo a ser executados ou exigir ambientes de teste de alta fidelidade). Além disso, as equipas têm de estar cientes de quaisquer falhas causadas por fatores fora do seu controlo, como alterações nas dependências externas.
É por isso que a Google exige uma fase de qualificação após a fase de desenvolvimento. Esta fase de qualificação usa um processo de compilação e teste contínuo, conforme mostrado no diagrama seguinte:
Este processo executa periodicamente testes para todo o código afetado por alterações diretas ou indiretas desde a última execução. Todas as falhas são encaminhadas automaticamente para a equipa de engenharia responsável. Em muitos casos, o sistema consegue identificar automaticamente a lista de alterações que causou a falha e revertê-la. Estes testes de integração em grande escala são executados num espetro de ambientes de preparação que vão desde ambientes parcialmente simulados a localizações físicas inteiras.
Os testes têm vários objetivos de qualificação que vão desde a fiabilidade e a segurança básicas até à lógica empresarial. Estes testes de qualificação incluem testar o código para o seguinte:
- A capacidade de oferecer a funcionalidade necessária, que é testada através de testes de integração em grande escala
- A capacidade de satisfazer os requisitos empresariais, que é testada com representações sintéticas de cargas de trabalho dos clientes
- A capacidade de suportar falhas da infraestrutura subjacente, que é testada através da injeção de falhas na pilha
- A capacidade de manter a capacidade de publicação, que é testada com frameworks de testes de carga
- A capacidade de reverter a atualização em segurança
Implementações seguras
Mesmo com os processos de desenvolvimento, teste e qualificação mais rigorosos, por vezes, surgem defeitos nos ambientes de produção que afetam negativamente os nossos utilizadores. Nesta secção, explicamos como o Google Cloud processo de implementação limita o impacto das alterações defeituosas e garante a deteção rápida de quaisquer regressões. Aplicamos esta abordagem a todos os tipos de alterações implementadas na produção, incluindo ficheiros binários, configurações, atualizações de esquemas, alterações de capacidade e listas de controlo de acesso.
Alteração da propagação e supervisão
Aplicamos uma abordagem consistente à implementação de alterações em todos os nossos sistemas para minimizar os impactos negativos nos clientes e isolar os problemas em domínios de falhas lógicos e físicos individuais. Google Cloud O processo baseia-se nas nossas práticas de fiabilidade de SRE com décadas de experiência e no nosso sistema de monitorização à escala global para detetar e mitigar alterações negativas o mais rapidamente possível. A deteção rápida permite-nos notificar os clientes mais rapidamente e tomar medidas corretivas para evitar sistematicamente que ocorram falhas semelhantes novamente.
A maioria dos Google Cloud produtos é regional ou zonal. Isto significa que um produto regional apresentado na região A é independente do mesmo produto apresentado na região B. Da mesma forma, um produto zonal executado na zona C na região A é independente do mesmo produto zonal executado na zona D na região A. Esta arquitetura minimiza o risco de uma indisponibilidade que afete outras regiões ou outras zonas numa única região. Alguns serviços, como o IAM ou a Google Cloud consola, oferecem uma camada globalmente consistente que abrange todas as regiões, motivo pelo qual os denominamos serviços globais. Os serviços globais são replicados em várias regiões para evitar pontos únicos de falha e minimizar a latência. A Google Cloud plataforma de implementação partilhada sabe se um serviço é zonal, regional ou global e organiza as alterações de produção de forma adequada.
O Google Cloud processo de implementação divide todas as réplicas de um serviço implementado em várias localizações de destino em ondas. As ondas iniciais incluem um pequeno número de réplicas, com as atualizações a decorrerem em série. As ondas iniciais equilibram a proteção da maioria dos fluxos de trabalho dos clientes com a maximização da exposição à diversidade dos fluxos de trabalho para detetar problemas o mais cedo possível e incluem fluxos de trabalho sintéticos que imitam padrões comuns de fluxos de trabalho dos clientes.
Se a implementação continuar a ser bem-sucedida à medida que as réplicas do serviço são atualizadas nas localizações de destino, as ondas de implementação subsequentes aumentam progressivamente de tamanho e introduzem mais paralelismo. Embora algum paralelismo seja necessário para ter em conta o número de Google Cloud localizações, não permitimos atualizações simultâneas de localizações que estejam em ondas diferentes. Se uma onda se prolongar pela noite ou por um fim de semana, pode concluir a progressão, mas não pode iniciar uma nova onda até ao início do horário de funcionamento da equipa que gere a implementação.
O diagrama seguinte é um exemplo de fluxo de trabalho que ilustra a lógica de implementação que usamos em Google Cloud para produtos e serviços regionais:
O Google Cloud processo de implementação usa o Canary Analysis Service (CAS) para automatizar os testes A/B durante a implementação. Algumas réplicas tornam-se canários (ou seja, uma implementação parcial e com limite de tempo de uma alteração num serviço), e as réplicas restantes constituem o grupo de controlo que não inclui a alteração. Cada passo do processo de implementação tem um tempo de preparação para detetar problemas de evolução lenta antes de avançar para o passo seguinte, de modo a garantir que todas as funcionalidades de um serviço são bem exercidas e que as potenciais anomalias são detetadas pelo CAS. O tempo de preparação é cuidadosamente definido para equilibrar a deteção de problemas de evolução lenta com a velocidade de desenvolvimento.As Google Cloud implementações demoram normalmente uma semana.
Este diagrama oferece uma breve vista geral do aspeto do fluxo de trabalho do CAS:
O fluxo de trabalho começa com a ferramenta de implementação a implementar a alteração na réplica de teste. Em seguida, a ferramenta de implementação pede um veredito ao CAS. O CAS avalia a réplica de teste beta em relação ao grupo de controlo e devolve um veredito de APROVADO ou REPROVADO. Se algum sinal de saúde falhar, é gerado um alerta para os proprietários do serviço e a etapa de implementação em execução é pausada ou revertida. Se a alteração causar interrupções aos clientes externos, é declarado um incidente externo e os clientes afetados são notificados através do serviço Estado do serviço personalizado. Os incidentes também acionam uma revisão interna. A filosofia de análise post mortem da Google garante que o conjunto certo de ações corretivas é identificado e aplicado para minimizar a probabilidade de ocorrência de falhas semelhantes no futuro.
Monitorização de sinais e segurança pós-implementação
Os defeitos de software nem sempre se manifestam instantaneamente e alguns podem exigir circunstâncias específicas para serem acionados. Por este motivo, continuamos a monitorizar os sistemas de produção após a conclusão de uma implementação. Ao longo dos anos, verificámos que, mesmo que uma implementação não desencadeie problemas imediatamente, uma implementação incorreta continua a ser o culpado mais provável de um incidente de produção. Por este motivo, os nossos manuais de produção indicam aos responsáveis pela resposta a incidentes que correlacionem as implementações recentes com os problemas observados e que revertam uma implementação recente se os responsáveis pela resposta a incidentes não conseguirem excluir as alterações recentes como causa principal do incidente.
A monitorização pós-implementação baseia-se no mesmo conjunto de sinais de monitorização que usamos para as análises A/B automatizadas durante um período de implementação. A filosofia de Google Cloud monitorização e alertas combina dois tipos de monitorização: introspectiva (também conhecida como caixa branca) e sintética (também conhecida como caixa negra). A monitorização introspectiva usa métricas como a utilização da CPU, a utilização da memória e outros dados de serviços internos. A monitorização sintética analisa o comportamento do sistema na perspetiva de um cliente, acompanhando as taxas de erro do serviço e as respostas ao tráfego sintético dos serviços de sondagem. A monitorização sintética é orientada para os sintomas e identifica problemas ativos, enquanto a monitorização introspectiva permite-nos diagnosticar problemas confirmados e, em alguns casos, identificar problemas iminentes.
Para ajudar na deteção de incidentes que afetam apenas alguns clientes, agrupamos as cargas de trabalho dos clientes em coortes de cargas de trabalho relacionadas. Os alertas são acionados assim que o desempenho de uma coorte se desvia da norma. Estes alertas permitem-nos detetar regressões específicas do cliente, mesmo que o desempenho agregado pareça normal.
Proteção da cadeia de abastecimento de software
Sempre que Google Cloud as equipas introduzem alterações, usamos uma verificação de segurança denominada autorização binária para o Borg (BAB) para proteger a nossa cadeia de fornecimento de software e os clientes do Google Cloud contra o risco interno. A BAB começa na fase de revisão do código e cria uma trilha de auditoria do código e da configuração implementados na produção. Para garantir a integridade da produção, a BAB só admite alterações que cumpram os seguintes critérios:
- São invioláveis e assinados
- Provenientes de uma parte de compilação identificada e de uma localização de origem identificada
- Foram revistos e aprovados explicitamente por uma parte distinta do autor do código
Se tiver interesse em aplicar alguns dos mesmos conceitos no seu próprio ciclo de vida de desenvolvimento de software, incluímos conceitos-chave da BAB numa especificação aberta denominada Níveis da cadeia de fornecimento para artefactos de software (SLSA). A SLSA funciona como uma framework de segurança para desenvolver e executar código em ambientes de produção.
Conclusão
Google Cloud baseia-se nas décadas de investimento da Google na excelência do desenvolvimento. A integridade do código e a integridade da produção são princípios culturais incutidos em todas as equipas de engenharia da Google. O nosso processo de revisão de design garante que as implicações no código e no estado de produção são consideradas desde o início. O nosso processo de desenvolvimento, baseado no princípio de mudança para a esquerda e em testes extensivos, garante que as ideias de design são implementadas de forma segura e correta. O nosso processo de qualificação expande ainda mais os testes para abranger integrações em grande escala e dependências externas. Por último, a nossa plataforma de implementação permite-nos criar progressivamente confiança de que uma determinada alteração se comporta efetivamente conforme esperado. Desde a conceção à produção, a nossa abordagem permite-nos satisfazer Google Cloud as expetativas dos clientes em termos de velocidade de desenvolvimento e fiabilidade.