

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# AWS CloudFormation Guard Aturan pengujian
<a name="testing-rules"></a>

Anda dapat menggunakan kerangka pengujian unit AWS CloudFormation Guard bawaan untuk memverifikasi bahwa aturan Guard berfungsi sebagaimana dimaksud. Bagian ini memberikan panduan tentang cara menulis file pengujian unit dan cara menggunakannya untuk menguji file aturan Anda dengan perintah. `test`

File pengujian unit Anda harus memiliki salah satu ekstensi berikut:`.json`,`.JSON`,`.jsn`,`.yaml`,`.YAML`, atau`.yml`.

**Topics**
+ [Prasyarat](#testing-rules-prerequisites)
+ [Ikhtisar file pengujian unit Guard](#testing-rules-overview)
+ [Panduan penulisan file pengujian unit aturan Penjaga](#testing-rules-example)

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

Tulis aturan Guard untuk mengevaluasi data input Anda. Untuk informasi selengkapnya, lihat [Aturan Penjaga Menulis](writing-rules.md).

## Ikhtisar file pengujian unit Guard
<a name="testing-rules-overview"></a>

File pengujian unit penjaga adalah file berformat JSON atau YAML yang berisi beberapa input dan hasil yang diharapkan untuk aturan yang ditulis di dalam file aturan Guard. Mungkin ada beberapa sampel untuk menilai harapan yang berbeda. Kami menyarankan Anda memulai dengan menguji input kosong dan kemudian menambahkan informasi secara progresif untuk menilai berbagai aturan dan klausa.

Selain itu, kami menyarankan Anda memberi nama file pengujian unit menggunakan akhiran `_test.json` atau`_tests.yaml`. Misalnya, jika Anda memiliki file aturan bernama`my_rules.guard`, beri nama file pengujian unit Anda`my_rules_tests.yaml`.

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

Berikut ini menunjukkan sintaks file pengujian unit dalam format YAMM.

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

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

Berikut ini adalah properti dari file uji Guard.

`input`  <a name="testing-rules-properties-input"></a>
Data untuk menguji aturan Anda. Sebaiknya tes pertama Anda menggunakan input kosong, seperti yang ditunjukkan pada contoh berikut.  

```
---
- name: MyTest1
  input {}
```
Untuk pengujian selanjutnya, tambahkan data input untuk diuji.  
 *Wajib*: Ya 

`expectations`  <a name="testing-rules-properties-expectations"></a>
Hasil yang diharapkan ketika aturan tertentu dievaluasi terhadap data input Anda. Tentukan satu atau beberapa aturan yang ingin Anda uji selain hasil yang diharapkan untuk setiap aturan. Hasil yang diharapkan harus salah satu dari yang berikut:  
+ `PASS`— Ketika dijalankan terhadap data input Anda, aturan akan dievaluasi`true`.
+ `FAIL`— Ketika dijalankan terhadap data input Anda, aturan akan dievaluasi`false`.
+ `SKIP`— Saat dijalankan terhadap data input Anda, aturan tidak dipicu.

```
expectations:
    rules:
      check_rest_api_is_private: PASS
```
 *Wajib*: Ya 

## Panduan penulisan file pengujian unit aturan Penjaga
<a name="testing-rules-example"></a>

Berikut ini adalah file aturan bernama`api_gateway_private.guard`. Maksud dari aturan ini adalah untuk memeriksa apakah semua jenis sumber daya Amazon API Gateway yang ditentukan dalam CloudFormation templat disebarkan hanya untuk akses pribadi. Ini juga memeriksa apakah setidaknya satu pernyataan kebijakan memungkinkan akses dari virtual private cloud (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
            }
        }
    }
}
```

Panduan ini menguji maksud aturan pertama: Semua `AWS::ApiGateway::RestApi` sumber daya yang digunakan harus bersifat pribadi.

1. Buat file pengujian unit `api_gateway_private_tests.yaml` yang disebut yang berisi tes awal berikut. Dengan pengujian awal, tambahkan input kosong dan harapkan aturan `check_rest_api_is_private` akan dilewati karena tidak ada `AWS::ApiGateway::RestApi` sumber daya sebagai input.

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

1. Jalankan tes pertama di terminal Anda menggunakan `test` perintah. Untuk `--rules-file` parameter, tentukan file aturan Anda. Untuk `--test-data` parameter, tentukan file pengujian unit Anda.

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

   Hasil untuk tes pertama adalah`PASS`.

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

1. Tambahkan tes lain ke file pengujian unit Anda. Sekarang, perluas pengujian untuk memasukkan sumber daya kosong. Berikut ini adalah `api_gateway_private_tests.yaml` file yang diperbarui.

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

1. Jalankan `test` dengan file pengujian unit yang diperbarui.

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

   Hasil untuk tes kedua adalah`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. Tambahkan dua tes lagi ke file pengujian unit Anda. Perpanjang pengujian untuk memasukkan yang berikut:
   + `AWS::ApiGateway::RestApi`Sumber daya tanpa properti yang ditentukan.
