예제 #1
0
// Validate validates the provided data (d) against the provided schema (s).
func Validate(ctx types.Context, s, d []byte) error {

	if ctx == nil {
		log.StandardLogger().WithFields(log.Fields{
			"schema": string(s),
			"body":   string(d),
		}).Debug("validating schema")
	} else {
		ctx.WithFields(log.Fields{
			"schema": string(s),
			"body":   string(d),
		}).Debug("validating schema")
	}

	validator, err := getSchemaValidator(s)
	if err != nil {
		return err
	}

	if len(d) == 0 {
		d = []byte("{}")
	}

	data, err := ucl.Parse(bytes.NewReader(d))
	if err != nil {
		return err
	}
	return validator.Validate(data)
}
예제 #2
0
func TestCompliance(t *testing.T) {
	done := make(chan struct{})
	go serveRemotes(t, done)
	f, err := os.Open("draft04schema.json")
	if err != nil {
		t.Fatalf("Failed to open draft04schema.json: %s", err)
	}
	s, err := json.Parse(f)
	f.Close()
	if err != nil {
		t.Fatalf("Failed to parse draft04schema.json: %s", err)
	}
	loader := NewLoader()
	loader.Add(s)
	loader.EnableNetworkAccess(true)

	select {
	case <-done:
		t.Fatalf("HTTP server died")
	default:
	}

	files, err := filepath.Glob("schema-tests/tests/draft4/*.json")
	if err != nil {
		t.Fatalf("Test files not found: %s", err)
	}
	testFiles(t, files, loader)
}
예제 #3
0
func testFiles(t *testing.T, files []string, loader *Loader) {
	var passing, total, schemaErrors int
	for _, file := range files {
		f, err := os.Open(file)
		if err != nil {
			t.Fatalf("Failed to open %q: %s", file, err)
		}
		v, err := json.Parse(f)
		f.Close()
		if err != nil {
			t.Fatalf("Failed to parse %q: %s", file, err)
		}

		tests, ok := v.(*json.Array)
		if !ok {
			t.Fatalf("Content of %q is not an array: %T", file, v)
		}
		for i, tt := range tests.Value {
			test, ok := tt.(*json.Object)
			if !ok {
				t.Fatalf("Test %d in %q is not an object", i, file)
			}
			t.Logf(color.BlueString("=====> Testing %s, case %d: %s", file, i, test.Find("description")))
			schema := test.Find("schema")
			err := ValidateDraft04Schema(schema)
			if err != nil {
				t.Errorf(color.RedString("schema does not pass validation: %s", err))
				schemaErrors++
			}
			v, _ := NewValidator(schema, loader) // not checking the error since schema is already validated
			cases := test.Find("tests").(*json.Array)
			for _, c := range cases.Value {
				total++
				case_ := c.(*json.Object)
				valid := case_.Find("valid").(*json.Bool).Value
				err := v.Validate(case_.Find("data"))
				switch {
				case err == nil && valid:
					passing++
					t.Logf("%s %s", color.GreenString("PASSED"), case_.Find("description"))
				case err != nil && !valid:
					passing++
					t.Logf("%s %s: %s", color.GreenString("PASSED"), case_.Find("description"), err)
				case err != nil && valid:
					t.Errorf("%s %s: %s", color.RedString("FAILED"), case_.Find("description"), err)
				case err == nil && !valid:
					t.Errorf("%s %s", color.RedString("FAILED"), case_.Find("description"))
				}
			}
		}
	}
	t.Logf("Passing %d out of %d tests (%g%%)", passing, total, float64(passing)/float64(total)*100)
	if schemaErrors > 0 {
		t.Logf("%d schemas failed validation", schemaErrors)
	}
}
예제 #4
0
func getSchemaValidator(s []byte) (*schema.Validator, error) {
	volSchema, err := ucl.Parse(bytes.NewReader(s))
	if err != nil {
		return nil, err
	}

	rootSchema, err := ucl.Parse(bytes.NewReader(jsonSchema))
	if err != nil {
		return nil, err
	}

	loader := schema.NewLoader()

	if err := loader.Add(rootSchema); err != nil {
		return nil, err
	}

	validator, err := schema.NewValidator(volSchema, loader)
	if err != nil {
		return nil, err
	}

	return validator, nil
}
예제 #5
0
// Get returns a schema identified with id.
func (l *Loader) Get(id string) (json.Value, error) {
	s, found := l.cache[id]
	if found {
		return s, nil
	}
	if l.networkEnabled {
		resp, err := http.Get(id)
		if err != nil {
			return nil, err
		}
		s, err := json.Parse(resp.Body)
		resp.Body.Close()
		if err != nil {
			return nil, err
		}
		l.AddAs(s, id)
		return s, nil
	}
	return nil, fmt.Errorf("schema %q is not present in the cache and fetching is disabled", id)
}
예제 #6
0
func main() {
	flag.Parse()

	if *schemaFile == "" || *inputFile == "" {
		fmt.Fprintf(os.Stderr, "Need --schema and --input\n")
		os.Exit(1)
	}

	f, err := os.Open(*schemaFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open %q: %s\n", *schemaFile, err)
		os.Exit(1)
	}

	s, err := json.Parse(f)
	f.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to read schema: %s\n", err)
		os.Exit(1)
	}

	loader := schema.NewLoader()
	loader.EnableNetworkAccess(*network)
	if *extra != "" {
		for _, file := range strings.Split(*extra, " ") {
			f, err := os.Open(file)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to open %q: %s\n", file, err)
				os.Exit(1)
			}
			s, err := json.Parse(f)
			f.Close()
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to parse %q: %s\n", file, err)
				os.Exit(1)
			}
			loader.Add(s)
		}
	}
	if !*skipDefaultSchema {
		ds, err := json.Parse(bytes.NewBuffer(MustAsset("draft04schema.json")))
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to parse embedded draft 04 schema: %s\n", err)
			os.Exit(1)
		}
		// Just to be sure, schema.ParseDraft04Schema exercises different code path.
		v, err := schema.NewValidator(ds, loader)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create validator for draft04 schema, please file a bug: %s\n", err)
		} else {
			if err := v.Validate(s); err != nil {
				fmt.Fprintln(os.Stderr, "If you see this message, please file a bug and attach the schema you're using.")
				fmt.Fprintf(os.Stderr, "Warning: failed to validate %q with draft 04 schema: %s\n", *schemaFile, err)
			}
		}
	}

	validator, err := schema.NewValidator(s, loader)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create validator: %s\n", err)
		os.Exit(1)
	}

	f, err = os.Open(*inputFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open input file: %s\n", err)
		os.Exit(1)
	}
	defer f.Close()
	data, err := json.Parse(f)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to parse input file: %s\n", err)
		os.Exit(1)
	}
	if err := validator.Validate(data); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}