github.com/datreeio/datree@v1.9.22-rc/pkg/policy/policy_test.go (about) 1 package policy 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "path/filepath" 8 "reflect" 9 "strconv" 10 "testing" 11 12 "github.com/datreeio/datree/pkg/defaultPolicies" 13 14 "github.com/datreeio/datree/pkg/defaultRules" 15 "github.com/datreeio/datree/pkg/fileReader" 16 "github.com/datreeio/datree/pkg/jsonSchemaValidator" 17 "github.com/ghodss/yaml" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 type TestFilesByRuleId = map[int]*FailAndPassTests 22 23 type FailAndPassTests struct { 24 fails []*FileWithPath 25 passes []*FileWithPath 26 } 27 28 type FileWithPath struct { 29 path string 30 content string 31 } 32 33 func TestGetPoliciesFileFromPath(t *testing.T) { 34 policiesYamlPath := "../../internal/fixtures/policyAsCode/policies.yaml" 35 policies, err := GetPoliciesFileFromPath(policiesYamlPath) 36 if err != nil { 37 panic(err) 38 } 39 40 expectedPoliciesJson := expectedPoliciesContent(t, policiesYamlPath) 41 assert.True(t, reflect.DeepEqual(policies, expectedPoliciesJson)) 42 } 43 44 func TestDefaultRulesValidation(t *testing.T) { 45 err := os.Chdir("../../") 46 if err != nil { 47 panic(err) 48 } 49 50 defaultRules, err := defaultRules.GetDefaultRules() 51 if err != nil { 52 panic(err) 53 } 54 55 testFilesByRuleId := getTestFilesByRuleId(t) 56 validator := jsonSchemaValidator.New() 57 58 for _, rule := range defaultRules.Rules { 59 validatePassing(t, validator, rule.Schema, rule.ID, testFilesByRuleId[rule.ID].passes, true) 60 validatePassing(t, validator, rule.Schema, rule.ID, testFilesByRuleId[rule.ID].fails, false) 61 } 62 } 63 64 func validatePassing(t *testing.T, validator *jsonSchemaValidator.JSONSchemaValidator, schemaContent map[string]interface{}, ruleId int, files []*FileWithPath, expectPass bool) { 65 for _, file := range files { 66 schemaBytes, err := yaml.Marshal(schemaContent) 67 if err != nil { 68 panic(err) 69 } 70 71 errorsResult, err := validator.ValidateYamlSchema(string(schemaBytes), file.content) 72 if err != nil { 73 panic(errors.New(err.Error() + fmt.Sprintf("\nruleId: %d", ruleId))) 74 } 75 76 if len(errorsResult) > 0 && expectPass { 77 t.Errorf("Expected validation for rule with id %d to pass, but it failed for file %s\n", ruleId, file.path) 78 } 79 if len(errorsResult) == 0 && !expectPass { 80 t.Errorf("Expected validation for rule with id %d to fail, but it passed for file %s\n", ruleId, file.path) 81 } 82 } 83 } 84 85 func getTestFilesByRuleId(t *testing.T) TestFilesByRuleId { 86 dirPath := "./pkg/policy/tests" 87 fileReader := fileReader.CreateFileReader(nil) 88 files, err := fileReader.ReadDir(dirPath) 89 if err != nil { 90 panic(err) 91 } 92 93 testFilesByRuleId := make(TestFilesByRuleId) 94 for _, filePath := range files { 95 // skip directories 96 if !fileExists(filePath) { 97 continue 98 } 99 100 path, _ := filepath.Split(filePath) 101 passOrFail := filepath.Base(path) 102 ruleId := filepath.Base(filepath.Dir(filepath.Dir(path))) 103 id, err := strconv.Atoi(ruleId) 104 if err != nil { 105 panic(err) 106 } 107 108 isPass := passOrFail == "pass" 109 110 fileContent, err := fileReader.ReadFileContent(filePath) 111 if err != nil { 112 panic(err) 113 } 114 115 if testFilesByRuleId[id] == nil { 116 testFilesByRuleId[id] = &FailAndPassTests{} 117 } 118 119 fileWithPath := &FileWithPath{path: filePath, content: fileContent} 120 if isPass { 121 testFilesByRuleId[id].passes = append(testFilesByRuleId[id].passes, fileWithPath) 122 } else { 123 testFilesByRuleId[id].fails = append(testFilesByRuleId[id].fails, fileWithPath) 124 } 125 } 126 127 return testFilesByRuleId 128 } 129 130 func fileExists(path string) bool { 131 info, err := os.Stat(path) 132 if os.IsNotExist(err) { 133 return false 134 } 135 return !info.IsDir() 136 } 137 138 func expectedPoliciesContent(t *testing.T, path string) *defaultPolicies.EvaluationPrerunPolicies { 139 fileReader := fileReader.CreateFileReader(nil) 140 policiesStr, _ := fileReader.ReadFileContent(path) 141 142 var policiesJson *defaultPolicies.EvaluationPrerunPolicies 143 policiesBytes, _ := yaml.YAMLToJSON([]byte(policiesStr)) 144 145 err := yaml.Unmarshal(policiesBytes, &policiesJson) 146 if err != nil { 147 panic(err) 148 } 149 return policiesJson 150 }