

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# AWS CloudFormation Guard Regole di test
<a name="testing-rules"></a>

Puoi utilizzare il framework di unit testing AWS CloudFormation Guard integrato per verificare che le regole di Guard funzionino come previsto. Questa sezione fornisce una procedura dettagliata su come scrivere un file di unit testing e su come utilizzarlo per testare il file delle regole con il `test` comando.

Il file di unit test deve avere una delle seguenti estensioni:`.json`,,`.JSON`, `.jsn` `.yaml``.YAML`, o. `.yml`

**Topics**
+ [Prerequisiti](#testing-rules-prerequisites)
+ [Panoramica dei file di test delle unità Guard](#testing-rules-overview)
+ [Procedura dettagliata per la scrittura di un file di test unitario delle regole di Guard](#testing-rules-example)

## Prerequisiti
<a name="testing-rules-prerequisites"></a>

Scrivi le regole di Guard in base alle quali valutare i tuoi dati di input. Per ulteriori informazioni, consulta [regole di Writing Guard](writing-rules.md).

## Panoramica dei file di test delle unità Guard
<a name="testing-rules-overview"></a>

I file di test delle unità Guard sono file in formato JSON o YAML che contengono più input e i risultati previsti per le regole scritte all'interno di un file di regole Guard. Possono esserci più esempi per valutare aspettative diverse. Ti consigliamo di iniziare verificando la presenza di input vuoti e quindi di aggiungere progressivamente informazioni per valutare varie regole e clausole.

Inoltre, si consiglia di denominare i file di unit test utilizzando il suffisso o. `_test.json` `_tests.yaml` Ad esempio, se avete un file di regole denominato`my_rules.guard`, assegnate un nome al file `my_rules_tests.yaml` di unit testing.

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

Di seguito viene illustrata la sintassi di un file di unit testing in formato YAML.

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

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

Di seguito sono riportate le proprietà di un file di test Guard.

`input`  <a name="testing-rules-properties-input"></a>
Dati in base ai quali testare le tue regole. È consigliabile che il primo test utilizzi un input vuoto, come illustrato nell'esempio seguente.  

```
---
- name: MyTest1
  input {}
```
Per i test successivi, aggiungi i dati di input al test.  
 *Obbligatorio:* sì 

`expectations`  <a name="testing-rules-properties-expectations"></a>
Il risultato previsto quando regole specifiche vengono valutate rispetto ai dati di input. Specificate una o più regole da testare oltre al risultato previsto per ogni regola. Il risultato previsto deve essere uno dei seguenti:  
+ `PASS`— Quando vengono eseguite sulla base dei dati di input, le regole restituiscono lo stesso risultato`true`.
+ `FAIL`— Quando vengono eseguite in base ai dati di input, le regole restituiscono lo stesso risultato`false`.
+ `SKIP`— Quando viene eseguita sui dati di input, la regola non viene attivata.

```
expectations:
    rules:
      check_rest_api_is_private: PASS
```
 *Obbligatorio:* sì 

## Procedura dettagliata per la scrittura di un file di test unitario delle regole di Guard
<a name="testing-rules-example"></a>

Di seguito è riportato un file di regole denominato. `api_gateway_private.guard` L'intento di questa regola è verificare se tutti i tipi di risorse Amazon API Gateway definiti in un CloudFormation modello sono distribuiti solo per l'accesso privato. Verifica inoltre se almeno una dichiarazione di policy consente l'accesso da un cloud privato virtuale (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
            }
        }
    }
}
```

Questa procedura dettagliata verifica l'intento della prima regola: tutte le `AWS::ApiGateway::RestApi` risorse distribuite devono essere private.

1. Crea un file di unit test chiamato `api_gateway_private_tests.yaml` che contiene il seguente test iniziale. Con il test iniziale, aggiungi un input vuoto e aspettati che la regola `check_rest_api_is_private` venga ignorata perché non ci sono `AWS::ApiGateway::RestApi` risorse come input.

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

1. Esegui il primo test nel tuo terminale usando il `test` comando. Per il `--rules-file` parametro, specifica il file delle regole. Per il `--test-data` parametro, specificate il file di test unitario.

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

   Il risultato del primo test è`PASS`.

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

1. Aggiungi un altro test al tuo file di unit test. Ora estendi il test per includere risorse vuote. Di seguito è riportato il `api_gateway_private_tests.yaml` file aggiornato.

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

1. Esegui `test` con il file di unit test aggiornato.

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

   Il risultato del secondo test è`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. Aggiungi altri due test al tuo file di unit testing. Estendi il test per includere quanto segue:
   + Una `AWS::ApiGateway::RestApi` risorsa senza proprietà specificate.
