예제 #1
0
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")
	}
}
예제 #2
0
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")
	}
}
예제 #3
0
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
	}
}
예제 #4
0
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)
		}
	}
}
예제 #5
0
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
}
예제 #6
0
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)
	}
}
예제 #7
0
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)
	}
}
예제 #8
0
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)
		}
	}
}
예제 #9
0
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
	}
}
예제 #10
0
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)
	}
}
예제 #11
0
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)
	}
}
예제 #12
0
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)
	}
}
예제 #14
0
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
}