get.porter.sh/porter@v1.3.0/tests/integration/schema_test.go (about) 1 //go:build integration 2 3 package integration 4 5 import ( 6 "os" 7 "path/filepath" 8 "strings" 9 "testing" 10 11 "get.porter.sh/porter/pkg/config" 12 "get.porter.sh/porter/pkg/manifest" 13 testhelper "get.porter.sh/porter/pkg/test" 14 "get.porter.sh/porter/pkg/yaml" 15 "get.porter.sh/porter/tests" 16 "get.porter.sh/porter/tests/tester" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 "github.com/xeipuuv/gojsonschema" 20 ) 21 22 // Validates how porter integrates the mixin schema into porter's base schema to generate the final content for 23 // the porter schema command 24 func TestSchema(t *testing.T) { 25 test, err := tester.NewTest(t) 26 defer test.Close() 27 require.NoError(t, err, "test setup failed") 28 29 // Only use a well-known set of mixin in our home directory so that the schema is consistent 30 mixinsDir := filepath.Join(test.PorterHomeDir, "mixins") 31 mixins, err := os.ReadDir(mixinsDir) 32 for _, mixinDir := range mixins { 33 mixinName := mixinDir.Name() 34 if mixinName != "exec" && mixinName != "testmixin" { 35 require.NoError(t, os.RemoveAll(filepath.Join(mixinsDir, mixinName))) 36 } 37 } 38 39 // Validate that the schema matches what we expected 40 gotSchema, _ := test.RequirePorter("schema") 41 testhelper.CompareGoldenFile(t, "testdata/schema/schema.json", gotSchema) 42 43 testManifests := []struct { 44 name string 45 path string 46 wantErr string 47 }{ 48 {name: "valid", path: filepath.Join(test.RepoRoot, "tests/testdata/mybuns/porter.yaml")}, 49 {name: "invalid mixin declarations", path: "testdata/schema/invalid_mixin_config.yaml", 50 wantErr: `mixins.1: mixins.1 must be one of the following: "exec", "testmixin" 51 mixins.2: Must validate one and only one schema (oneOf) 52 mixins.2.testmixin: Additional property missingproperty is not allowed`}, 53 } 54 55 // Validate each manifest against the schema 56 for _, tm := range testManifests { 57 t.Run(tm.name, func(t *testing.T) { 58 // Load the manifest as a go dump 59 testManifestPath := tm.path 60 mani, err := manifest.ReadManifest(test.TestContext.Context, testManifestPath, config.NewTestConfig(t).Config) 61 62 maniYaml, err := yaml.Marshal(mani) 63 require.NoError(t, err, "error marshaling manifest to yaml") 64 65 m := make(map[string]interface{}) 66 err = yaml.Unmarshal(maniYaml, &m) 67 require.NoError(t, err, "failed to unmarshal %s", testManifestPath) 68 69 // Load the manifest schema returned from `porter schema` 70 manifestLoader := gojsonschema.NewGoLoader(m) 71 schemaLoader := gojsonschema.NewStringLoader(gotSchema) 72 73 // Validate the manifest against the schema 74 fails, err := gojsonschema.Validate(schemaLoader, manifestLoader) 75 require.NoError(t, err) 76 77 if tm.wantErr == "" { 78 assert.Empty(t, fails.Errors(), "expected %s to validate against the porter schema", testManifestPath) 79 // Print any validation errors returned 80 for _, err := range fails.Errors() { 81 t.Logf("%s", err) 82 } 83 } else { 84 var allFails strings.Builder 85 for _, err := range fails.Errors() { 86 allFails.WriteString(err.String()) 87 allFails.WriteString("\n") 88 } 89 tests.RequireOutputContains(t, allFails.String(), tm.wantErr) 90 } 91 }) 92 } 93 }