func BenchmarkReplicationControllerConversion(b *testing.B) { data, err := ioutil.ReadFile("replication_controller_example.json") if err != nil { b.Fatalf("Unexpected error while reading file: %v", err) } var replicationController api.ReplicationController if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } scheme := api.Scheme var result *api.ReplicationController for i := 0; i < b.N; i++ { versionedObj, err := scheme.ConvertToVersion(&replicationController, testapi.Default.GroupVersion().String()) if err != nil { b.Fatalf("Conversion error: %v", err) } obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String()) if err != nil { b.Fatalf("Conversion error: %v", err) } result = obj.(*api.ReplicationController) } if !api.Semantic.DeepDerivative(replicationController, *result) { b.Fatalf("Incorrect conversion: expected %v, got %v", replicationController, *result) } }
func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { t.Logf("codec: %#v", codec) printer := spew.ConfigState{DisableMethods: true} name := reflect.TypeOf(item).Elem().Name() data, err := runtime.Encode(codec, item) if err != nil { t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item)) return } obj2, err := runtime.Decode(codec, data) if err != nil { t.Errorf("0: %v: %v\nCodec: %v\nData: %s\nSource: %#v", name, err, codec, string(data), printer.Sprintf("%#v", item)) return } if !api.Semantic.DeepEqual(item, obj2) { t.Errorf("\n1: %v: diff: %v\nCodec: %v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, util.ObjectGoPrintDiff(item, obj2), codec, printer.Sprintf("%#v", item), string(data), printer.Sprintf("%#v", obj2)) return } obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) if err := runtime.DecodeInto(codec, data, obj3); err != nil { t.Errorf("2: %v: %v", name, err) return } if !api.Semantic.DeepEqual(item, obj3) { t.Errorf("3: %v: diff: %v\nCodec: %v", name, util.ObjectDiff(item, obj3), codec) return } }
func BenchmarkPodConversion(b *testing.B) { data, err := ioutil.ReadFile("pod_example.json") if err != nil { b.Fatalf("Unexpected error while reading file: %v", err) } var pod api.Pod if err := runtime.DecodeInto(testapi.Default.Codec(), data, &pod); err != nil { b.Fatalf("Unexpected error decoding pod: %v", err) } scheme := api.Scheme var result *api.Pod for i := 0; i < b.N; i++ { versionedObj, err := scheme.ConvertToVersion(&pod, testapi.Default.GroupVersion().String()) if err != nil { b.Fatalf("Conversion error: %v", err) } obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String()) if err != nil { b.Fatalf("Conversion error: %v", err) } result = obj.(*api.Pod) } if !api.Semantic.DeepDerivative(pod, *result) { b.Fatalf("Incorrect conversion: expected %v, got %v", pod, *result) } }
func runTest(t *testing.T, source interface{}) { name := reflect.TypeOf(source).Elem().Name() TestObjectFuzzer.Fuzz(source) _, codec := GetTestScheme() data, err := runtime.Encode(codec, source.(runtime.Object)) if err != nil { t.Errorf("%v: %v (%#v)", name, err, source) return } obj2, err := runtime.Decode(codec, data) if err != nil { t.Errorf("%v: %v (%v)", name, err, string(data)) return } if !semantic.DeepEqual(source, obj2) { t.Errorf("1: %v: diff: %v", name, util.ObjectGoPrintSideBySide(source, obj2)) return } obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface() if err := runtime.DecodeInto(codec, data, obj3.(runtime.Object)); err != nil { t.Errorf("2: %v: %v", name, err) return } if !semantic.DeepEqual(source, obj3) { t.Errorf("3: %v: diff: %v", name, objDiff(source, obj3)) return } }
func TestBadJSONRejection(t *testing.T) { log.SetOutput(os.Stderr) _, codec := GetTestScheme() badJSONs := [][]byte{ []byte(`{"myVersionKey":"v1"}`), // Missing kind []byte(`{"myVersionKey":"v1","myKindKey":"bar"}`), // Unknown kind []byte(`{"myVersionKey":"bar","myKindKey":"TestType1"}`), // Unknown version []byte(`{"myKindKey":"TestType1"}`), // Missing version } for _, b := range badJSONs { if _, err := runtime.Decode(codec, b); err == nil { t.Errorf("Did not reject bad json: %s", string(b)) } } badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`) if err := runtime.DecodeInto(codec, badJSONKindMismatch, &TestType1{}); err == nil { t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch) } if err := runtime.DecodeInto(codec, []byte(``), &TestType1{}); err != nil { t.Errorf("Should allow empty decode: %v", err) } if _, _, err := codec.Decode([]byte(``), &unversioned.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err == nil { t.Errorf("Did not give error for empty data with only kind default") } if _, _, err := codec.Decode([]byte(`{"myVersionKey":"v1"}`), &unversioned.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err != nil { t.Errorf("Gave error for version and kind default") } if _, _, err := codec.Decode([]byte(`{"myKindKey":"ExternalInternalSame"}`), &unversioned.GroupVersionKind{Version: "v1"}, nil); err != nil { t.Errorf("Gave error for version and kind default") } if _, _, err := codec.Decode([]byte(``), &unversioned.GroupVersionKind{Kind: "ExternalInternalSame", Version: "v1"}, nil); err != nil { t.Errorf("Gave error for version and kind defaulted: %v", err) } if _, err := runtime.Decode(codec, []byte(``)); err == nil { t.Errorf("Did not give error for empty data") } }
func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) { internalGV := unversioned.GroupVersion{Version: runtime.APIVersionInternal} externalGV := unversioned.GroupVersion{Version: "v1"} s := runtime.NewScheme() // create two names internally, with TestType1 being preferred s.AddKnownTypeWithName(internalGV.WithKind("TestType1"), &TestType1{}) s.AddKnownTypeWithName(internalGV.WithKind("OtherType1"), &TestType1{}) // create two names externally, with TestType1 being preferred s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("OtherType1"), &ExternalTestType1{}) ext := &ExternalTestType1{} ext.APIVersion = "v1" ext.ObjectKind = "OtherType1" ext.A = "test" data, err := json.Marshal(ext) if err != nil { t.Fatalf("unexpected error: %v", err) } expect := &TestType1{A: "test"} codec := newCodecFactory(s, testMetaFactory{}).LegacyCodec(unversioned.GroupVersion{Version: "v1"}) obj, err := runtime.Decode(codec, data) if err != nil { t.Fatalf("unexpected error: %v", err) } if !semantic.DeepEqual(expect, obj) { t.Errorf("unexpected object: %#v", obj) } into := &TestType1{} if err := runtime.DecodeInto(codec, data, into); err != nil { t.Fatalf("unexpected error: %v", err) } if !semantic.DeepEqual(expect, into) { t.Errorf("unexpected object: %#v", obj) } }
func BenchmarkDecodeIntoInternalCodec(b *testing.B) { codec := testapi.Default.Codec() items := benchmarkItems() width := len(items) encoded := make([][]byte, width) for i := range items { data, err := runtime.Encode(codec, &items[i]) if err != nil { b.Fatal(err) } encoded[i] = data } b.ResetTimer() for i := 0; i < b.N; i++ { obj := api.Pod{} if err := runtime.DecodeInto(codec, encoded[i%width], &obj); err != nil { b.Fatal(err) } } b.StopTimer() }
func BenchmarkReplicationControllerCopy(b *testing.B) { data, err := ioutil.ReadFile("replication_controller_example.json") if err != nil { b.Fatalf("Unexpected error while reading file: %v", err) } var replicationController api.ReplicationController if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } var result *api.ReplicationController for i := 0; i < b.N; i++ { obj, err := api.Scheme.DeepCopy(&replicationController) if err != nil { b.Fatalf("Unexpected error copying replication controller: %v", err) } result = obj.(*api.ReplicationController) } if !api.Semantic.DeepEqual(replicationController, *result) { b.Fatalf("Incorrect copy: expected %v, got %v", replicationController, *result) } }
func BenchmarkNodeCopy(b *testing.B) { data, err := ioutil.ReadFile("node_example.json") if err != nil { b.Fatalf("Unexpected error while reading file: %v", err) } var node api.Node if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil { b.Fatalf("Unexpected error decoding node: %v", err) } var result *api.Node for i := 0; i < b.N; i++ { obj, err := api.Scheme.DeepCopy(&node) if err != nil { b.Fatalf("Unexpected error copying node: %v", err) } result = obj.(*api.Node) } if !api.Semantic.DeepEqual(node, *result) { b.Fatalf("Incorrect copy: expected %v, got %v", node, *result) } }
func BenchmarkPodCopy(b *testing.B) { data, err := ioutil.ReadFile("pod_example.json") if err != nil { b.Fatalf("Unexpected error while reading file: %v", err) } var pod api.Pod if err := runtime.DecodeInto(testapi.Default.Codec(), data, &pod); err != nil { b.Fatalf("Unexpected error decoding pod: %v", err) } var result *api.Pod for i := 0; i < b.N; i++ { obj, err := api.Scheme.DeepCopy(&pod) if err != nil { b.Fatalf("Unexpected error copying pod: %v", err) } result = obj.(*api.Pod) } if !api.Semantic.DeepEqual(pod, *result) { b.Fatalf("Incorrect copy: expected %v, got %v", pod, *result) } }
func TestScheme(t *testing.T) { internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"} scheme := runtime.NewScheme() scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) // If set, would clear TypeMeta during conversion. //scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{}) // test that scheme is an ObjectTyper var _ runtime.ObjectTyper = scheme internalToExternalCalls := 0 externalToInternalCalls := 0 // Register functions to verify that scope.Meta() gets set correctly. err := scheme.AddConversionFuncs( func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error { if e, a := internalGV.String(), scope.Meta().SrcVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } if e, a := externalGV.String(), scope.Meta().DestVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) scope.Convert(&in.TestString, &out.TestString, 0) internalToExternalCalls++ return nil }, func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error { if e, a := externalGV.String(), scope.Meta().SrcVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } if e, a := internalGV.String(), scope.Meta().DestVersion; e != a { t.Errorf("Expected '%v', got '%v'", e, a) } scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) scope.Convert(&in.TestString, &out.TestString, 0) externalToInternalCalls++ return nil }, ) if err != nil { t.Fatalf("unexpected error: %v", err) } codecs := serializer.NewCodecFactory(scheme) codec := codecs.LegacyCodec(externalGV) jsonserializer, _ := codecs.SerializerForFileExtension("json") simple := &InternalSimple{ TestString: "foo", } // Test Encode, Decode, DecodeInto, and DecodeToVersion obj := runtime.Object(simple) data, err := runtime.Encode(codec, obj) if err != nil { t.Fatal(err) } obj2, err := runtime.Decode(codec, data) if err != nil { t.Fatal(err) } if _, ok := obj2.(*InternalSimple); !ok { t.Fatalf("Got wrong type") } if e, a := simple, obj2; !reflect.DeepEqual(e, a) { t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) } obj3 := &InternalSimple{} if err := runtime.DecodeInto(codec, data, obj3); err != nil { t.Fatal(err) } // clearing TypeMeta is a function of the scheme, which we do not test here (ConvertToVersion // does not automatically clear TypeMeta anymore). simple.TypeMeta = runtime.TypeMeta{Kind: "Simple", APIVersion: externalGV.String()} if e, a := simple, obj3; !reflect.DeepEqual(e, a) { t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) } obj4, err := runtime.Decode(jsonserializer, data) if err != nil { t.Fatal(err) } if _, ok := obj4.(*ExternalSimple); !ok { t.Fatalf("Got wrong type") } // Test Convert external := &ExternalSimple{} err = scheme.Convert(simple, external) if err != nil { t.Fatalf("Unexpected error: %v", err) } if e, a := simple.TestString, external.TestString; e != a { t.Errorf("Expected %v, got %v", e, a) } // Encode and Convert should each have caused an increment. if e, a := 2, internalToExternalCalls; e != a { t.Errorf("Expected %v, got %v", e, a) } // DecodeInto and Decode should each have caused an increment because of a conversion if e, a := 2, externalToInternalCalls; e != a { t.Errorf("Expected %v, got %v", e, a) } }
// TODO: Have policies be created via an API call and stored in REST storage. func NewFromFile(path string) (policyList, error) { // File format is one map per line. This allows easy concatentation of files, // comments in files, and identification of errors by line number. file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() scanner := bufio.NewScanner(file) pl := make(policyList, 0) decoder := api.Codecs.UniversalDecoder() i := 0 unversionedLines := 0 for scanner.Scan() { i++ p := &api.Policy{} b := scanner.Bytes() // skip comment lines and blank lines trimmed := strings.TrimSpace(string(b)) if len(trimmed) == 0 || strings.HasPrefix(trimmed, "#") { continue } decodedObj, _, err := decoder.Decode(b, nil, nil) if err != nil { if !(runtime.IsMissingVersion(err) || runtime.IsMissingKind(err) || runtime.IsNotRegisteredError(err)) { return nil, policyLoadError{path, i, b, err} } unversionedLines++ // Migrate unversioned policy object oldPolicy := &v0.Policy{} if err := runtime.DecodeInto(decoder, b, oldPolicy); err != nil { return nil, policyLoadError{path, i, b, err} } if err := api.Scheme.Convert(oldPolicy, p); err != nil { return nil, policyLoadError{path, i, b, err} } pl = append(pl, p) continue } decodedPolicy, ok := decodedObj.(*api.Policy) if !ok { return nil, policyLoadError{path, i, b, fmt.Errorf("unrecognized object: %#v", decodedObj)} } pl = append(pl, decodedPolicy) } if unversionedLines > 0 { glog.Warningf(`Policy file %s contained unversioned rules. See docs/admin/authorization.md#abac-mode for ABAC file format details.`, path) } if err := scanner.Err(); err != nil { return nil, policyLoadError{path, -1, nil, err} } return pl, nil }
// Into stores the result into obj, if possible. If obj is nil it is ignored. func (r Result) Into(obj runtime.Object) error { if r.err != nil { return r.err } return runtime.DecodeInto(r.decoder, r.body, obj) }