

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# AWS CloudFormation Guard Regras de teste
<a name="testing-rules"></a>

Você pode usar a estrutura de teste de unidade AWS CloudFormation Guard integrada para verificar se as regras do Guard funcionam conforme o esperado. Esta seção fornece uma explicação passo a passo sobre como escrever um arquivo de teste unitário e como usá-lo para testar seu arquivo de regras com o `test` comando.

Seu arquivo de teste de unidade deve ter uma das seguintes extensões:`.json`,`.JSON`,`.jsn`,`.yaml`,`.YAML`, ou`.yml`.

**Topics**
+ [Pré-requisitos](#testing-rules-prerequisites)
+ [Visão geral dos arquivos de teste unitário do Guard](#testing-rules-overview)
+ [Passo a passo da criação de um arquivo de teste unitário de regras do Guard](#testing-rules-example)

## Pré-requisitos
<a name="testing-rules-prerequisites"></a>

Escreva as regras do Guard para avaliar seus dados de entrada. Para obter mais informações, consulte [Regras do Writing Guard](writing-rules.md).

## Visão geral dos arquivos de teste unitário do Guard
<a name="testing-rules-overview"></a>

Os arquivos de teste de unidade do Guard são arquivos no formato JSON ou YAML que contêm várias entradas e os resultados esperados para regras escritas dentro de um arquivo de regras do Guard. Pode haver várias amostras para avaliar diferentes expectativas. Recomendamos que você comece testando entradas vazias e, em seguida, adicione progressivamente informações para avaliar várias regras e cláusulas.

Além disso, recomendamos que você nomeie os arquivos de teste de unidade usando o sufixo `_test.json` ou`_tests.yaml`. Por exemplo, se você tiver um arquivo de regras chamado`my_rules.guard`, nomeie seu arquivo de teste de unidade`my_rules_tests.yaml`.

### Sintaxe
<a name="testing-rules-syntax"></a>

Veja a seguir a sintaxe de um arquivo de teste de unidade no formato YAML.

```
---
- name: <TEST NAME>
  input:
     <SAMPLE INPUT>
   expectations:
     rules:
       <RULE NAME>: [PASS|FAIL|SKIP]
```

### Propriedades
<a name="testing-rules-properties"></a>

A seguir estão as propriedades de um arquivo de teste do Guard.

`input`  <a name="testing-rules-properties-input"></a>
Dados para testar suas regras. Recomendamos que seu primeiro teste use uma entrada vazia, conforme mostrado no exemplo a seguir.  

```
---
- name: MyTest1
  input {}
```
Para testes subsequentes, adicione dados de entrada para testar.  
 *Obrigatório*: sim 

`expectations`  <a name="testing-rules-properties-expectations"></a>
O resultado esperado quando regras específicas são avaliadas em relação aos dados de entrada. Especifique uma ou várias regras que você deseja testar além do resultado esperado para cada regra. O resultado esperado deve ser um dos seguintes:  
+ `PASS`— Quando executadas com base em seus dados de entrada, as regras são avaliadas como`true`.
+ `FAIL`— Quando executadas com base em seus dados de entrada, as regras são avaliadas como`false`.
+ `SKIP`— Quando executada com base nos dados de entrada, a regra não é acionada.

```
expectations:
    rules:
      check_rest_api_is_private: PASS
```
 *Obrigatório*: sim 

## Passo a passo da criação de um arquivo de teste unitário de regras do Guard
<a name="testing-rules-example"></a>

A seguir está um arquivo de regras chamado`api_gateway_private.guard`. A intenção dessa regra é verificar se todos os tipos de recursos do Amazon API Gateway definidos em um CloudFormation modelo são implantados somente para acesso privado. Também verifica se pelo menos uma declaração de política permite acesso a partir de uma nuvem privada virtual (VPC).

```
#
# Select all AWS::ApiGateway::RestApi resources
#     present in the Resources section of the template. 
#
let api_gws = Resources.*[ Type == 'AWS::ApiGateway::RestApi']

#
# Rule intent:         
# 1) All AWS::ApiGateway::RestApi resources deployed must be private.                                            
# 2) All AWS::ApiGateway::RestApi resources deployed must have at least one AWS Identity and Access Management (IAM) policy condition key to allow access from a VPC.
#
# Expectations:        
# 1) SKIP when there are no AWS::ApiGateway::RestApi resources in the template.  
# 2) PASS when:
#     ALL AWS::ApiGateway::RestApi resources in the template have the EndpointConfiguration property set to Type: PRIVATE. 
#     ALL AWS::ApiGateway::RestApi resources in the template have one IAM condition key specified in the Policy property with aws:sourceVpc or :SourceVpc.    
# 3) FAIL otherwise.                                                                                  
#
#

rule check_rest_api_is_private when %api_gws !empty {      
    %api_gws {
        Properties.EndpointConfiguration.Types[*] == "PRIVATE"                             
    }  
}       

rule check_rest_api_has_vpc_access when check_rest_api_is_private {
    %api_gws {
        Properties {
            #
            # ALL AWS::ApiGateway::RestApi resources in the template have one IAM condition key specified in the Policy property with 
            #     aws:sourceVpc or :SourceVpc
            #           
            some Policy.Statement[*] {
                Condition.*[ keys == /aws:[sS]ource(Vpc|VPC|Vpce|VPCE)/ ] !empty
            }
        }
    }
}
```

Este passo a passo testa a intenção da primeira regra: todos os `AWS::ApiGateway::RestApi` recursos implantados devem ser privados.

1. Crie um arquivo de teste unitário chamado `api_gateway_private_tests.yaml` que contenha o seguinte teste inicial. Com o teste inicial, adicione uma entrada vazia e espere que a regra `check_rest_api_is_private` seja ignorada porque não há `AWS::ApiGateway::RestApi` recursos como entradas.

   ```
   ---
   - name: MyTest1
     input: {}
     expectations:
       rules:
         check_rest_api_is_private: SKIP
   ```

1. Execute o primeiro teste em seu terminal usando o `test` comando. Para o `--rules-file` parâmetro, especifique seu arquivo de regras. Para o `--test-data` parâmetro, especifique seu arquivo de teste de unidade.

   ```
   cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml
   ```

   O resultado do primeiro teste é`PASS`.

   ```
   Test Case #1
   Name: "MyTest1"
     PASS Rules:
       check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP
   ```

1. Adicione outro teste ao seu arquivo de teste unitário. Agora, estenda o teste para incluir recursos vazios. A seguir está o `api_gateway_private_tests.yaml` arquivo atualizado.

   ```
   ---
   - name: MyTest1
     input: {}
     expectations:
       rules:
         check_rest_api_is_private: SKIP
   - name: MyTest2
     input:
        Resources: {}
     expectations:
       rules:
         check_rest_api_is_private: SKIP
   ```

1. Execute `test` com o arquivo de teste de unidade atualizado.

   ```
   cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml
   ```

   O resultado do segundo teste é`PASS`.

   ```
   Test Case #1
   Name: "MyTest1"
     PASS Rules:
       check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP
   Test Case #2
   Name: "MyTest2"
     PASS Rules:
       check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP
   ```

1. Adicione mais dois testes ao seu arquivo de teste unitário. Estenda o teste para incluir o seguinte:
   + Um `AWS::ApiGateway::RestApi` recurso sem propriedades especificadas.
**nota**  
Esse não é um CloudFormation modelo válido, mas é útil testar se a regra funciona corretamente mesmo para entradas malformadas.

     Espere que esse teste falhe porque a `EndpointConfiguration` propriedade não foi especificada e, portanto, não está definida como`PRIVATE`.
   + Um `AWS::ApiGateway::RestApi` recurso que satisfaz a primeira intenção com a `EndpointConfiguration` propriedade definida como`PRIVATE`, mas não satisfaz a segunda intenção porque não tem declarações de política definidas. Espere que esse teste passe.

   A seguir está o arquivo de teste unitário atualizado.

   ```
   ---
   - name: MyTest1
     input: {}
     expectations:
       rules:
         check_rest_api_is_private: SKIP
   - name: MyTest2
     input:
        Resources: {}
     expectations:
       rules:
         check_rest_api_is_private: SKIP
   - name: MyTest3
     input:
       Resources: 
         apiGw:
           Type: AWS::ApiGateway::RestApi
     expectations:
       rules:
         check_rest_api_is_private: FAIL
   - name: MyTest4
     input:
       Resources: 
         apiGw:
           Type: AWS::ApiGateway::RestApi
           Properties:
             EndpointConfiguration:
               Types: "PRIVATE"
     expectations:
       rules:
         check_rest_api_is_private: PASS
   ```

1. Execute `test` com o arquivo de teste de unidade atualizado.

   ```
   cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \
   ```

   O terceiro resultado é`FAIL`, e o quarto resultado é`PASS`.

   ```
   Test Case #1
   Name: "MyTest1"
     PASS Rules:
       check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP
   
   Test Case #2
   Name: "MyTest2"
     PASS Rules:
       check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP
   
   Test Case #3
   Name: "MyTest3"
     PASS Rules:
       check_rest_api_is_private: Expected = FAIL, Evaluated = FAIL
   
   Test Case #4
   Name: "MyTest4"
     PASS Rules:
       check_rest_api_is_private: Expected = PASS, Evaluated = PASS
   ```

1. Comente os testes 1—3 em seu arquivo de teste unitário. Acesse o contexto detalhado somente para o quarto teste. A seguir está o arquivo de teste unitário atualizado.

   ```
   ---
   #- name: MyTest1
   #  input: {}
   #  expectations:
   #    rules:
   #      check_rest_api_is_private_and_has_access: SKIP
   #- name: MyTest2
   #  input:
   #     Resources: {}
   #  expectations:
   #    rules:
   #      check_rest_api_is_private_and_has_access: SKIP
   #- name: MyTest3
   #  input:
   #    Resources: 
   #      apiGw:
   #        Type: AWS::ApiGateway::RestApi
   #  expectations:
   #    rules:
   #      check_rest_api_is_private_and_has_access: FAIL
   - name: MyTest4
     input:
       Resources: 
         apiGw:
           Type: AWS::ApiGateway::RestApi
           Properties:
             EndpointConfiguration:
               Types: "PRIVATE"
     expectations:
       rules:
         check_rest_api_is_private: PASS
   ```

1. Inspecione os resultados da avaliação executando o `test` comando em seu terminal, usando o `--verbose` sinalizador. O contexto detalhado é útil para entender as avaliações. Nesse caso, ele fornece informações detalhadas sobre por que o quarto teste teve sucesso com um `PASS` resultado.

   ```
   cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \
     --verbose
   ```

   Aqui está a saída dessa execução.

   ```
   Test Case #1
   Name: "MyTest4"
     PASS Rules:
       check_rest_api_is_private: Expected = PASS, Evaluated = PASS
   Rule(check_rest_api_is_private, PASS)
       |  Message: DEFAULT MESSAGE(PASS)
       Condition(check_rest_api_is_private, PASS)
           |  Message: DEFAULT MESSAGE(PASS)
           Clause(Clause(Location[file:api_gateway_private.guard, line:20, column:37], Check: %api_gws NOT EMPTY ), PASS)
               |  From: Map((Path("/Resources/apiGw"), MapValue { keys: [String((Path("/Resources/apiGw/Type"), "Type")), String((Path("/Resources/apiGw/Properties"), "Properties"))], values: {"Type": String((Path("/Resources/apiGw/Type"), "AWS::ApiGateway::RestApi")), "Properties": Map((Path("/Resources/apiGw/Properties"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration"), "EndpointConfiguration"))], values: {"EndpointConfiguration": Map((Path("/Resources/apiGw/Properties/EndpointConfiguration"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), "Types"))], values: {"Types": String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), "PRIVATE"))} }))} }))} }))
               |  Message: (DEFAULT: NO_MESSAGE)
       Conjunction(cfn_guard::rules::exprs::GuardClause, PASS)
           |  Message: DEFAULT MESSAGE(PASS)
           Clause(Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*]  EQUALS String("PRIVATE")), PASS)
               |  Message: (DEFAULT: NO_MESSAGE)
   ```

   A principal observação da saída é a linha`Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), PASS)`, que indica que a verificação foi aprovada. O exemplo também mostrou o caso em que se esperava que `Types` fosse uma matriz, mas um único valor foi fornecido. Nesse caso, a Guard continuou avaliando e fornecendo um resultado correto.

1. Adicione um caso de teste como o quarto caso de teste ao seu arquivo de teste de unidade para um `AWS::ApiGateway::RestApi` recurso com a `EndpointConfiguration` propriedade especificada. O caso de teste falhará em vez de ser aprovado. A seguir está o arquivo de teste unitário atualizado.

   ```
   ---
   #- name: MyTest1
   #  input: {}
   #  expectations:
   #    rules:
   #      check_rest_api_is_private_and_has_access: SKIP
   #- name: MyTest2
   #  input:
   #     Resources: {}
   #  expectations:
   #    rules:
   #      check_rest_api_is_private_and_has_access: SKIP
   #- name: MyTest3
   #  input:
   #    Resources: 
   #      apiGw:
   #        Type: AWS::ApiGateway::RestApi
   #  expectations:
   #    rules:
   #      check_rest_api_is_private_and_has_access: FAIL
   #- name: MyTest4
   #  input:
   #    Resources: 
   #      apiGw:
   #        Type: AWS::ApiGateway::RestApi
   #        Properties:
   #          EndpointConfiguration:
   #            Types: "PRIVATE"
   #  expectations:
   #    rules:
   #      check_rest_api_is_private: PASS
   - name: MyTest5
     input:
       Resources: 
         apiGw:
           Type: AWS::ApiGateway::RestApi
           Properties:
             EndpointConfiguration:
               Types: [PRIVATE, REGIONAL]
     expectations:
       rules:
         check_rest_api_is_private: FAIL
   ```

1. Execute o `test` comando com o arquivo de teste de unidade atualizado usando o `--verbose` sinalizador.

   ```
   cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \
    --verbose
   ```

   O `FAIL` resultado é o esperado porque `REGIONAL` está especificado`EndpointConfiguration`, mas não é esperado.

   ```
   Test Case #1
   Name: "MyTest5"
     PASS Rules: 
       check_rest_api_is_private: Expected = FAIL, Evaluated = FAIL
   Rule(check_rest_api_is_private, FAIL)
       |  Message: DEFAULT MESSAGE(FAIL)
       Condition(check_rest_api_is_private, PASS) 
           |  Message: DEFAULT MESSAGE(PASS)
           Clause(Clause(Location[file:api_gateway_private.guard, line:20, column:37], Check: %api_gws NOT EMPTY ), PASS)
               |  From: Map((Path("/Resources/apiGw"), MapValue { keys: [String((Path("/Resources/apiGw/Type"), "Type")), String((Path("/Resources/apiGw/Properties"), "Properties"))], values: {"Type": String((Path("/Resources/apiGw/Type"), "AWS::ApiGateway::RestApi")), "Properties": Map((Path("/Resources/apiGw/Properties"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration"), "EndpointConfiguration"))], values: {"EndpointConfiguration": Map((Path("/Resources/apiGw/Properties/EndpointConfiguration"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), "Types"))], values: {"Types": List((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), [String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types/0"), "PRIVATE")), String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types/1"), "REGIONAL"))]))} }))} }))} }))
               |  Message: DEFAULT MESSAGE(PASS)
       BlockClause(Block[Location[file:api_gateway_private.guard, line:21, column:3]], FAIL)
           |  Message: DEFAULT MESSAGE(FAIL)
           Conjunction(cfn_guard::rules::exprs::GuardClause, FAIL)
               |  Message: DEFAULT MESSAGE(FAIL)
               Clause(Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*]  EQUALS String("PRIVATE")), FAIL)
                   |  From: String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types/1"), "REGIONAL"))
                   |  To: String((Path("api_gateway_private.guard/22/5/Clause/"), "PRIVATE"))
                   |  Message: (DEFAULT: NO_MESSAGE)
   ```

   A saída detalhada do `test` comando segue a estrutura do arquivo de regras. Cada bloco no arquivo de regras é um bloco na saída detalhada. O bloco mais alto é cada regra. Se houver `when` condições contrárias à regra, elas aparecerão em um bloco de condições de irmãos. No exemplo a seguir, a condição `%api_gws !empty` é testada e aprovada.

   ```
   rule check_rest_api_is_private when %api_gws !empty {
   ```

   Depois que a condição for aprovada, testamos as cláusulas da regra.

   ```
   %api_gws {
       Properties.EndpointConfiguration.Types[*] == "PRIVATE"                      
   }
   ```

   `%api_gws`é uma regra de bloqueio que corresponde ao `BlockClause` nível na saída (linha: 21). A cláusula de regra é um conjunto de cláusulas de conjunção (AND), em que cada cláusula de conjunção é um conjunto de disjunções. `OR` A conjunção tem uma única cláusula,. `Properties.EndpointConfiguration.Types[*] == "PRIVATE"` Portanto, a saída detalhada mostra uma única cláusula. O caminho `/Resources/apiGw/Properties/EndpointConfiguration/Types/1` mostra quais valores na entrada são comparados, que nesse caso é o elemento `Types` indexado em 1.

Em[Validando os dados de entrada de acordo com as regras do Guard](validating-rules.md), você pode usar os exemplos desta seção para usar o `validate` comando para avaliar os dados de entrada em relação às regras.