**Nota**  
Questo non è un CloudFormation modello valido, ma è utile per verificare se la regola funziona correttamente anche per input non validi.

     Aspettatevi che questo test abbia esito negativo perché la `EndpointConfiguration` proprietà non è specificata e quindi non è impostata su. `PRIVATE`
   + Una `AWS::ApiGateway::RestApi` risorsa che soddisfa il primo intento con la `EndpointConfiguration` proprietà impostata su `PRIVATE` ma non soddisfa il secondo intento perché non ha istruzioni politiche definite. Aspettatevi che questo test venga superato.

   Di seguito è riportato il file di unit test aggiornato.

   ```
   ---
   - 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. Esegui `test` con il file di unit test aggiornato.

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

   Il terzo risultato è`FAIL`, e il quarto risultato è`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. Commenta i test 1-3 nel tuo file di unit testing. Accedi al contesto dettagliato solo per il quarto test. Di seguito è riportato il file di unit test aggiornato.

   ```
   ---
   #- 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. Controlla i risultati della valutazione eseguendo il `test` comando nel tuo terminale, usando il `--verbose` flag. Il contesto verboso è utile per comprendere le valutazioni. In questo caso, fornisce informazioni dettagliate sul motivo per cui il quarto test ha avuto esito positivo. `PASS`

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

   Ecco l'output di quella corsa.

   ```
   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)
   ```

   L'osservazione chiave dell'output è la riga`Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), PASS)`, che indica che il controllo è stato superato. L'esempio ha mostrato anche il caso in cui ci si `Types` aspettava che fosse un array, ma è stato fornito un singolo valore. In tal caso, Guard ha continuato a valutare e ha fornito un risultato corretto.

1. Aggiungi un test case come il quarto test case al tuo file di unit testing per una `AWS::ApiGateway::RestApi` risorsa con la `EndpointConfiguration` proprietà specificata. Il test case fallirà invece di essere superato. Di seguito è riportato il file di test unitario aggiornato.

   ```
   ---
   #- 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. Esegui il `test` comando con il file di unit test aggiornato usando il `--verbose` flag.

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

   Il risultato è quello `FAIL` previsto perché `REGIONAL` è stato specificato `EndpointConfiguration` ma non è previsto.

   ```
   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)
   ```

   L'output dettagliato del `test` comando segue la struttura del file delle regole. Ogni blocco nel file delle regole è un blocco nell'output dettagliato. Il blocco più in alto è ogni regola. Se sono presenti `when` condizioni contrarie alla regola, queste vengono visualizzate in un blocco di condizioni di pari livello. Nell'esempio seguente, la condizione `%api_gws !empty` viene testata e viene soddisfatta.

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

   Una volta superata la condizione, testiamo le clausole della regola.

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

   `%api_gws`è una regola di blocco che corrisponde al `BlockClause` livello dell'output (linea:21). La clausola della regola è un insieme di clausole di congiunzione (AND), in cui ogni clausola di congiunzione è un insieme di disgiunzioni. `OR` La `Properties.EndpointConfiguration.Types[*] == "PRIVATE"` congiunzione ha una sola clausola,. Pertanto, l'output dettagliato mostra una singola clausola. Il percorso `/Resources/apiGw/Properties/EndpointConfiguration/Types/1` mostra quali valori dell'input vengono confrontati, che in questo caso è l'elemento `Types` indicizzato a 1.

In[Convalida dei dati di input rispetto alle regole di Guard](validating-rules.md), è possibile utilizzare gli esempi in questa sezione per utilizzare il `validate` comando per valutare i dati di input in base alle regole.