func validateEvent(messagePrefix string, actualEvent *api.Event, expectedEvent *api.Event, t *testing.T) (*api.Event, error) { recvEvent := *actualEvent expectCompression := expectedEvent.Count > 1 t.Logf("%v - expectedEvent.Count is %d\n", messagePrefix, expectedEvent.Count) // Just check that the timestamp was set. if recvEvent.FirstTimestamp.IsZero() || recvEvent.LastTimestamp.IsZero() { t.Errorf("%v - timestamp wasn't set: %#v", messagePrefix, recvEvent) } actualFirstTimestamp := recvEvent.FirstTimestamp actualLastTimestamp := recvEvent.LastTimestamp if actualFirstTimestamp.Equal(actualLastTimestamp) { if expectCompression { t.Errorf("%v - FirstTimestamp (%q) and LastTimestamp (%q) must be different to indicate event compression happened, but were the same. Actual Event: %#v", messagePrefix, actualFirstTimestamp, actualLastTimestamp, recvEvent) } } else { if expectedEvent.Count == 1 { t.Errorf("%v - FirstTimestamp (%q) and LastTimestamp (%q) must be equal to indicate only one occurrence of the event, but were different. Actual Event: %#v", messagePrefix, actualFirstTimestamp, actualLastTimestamp, recvEvent) } } // Temp clear time stamps for comparison because actual values don't matter for comparison recvEvent.FirstTimestamp = expectedEvent.FirstTimestamp recvEvent.LastTimestamp = expectedEvent.LastTimestamp // Check that name has the right prefix. if n, en := recvEvent.Name, expectedEvent.Name; !strings.HasPrefix(n, en) { t.Errorf("%v - Name '%v' does not contain prefix '%v'", messagePrefix, n, en) } recvEvent.Name = expectedEvent.Name if e, a := expectedEvent, &recvEvent; !reflect.DeepEqual(e, a) { t.Errorf("%v - diff: %s", messagePrefix, diff.ObjectGoPrintDiff(e, a)) } recvEvent.FirstTimestamp = actualFirstTimestamp recvEvent.LastTimestamp = actualLastTimestamp return actualEvent, nil }
func TestProtobufRoundTrip(t *testing.T) { obj := &v1.Pod{} apitesting.FuzzerFor(t, v1.SchemeGroupVersion, rand.NewSource(benchmarkSeed)).Fuzz(obj) // InitContainers are turned into annotations by conversion. obj.Spec.InitContainers = nil obj.Status.InitContainerStatuses = nil data, err := obj.Marshal() if err != nil { t.Fatal(err) } out := &v1.Pod{} if err := out.Unmarshal(data); err != nil { t.Fatal(err) } if !api.Semantic.Equalities.DeepEqual(out, obj) { t.Logf("marshal\n%s", hex.Dump(data)) t.Fatalf("Unmarshal is unequal\n%s", diff.ObjectGoPrintDiff(out, obj)) } }
func (tc *patchTestCase) Run(t *testing.T) { t.Logf("Starting test %s", tc.name) namespace := tc.startingPod.Namespace name := tc.startingPod.Name codec := testapi.Default.Codec() admit := tc.admit if admit == nil { admit = func(updatedObject runtime.Object, currentObject runtime.Object) error { return nil } } testPatcher := &testPatcher{} testPatcher.t = t testPatcher.startingPod = tc.startingPod testPatcher.updatePod = tc.updatePod ctx := api.NewDefaultContext() ctx = api.WithNamespace(ctx, namespace) namer := &testNamer{namespace, name} copier := runtime.ObjectCopier(api.Scheme) resource := unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} versionedObj, err := api.Scheme.ConvertToVersion(&api.Pod{}, unversioned.GroupVersion{Version: "v1"}) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } for _, patchType := range []api.PatchType{api.JSONPatchType, api.MergePatchType, api.StrategicMergePatchType} { // TODO SUPPORT THIS! if patchType == api.JSONPatchType { continue } t.Logf("Working with patchType %v", patchType) originalObjJS, err := runtime.Encode(codec, tc.startingPod) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } changedJS, err := runtime.Encode(codec, tc.changedPod) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } patch := []byte{} switch patchType { case api.JSONPatchType: continue case api.StrategicMergePatchType: patch, err = strategicpatch.CreateStrategicMergePatch(originalObjJS, changedJS, versionedObj) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } case api.MergePatchType: patch, err = jsonpatch.CreateMergePatch(originalObjJS, changedJS) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } } resultObj, err := patchResource(ctx, admit, 1*time.Second, versionedObj, testPatcher, name, patchType, patch, namer, copier, resource, codec) if len(tc.expectedError) != 0 { if err == nil || err.Error() != tc.expectedError { t.Errorf("%s: expected error %v, but got %v", tc.name, tc.expectedError, err) return } } else { if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } } if tc.expectedPod == nil { if resultObj != nil { t.Errorf("%s: unexpected result: %v", tc.name, resultObj) } return } resultPod := resultObj.(*api.Pod) // roundtrip to get defaulting expectedJS, err := runtime.Encode(codec, tc.expectedPod) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } expectedObj, err := runtime.Decode(codec, expectedJS) if err != nil { t.Errorf("%s: unexpected error: %v", tc.name, err) return } reallyExpectedPod := expectedObj.(*api.Pod) if !reflect.DeepEqual(*reallyExpectedPod, *resultPod) { t.Errorf("%s mismatch: %v\n", tc.name, diff.ObjectGoPrintDiff(reallyExpectedPod, resultPod)) return } } }
func TestDecodeObjects(t *testing.T) { obj1 := &v1.Pod{ ObjectMeta: v1.ObjectMeta{ Name: "cool", }, Spec: v1.PodSpec{ Containers: []v1.Container{ { Name: "test", }, }, }, } obj1wire, err := obj1.Marshal() if err != nil { t.Fatal(err) } wire1, err := (&runtime.Unknown{ TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: "v1"}, Raw: obj1wire, }).Marshal() if err != nil { t.Fatal(err) } unk2 := &runtime.Unknown{ TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: "v1"}, } wire2 := make([]byte, len(wire1)*2) n, err := unk2.NestedMarshalTo(wire2, obj1, uint64(obj1.Size())) if err != nil { t.Fatal(err) } if n != len(wire1) || !bytes.Equal(wire1, wire2[:n]) { t.Fatalf("unexpected wire:\n%s", hex.Dump(wire2[:n])) } wire1 = append([]byte{0x6b, 0x38, 0x73, 0x00}, wire1...) testCases := []struct { obj runtime.Object data []byte errFn func(error) bool }{ { obj: obj1, data: wire1, }, } for i, test := range testCases { s := protobuf.NewSerializer(api.Scheme, api.Scheme, "application/protobuf") obj, err := runtime.Decode(s, test.data) switch { case err == nil && test.errFn != nil: t.Errorf("%d: failed: %v", i, err) continue case err != nil && test.errFn == nil: t.Errorf("%d: failed: %v", i, err) continue case err != nil: if !test.errFn(err) { t.Errorf("%d: failed: %v", i, err) } if obj != nil { t.Errorf("%d: should not have returned an object", i) } continue } if !api.Semantic.DeepEqual(obj, test.obj) { t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintDiff(test.obj, obj)) continue } } }
func TestObjectWatchFraming(t *testing.T) { f := apitesting.FuzzerFor(nil, api.SchemeGroupVersion, rand.NewSource(benchmarkSeed)) secret := &api.Secret{} f.Fuzz(secret) secret.Data["binary"] = []byte{0x00, 0x10, 0x30, 0x55, 0xff, 0x00} secret.Data["utf8"] = []byte("a string with \u0345 characters") secret.Data["long"] = bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x00}, 1000) converted, _ := api.Scheme.ConvertToVersion(secret, v1.SchemeGroupVersion) v1secret := converted.(*v1.Secret) for _, streamingMediaType := range api.Codecs.SupportedStreamingMediaTypes() { s, _ := api.Codecs.StreamingSerializerForMediaType(streamingMediaType, nil) framer := s.Framer embedded := s.Embedded.Serializer if embedded == nil { t.Errorf("no embedded serializer for %s", streamingMediaType) continue } innerDecode := api.Codecs.DecoderToVersion(embedded, api.SchemeGroupVersion) // write a single object through the framer and back out obj := &bytes.Buffer{} if err := s.Encode(v1secret, obj); err != nil { t.Fatal(err) } out := &bytes.Buffer{} w := framer.NewFrameWriter(out) if n, err := w.Write(obj.Bytes()); err != nil || n != len(obj.Bytes()) { t.Fatal(err) } sr := streaming.NewDecoder(framer.NewFrameReader(ioutil.NopCloser(out)), s) resultSecret := &v1.Secret{} res, _, err := sr.Decode(nil, resultSecret) if err != nil { t.Fatalf("%v:\n%s", err, hex.Dump(obj.Bytes())) } resultSecret.Kind = "Secret" resultSecret.APIVersion = "v1" if !api.Semantic.DeepEqual(v1secret, res) { t.Fatalf("objects did not match: %s", diff.ObjectGoPrintDiff(v1secret, res)) } // write a watch event through and back out obj = &bytes.Buffer{} if err := embedded.Encode(v1secret, obj); err != nil { t.Fatal(err) } event := &versioned.Event{Type: string(watch.Added)} event.Object.Raw = obj.Bytes() obj = &bytes.Buffer{} if err := s.Encode(event, obj); err != nil { t.Fatal(err) } out = &bytes.Buffer{} w = framer.NewFrameWriter(out) if n, err := w.Write(obj.Bytes()); err != nil || n != len(obj.Bytes()) { t.Fatal(err) } sr = streaming.NewDecoder(framer.NewFrameReader(ioutil.NopCloser(out)), s) outEvent := &versioned.Event{} res, _, err = sr.Decode(nil, outEvent) if err != nil || outEvent.Type != string(watch.Added) { t.Fatalf("%v: %#v", err, outEvent) } if outEvent.Object.Object == nil && outEvent.Object.Raw != nil { outEvent.Object.Object, err = runtime.Decode(innerDecode, outEvent.Object.Raw) if err != nil { t.Fatalf("%v:\n%s", err, hex.Dump(outEvent.Object.Raw)) } } if !api.Semantic.DeepEqual(secret, outEvent.Object.Object) { t.Fatalf("%s: did not match after frame decoding: %s", streamingMediaType, diff.ObjectGoPrintDiff(secret, outEvent.Object.Object)) } } }