**catatan**  
Ini bukan CloudFormation template yang valid, tetapi berguna untuk menguji apakah aturan berfungsi dengan benar bahkan untuk input yang salah bentuk.

     Harapkan pengujian ini akan gagal karena `EndpointConfiguration` properti tidak ditentukan dan oleh karena itu tidak disetel ke`PRIVATE`.
   + `AWS::ApiGateway::RestApi`Sumber daya yang memenuhi intent pertama dengan `EndpointConfiguration` properti yang disetel ke `PRIVATE` tetapi tidak memenuhi maksud kedua karena tidak memiliki pernyataan kebijakan yang ditentukan. Harapkan tes ini akan lulus.

   Berikut ini adalah file pengujian unit yang diperbarui.

   ```
   ---
   - 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. Jalankan `test` dengan file pengujian unit yang diperbarui.

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

   Hasil ketiga adalah`FAIL`, dan hasil keempat adalah`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. Komentari tes 1-3 dalam file pengujian unit Anda. Akses konteks verbose untuk tes keempat saja. Berikut ini adalah file pengujian unit yang diperbarui.

   ```
   ---
   #- 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. Periksa hasil evaluasi dengan menjalankan `test` perintah di terminal Anda, menggunakan `--verbose` bendera. Konteks verbose berguna untuk memahami evaluasi. Dalam hal ini, ini memberikan informasi rinci tentang mengapa tes keempat berhasil dengan `PASS` hasil.

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

   Berikut adalah output dari run itu.

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

   Pengamatan utama dari output adalah garis`Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), PASS)`, yang menyatakan bahwa cek lulus. Contoh ini juga menunjukkan kasus `Types` di mana diharapkan menjadi array, tetapi satu nilai diberikan. Dalam hal ini, Guard terus mengevaluasi dan memberikan hasil yang benar.

1. Tambahkan kasus uji seperti kasus uji keempat ke file pengujian unit Anda untuk `AWS::ApiGateway::RestApi` sumber daya dengan `EndpointConfiguration` properti yang ditentukan. Kasus uji akan gagal alih-alih lulus. Berikut ini adalah file pengujian unit yang diperbarui.

   ```
   ---
   #- 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. Jalankan `test` perintah dengan file pengujian unit yang diperbarui menggunakan `--verbose` bendera.

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

   Hasilnya `FAIL` seperti yang diharapkan karena `REGIONAL` ditentukan untuk `EndpointConfiguration` tetapi tidak diharapkan.

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

   Output verbose dari `test` perintah mengikuti struktur file aturan. Setiap blok dalam file aturan adalah blok dalam output verbose. Blok paling atas adalah setiap aturan. Jika ada `when` kondisi yang bertentangan dengan aturan, mereka muncul di blok kondisi saudara kandung. Dalam contoh berikut, kondisi `%api_gws !empty` diuji dan berlalu.

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

   Setelah kondisi berlalu, kami menguji klausa aturan.

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

   `%api_gws`adalah aturan blok yang sesuai dengan `BlockClause` level dalam output (baris: 21). Klausa aturanadalah seperangkat klausa konjungsi (AND), di mana setiap klausa konjungsi adalah sekumpulan disjungsi. `OR` Konjungsi memiliki satu klausa,. `Properties.EndpointConfiguration.Types[*] == "PRIVATE"` Oleh karena itu, output verbose menunjukkan satu klausa. Jalur `/Resources/apiGw/Properties/EndpointConfiguration/Types/1` menunjukkan nilai mana dalam input yang dibandingkan, yang dalam hal ini adalah elemen untuk `Types` diindeks pada 1.

Di[Memvalidasi data input terhadap aturan Guard](validating-rules.md), Anda dapat menggunakan contoh di bagian ini untuk menggunakan `validate` perintah untuk mengevaluasi data input terhadap aturan.