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  }