func TestClone(t *testing.T) { m := proto.Clone(cloneTestMessage).(*pb.MyMessage) if !proto.Equal(m, cloneTestMessage) { t.Errorf("Clone(%v) = %v", cloneTestMessage, m) } // Verify it was a deep copy. *m.Inner.Port++ if proto.Equal(m, cloneTestMessage) { t.Error("Mutating clone changed the original") } // Byte fields and repeated fields should be copied. if &m.Pet[0] == &cloneTestMessage.Pet[0] { t.Error("Pet: repeated field not copied") } if &m.Others[0] == &cloneTestMessage.Others[0] { t.Error("Others: repeated field not copied") } if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] { t.Error("Others[0].Value: bytes field not copied") } if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] { t.Error("RepBytes: repeated field not copied") } if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] { t.Error("RepBytes[0]: bytes field not copied") } }
func TestClone(t *testing.T) { m := proto.Clone(cloneTestMessage).(*pb.MyMessage) if !proto.Equal(m, cloneTestMessage) { t.Errorf("Clone(%v) = %v", cloneTestMessage, m) } // Verify it was a deep copy. *m.Inner.Port++ if proto.Equal(m, cloneTestMessage) { t.Error("Mutating clone changed the original") } }
func TestLogging(t *testing.T) { l, err := NewLogFile("logging.log") if err != nil { t.Error(err) return } defer os.Remove("logging.log") for _, val := range testValues { err = l.Put(val) if err != nil { t.Fatal(err) } } err = l.Close() if err != nil { t.Fatal(err) } f, err := os.Open("logging.log") if err != nil { t.Fatal(err) } walker, err := NewReaderWalker(f) if err != nil { t.Error(err) return } i := 0 for { entries, err := walker.Next() if err == io.EOF { err = f.Close() if err != nil { t.Fatal(err) } break } else if err != nil { t.Error(err) return } if len(entries) != 1 { t.Error("> 1 entry in log tx") return } val, ok := entries[0].(proto.Message) if !ok { t.Fatal("val does not implement proto.Message") } if !proto.Equal(val, testValues[i]) { t.Error("proto message mismatch") } i += 1 } }
func TestMerge(t *testing.T) { for _, m := range mergeTests { got := proto.Clone(m.dst) proto.Merge(got, m.src) if !proto.Equal(got, m.want) { t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want) } } }
func fakeRunQuery(in *pb.Query, out *pb.QueryResult) error { expectedIn := &pb.Query{ App: proto.String("dev~fake-app"), Kind: proto.String("Gopher"), Compile: proto.Bool(true), } if !proto.Equal(in, expectedIn) { return fmt.Errorf("unsupported argument: got %v want %v", in, expectedIn) } *out = pb.QueryResult{ Result: []*pb.EntityProto{ { Key: &pb.Reference{ App: proto.String("s~test-app"), Path: path1, }, EntityGroup: path1, Property: []*pb.Property{ { Meaning: pb.Property_TEXT.Enum(), Name: proto.String("Name"), Value: &pb.PropertyValue{ StringValue: proto.String("George"), }, }, { Name: proto.String("Height"), Value: &pb.PropertyValue{ Int64Value: proto.Int64(32), }, }, }, }, { Key: &pb.Reference{ App: proto.String("s~test-app"), Path: path2, }, EntityGroup: path1, // ancestor is George Property: []*pb.Property{ { Meaning: pb.Property_TEXT.Enum(), Name: proto.String("Name"), Value: &pb.PropertyValue{ StringValue: proto.String("Rufus"), }, }, // No height for Rufus. }, }, }, MoreResults: proto.Bool(false), } return nil }
func TestMessageConstruction(t *testing.T) { var got *pb.MailMessage c := aetesting.FakeSingleContext(t, "mail", "Send", func(in *pb.MailMessage, out *basepb.VoidProto) error { got = in return nil }) msg := &Message{ Sender: "*****@*****.**", To: []string{"*****@*****.**"}, Body: "Hey, lunch time?", Attachments: []Attachment{ // Regression test for a prod bug. The address of a range variable was used when // constructing the outgoing proto, so multiple attachments used the same name. { Name: "att1.txt", Data: []byte("data1"), ContentID: "<att1>", }, { Name: "att2.txt", Data: []byte("data2"), }, }, } if err := Send(c, msg); err != nil { t.Fatalf("Send: %v", err) } want := &pb.MailMessage{ Sender: proto.String("*****@*****.**"), To: []string{"*****@*****.**"}, Subject: proto.String(""), TextBody: proto.String("Hey, lunch time?"), Attachment: []*pb.MailAttachment{ { FileName: proto.String("att1.txt"), Data: []byte("data1"), ContentID: proto.String("<att1>"), }, { FileName: proto.String("att2.txt"), Data: []byte("data2"), }, }, } if !proto.Equal(got, want) { t.Errorf("Bad proto for %+v\n got %v\nwant %v", msg, got, want) } }
func TestPut(t *testing.T) { index, err := Open("Doc") if err != nil { t.Fatalf("err from Open: %v", err) } c := aetesting.FakeSingleContext(t, "search", "IndexDocument", func(in *pb.IndexDocumentRequest, out *pb.IndexDocumentResponse) error { expectedIn := &pb.IndexDocumentRequest{ Params: &pb.IndexDocumentParams{ Document: []*pb.Document{ {Field: protoFields}, // Omit OrderId since we'll check it explicitly. }, IndexSpec: &pb.IndexSpec{ Name: proto.String("Doc"), }, }, } if len(in.Params.GetDocument()) < 1 { return fmt.Errorf("expected at least one Document, got %v", in) } got, want := in.Params.Document[0].GetOrderId(), int32(time.Since(orderIDEpoch).Seconds()) if d := got - want; -5 > d || d > 5 { return fmt.Errorf("got OrderId %d, want near %d", got, want) } in.Params.Document[0].OrderId = nil if !proto.Equal(in, expectedIn) { return fmt.Errorf("unsupported argument:\ngot %v\nwant %v", in, expectedIn) } *out = pb.IndexDocumentResponse{ Status: []*pb.RequestStatus{ {Code: pb.SearchServiceError_OK.Enum()}, }, DocId: []string{ "doc_id", }, } return nil }) id, err := index.Put(c, "", &searchDoc) if err != nil { t.Fatal(err) } if want := "doc_id"; id != want { t.Errorf("Got doc ID %q, want %q", id, want) } }
func TestStringEscaping(t *testing.T) { testCases := []struct { in *pb.Strings out string }{ { // Test data from C++ test (TextFormatTest.StringEscape). // Single divergence: we don't escape apostrophes. &pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces")}, "string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"\n", }, { // Test data from the same C++ test. &pb.Strings{StringField: proto.String("\350\260\267\346\255\214")}, "string_field: \"\\350\\260\\267\\346\\255\\214\"\n", }, { // Some UTF-8. &pb.Strings{StringField: proto.String("\x00\x01\xff\x81")}, `string_field: "\000\001\377\201"` + "\n", }, } for i, tc := range testCases { var buf bytes.Buffer if err := proto.MarshalText(&buf, tc.in); err != nil { t.Errorf("proto.MarsalText: %v", err) continue } s := buf.String() if s != tc.out { t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out) continue } // Check round-trip. pb := new(pb.Strings) if err := proto.UnmarshalText(s, pb); err != nil { t.Errorf("#%d: UnmarshalText: %v", i, err) continue } if !proto.Equal(pb, tc.in) { t.Errorf("#%d: Round-trip failed:\nstart: %v\n end: %v", i, tc.in, pb) } } }
func TestLogging(t *testing.T) { l, err := NewLogFile("logging.log") if err != nil { t.Error(err) return } defer l.Close() defer os.Remove("logging.log") for _, val := range testValues { err = l.Put(val) if err != nil { t.Error(err) return } } walker, err := NewFileWalker("logging.log") if err != nil { t.Error(err) return } i := 0 for { entries, err := walker.Next() if err == io.EOF { break } else if err != nil { t.Error(err) return } if len(entries) != 1 { t.Error("> 1 entry in log tx") return } val := entries[0] if !proto.Equal(val, testValues[i]) { t.Error("proto message mismatch") } i += 1 } }
func TestPut(t *testing.T) { index, err := Open("Doc") if err != nil { t.Fatalf("err from Open: %v", err) } c := aetesting.FakeSingleContext(t, "search", "IndexDocument", func(in *pb.IndexDocumentRequest, out *pb.IndexDocumentResponse) error { expectedIn := &pb.IndexDocumentRequest{ Params: &pb.IndexDocumentParams{ Document: []*pb.Document{ {Field: protoFields, OrderId: proto.Int32(42)}, }, IndexSpec: &pb.IndexSpec{ Name: proto.String("Doc"), }, }, } if !proto.Equal(in, expectedIn) { return fmt.Errorf("unsupported argument:\ngot %v\nwant %v", in, expectedIn) } *out = pb.IndexDocumentResponse{ Status: []*pb.RequestStatus{ {Code: pb.SearchServiceError_OK.Enum()}, }, DocId: []string{ "doc_id", }, } return nil }) id, err := index.Put(c, "", &FieldListWithMeta{ Meta: searchMeta, Fields: searchFields, }) if err != nil { t.Fatal(err) } if want := "doc_id"; id != want { t.Errorf("Got doc ID %q, want %q", id, want) } }
func TestLoginURL(t *testing.T) { expectedQuery := &pb.CreateLoginURLRequest{ DestinationUrl: proto.String("/destination"), } const expectedDest = "/redir/dest" c := aetesting.FakeSingleContext(t, "user", "CreateLoginURL", func(req *pb.CreateLoginURLRequest, res *pb.CreateLoginURLResponse) error { if !proto.Equal(req, expectedQuery) { return fmt.Errorf("got %v, want %v", req, expectedQuery) } res.LoginUrl = proto.String(expectedDest) return nil }) url, err := LoginURL(c, "/destination") if err != nil { t.Fatalf("LoginURL failed: %v", err) } if url != expectedDest { t.Errorf("got %v, want %v", url, expectedDest) } }
func TestCloneNil(t *testing.T) { var m *pb.MyMessage if c := proto.Clone(m); !proto.Equal(m, c) { t.Errorf("Clone(%v) = %v", m, c) } }
func checkProtosEqual(t *testing.T, expectedTrace *Trace, trace *Trace) { if !proto.Equal(expectedTrace, trace) { t.Fatalf("Protocol buffers not equal:\nExpected: %s\nActual: %s", expectedTrace, trace) } }
func (c *stubContext) Call(service, method string, in, out proto.Message, _ *internal.CallOptions) error { c.nCall++ if service != "datastore_v3" || method != "RunQuery" { return fmt.Errorf("stubContext: unsupported service %q or method %q", service, method) } expectedIn := &pb.Query{ App: proto.String("s~test-app"), Kind: proto.String("Gopher"), Compile: proto.Bool(true), } if !proto.Equal(in, expectedIn) { return fmt.Errorf("stubContext: unsupported in argument: got %v want %v", in, expectedIn) } x, ok := out.(*pb.QueryResult) if !ok { return fmt.Errorf("stubContext: unsupported out argument type: got %T want %T", out, x) } *x = pb.QueryResult{ Result: []*pb.EntityProto{ &pb.EntityProto{ Key: &pb.Reference{ App: proto.String("s~test-app"), Path: path1, }, EntityGroup: path1, Property: []*pb.Property{ &pb.Property{ Meaning: pb.Property_TEXT.Enum(), Name: proto.String("Name"), Value: &pb.PropertyValue{ StringValue: proto.String("George"), }, }, &pb.Property{ Name: proto.String("Height"), Value: &pb.PropertyValue{ Int64Value: proto.Int64(32), }, }, }, }, &pb.EntityProto{ Key: &pb.Reference{ App: proto.String("s~test-app"), Path: path2, }, EntityGroup: path1, // ancestor is George Property: []*pb.Property{ &pb.Property{ Meaning: pb.Property_TEXT.Enum(), Name: proto.String("Name"), Value: &pb.PropertyValue{ StringValue: proto.String("Rufus"), }, }, // No height for Rufus. }, }, }, MoreResults: proto.Bool(false), } return nil }