blob: 39abc77383d999345d2071c309a7aefe8c63a2a4 [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
3// Copyright 2010 Google Inc. All rights reserved.
4// http://code.google.com/p/goprotobuf/
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32// We need to compile the .pb.gos, which import this package, so
33// to run the test we must make install here and then make in the
34// testdata directory.
35// gotest: make install && cd testdata && make nuke && make
36
37package proto_test
38
39import (
40 "bytes"
41 "fmt"
42 "testing"
43
44 . "goprotobuf.googlecode.com/hg/proto"
45 . "./testdata/_obj/test_proto"
46)
47
48var globalO *Buffer
49
50func old() *Buffer {
51 if globalO == nil {
52 globalO = NewBuffer(nil)
53 }
54 globalO.Reset()
55 return globalO
56}
57
58func equalbytes(b1, b2 []byte, t *testing.T) {
59 if len(b1) != len(b2) {
60 t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2))
61 return
62 }
63 for i := 0; i < len(b1); i++ {
64 if b1[i] != b2[i] {
65 t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2)
66 }
67 }
68}
69
70func initGoTestField() *GoTestField {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070071 f := new(GoTestField)
Rob Pikeaaa3a622010-03-20 22:32:34 -070072 f.Label = String("label")
73 f.Type = String("type")
74 return f
75}
76
77// These are all structurally equivalent but the tag numbers differ.
78// (It's remarkable that required, optional, and repeated all have
79// 8 letters.)
80func initGoTest_RequiredGroup() *GoTest_RequiredGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070081 return &GoTest_RequiredGroup{
82 RequiredField: String("required"),
83 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070084}
85
86func initGoTest_OptionalGroup() *GoTest_OptionalGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070087 return &GoTest_OptionalGroup{
88 RequiredField: String("optional"),
89 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070090}
91
92func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070093 return &GoTest_RepeatedGroup{
94 RequiredField: String("repeated"),
95 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070096}
97
98func initGoTest(setdefaults bool) *GoTest {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070099 pb := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700100 if setdefaults {
101 pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted)
102 pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted)
103 pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted)
104 pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted)
105 pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted)
106 pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted)
107 pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted)
108 pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted)
109 pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted)
110 pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted)
111 pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted
112 pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted)
113 pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
114 }
115
116 pb.Kind = Int32(GoTest_TIME)
117 pb.RequiredField = initGoTestField()
118 pb.F_BoolRequired = Bool(true)
119 pb.F_Int32Required = Int32(3)
120 pb.F_Int64Required = Int64(6)
121 pb.F_Fixed32Required = Uint32(32)
122 pb.F_Fixed64Required = Uint64(64)
123 pb.F_Uint32Required = Uint32(3232)
124 pb.F_Uint64Required = Uint64(6464)
125 pb.F_FloatRequired = Float32(3232)
126 pb.F_DoubleRequired = Float64(6464)
127 pb.F_StringRequired = String("string")
128 pb.F_BytesRequired = []byte("bytes")
129 pb.F_Sint32Required = Int32(-32)
130 pb.F_Sint64Required = Int64(-64)
131 pb.Requiredgroup = initGoTest_RequiredGroup()
132
133 return pb
134}
135
136func fail(msg string, b *bytes.Buffer, s string, t *testing.T) {
137 data := b.Bytes()
138 ld := len(data)
139 ls := len(s) / 2
140
141 fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls)
142
143 // find the interesting spot - n
144 n := ls
145 if ld < ls {
146 n = ld
147 }
148 j := 0
149 for i := 0; i < n; i++ {
150 bs := hex(s[j])*16 + hex(s[j+1])
151 j += 2
152 if data[i] == bs {
153 continue
154 }
155 n = i
156 break
157 }
158 l := n - 10
159 if l < 0 {
160 l = 0
161 }
162 h := n + 10
163
164 // find the interesting spot - n
165 fmt.Printf("is[%d]:", l)
166 for i := l; i < h; i++ {
167 if i >= ld {
168 fmt.Printf(" --")
169 continue
170 }
171 fmt.Printf(" %.2x", data[i])
172 }
173 fmt.Printf("\n")
174
175 fmt.Printf("sb[%d]:", l)
176 for i := l; i < h; i++ {
177 if i >= ls {
178 fmt.Printf(" --")
179 continue
180 }
181 bs := hex(s[j])*16 + hex(s[j+1])
182 j += 2
183 fmt.Printf(" %.2x", bs)
184 }
185 fmt.Printf("\n")
186
187 t.Fail()
188
189
190 // t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
191 // Print the output in a partially-decoded format; can
192 // be helpful when updating the test. It produces the output
193 // that is pasted, with minor edits, into the argument to verify().
194 // data := b.Bytes()
195 // nesting := 0
196 // for b.Len() > 0 {
197 // start := len(data) - b.Len()
198 // var u uint64
199 // u, err := DecodeVarint(b)
200 // if err != nil {
201 // fmt.Printf("decode error on varint:", err)
202 // return
203 // }
204 // wire := u & 0x7
205 // tag := u >> 3
206 // switch wire {
207 // case WireVarint:
208 // v, err := DecodeVarint(b)
209 // if err != nil {
210 // fmt.Printf("decode error on varint:", err)
211 // return
212 // }
213 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
214 // data[start:len(data)-b.Len()], tag, wire, v)
215 // case WireFixed32:
216 // v, err := DecodeFixed32(b)
217 // if err != nil {
218 // fmt.Printf("decode error on fixed32:", err)
219 // return
220 // }
221 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
222 // data[start:len(data)-b.Len()], tag, wire, v)
223 // case WireFixed64:
224 // v, err := DecodeFixed64(b)
225 // if err != nil {
226 // fmt.Printf("decode error on fixed64:", err)
227 // return
228 // }
229 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
230 // data[start:len(data)-b.Len()], tag, wire, v)
231 // case WireBytes:
232 // nb, err := DecodeVarint(b)
233 // if err != nil {
234 // fmt.Printf("decode error on bytes:", err)
235 // return
236 // }
237 // after_tag := len(data) - b.Len()
238 // str := make([]byte, nb)
239 // _, err = b.Read(str)
240 // if err != nil {
241 // fmt.Printf("decode error on bytes:", err)
242 // return
243 // }
244 // fmt.Printf("\t\t\"%x\" \"%x\" // field %d, encoding %d (FIELD)\n",
245 // data[start:after_tag], str, tag, wire)
246 // case WireStartGroup:
247 // nesting++
248 // fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
249 // data[start:len(data)-b.Len()], tag, nesting)
250 // case WireEndGroup:
251 // fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
252 // data[start:len(data)-b.Len()], tag, nesting)
253 // nesting--
254 // default:
255 // fmt.Printf("unrecognized wire type %d\n", wire)
256 // return
257 // }
258 // }
259}
260
261func hex(c uint8) uint8 {
262 if '0' <= c && c <= '9' {
263 return c - '0'
264 }
265 if 'a' <= c && c <= 'f' {
266 return 10 + c - 'a'
267 }
268 if 'A' <= c && c <= 'F' {
269 return 10 + c - 'A'
270 }
271 return 0
272}
273
274func equal(b []byte, s string, t *testing.T) bool {
275 if 2*len(b) != len(s) {
276 // fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t)
277 fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s))
278 return false
279 }
280 for i, j := 0, 0; i < len(b); i, j = i+1, j+2 {
281 x := hex(s[j])*16 + hex(s[j+1])
282 if b[i] != x {
283 // fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t)
284 fmt.Printf("bad byte[%d]:%x %x", i, b[i], x)
285 return false
286 }
287 }
288 return true
289}
290
291func overify(t *testing.T, pb *GoTest, expected string) {
292 o := old()
293 err := o.Marshal(pb)
294 if err != nil {
295 fmt.Printf("overify marshal-1 err = %v", err)
296 o.DebugPrint("", o.Bytes())
297 t.Fatalf("expected = %s", expected)
298 }
299 if !equal(o.Bytes(), expected, t) {
300 o.DebugPrint("overify neq 1", o.Bytes())
301 t.Fatalf("expected = %s", expected)
302 }
303
304 // Now test Unmarshal by recreating the original buffer.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700305 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700306 err = o.Unmarshal(pbd)
307 if err != nil {
308 t.Fatalf("overify unmarshal err = %v", err)
309 o.DebugPrint("", o.Bytes())
310 t.Fatalf("string = %s", expected)
311 }
312 o.Reset()
313 err = o.Marshal(pbd)
314 if err != nil {
315 t.Errorf("overify marshal-2 err = %v", err)
316 o.DebugPrint("", o.Bytes())
317 t.Fatalf("string = %s", expected)
318 }
319 if !equal(o.Bytes(), expected, t) {
320 o.DebugPrint("overify neq 2", o.Bytes())
321 t.Fatalf("string = %s", expected)
322 }
323}
324
325// Simple tests for numeric encode/decode primitives (varint, etc.)
326func TestNumericPrimitives(t *testing.T) {
327 for i := uint64(0); i < 1e6; i += 111 {
328 o := old()
329 if o.EncodeVarint(i) != nil {
330 t.Error("EncodeVarint")
331 break
332 }
333 x, e := o.DecodeVarint()
334 if e != nil {
335 t.Fatal("DecodeVarint")
336 }
337 if x != i {
338 t.Fatal("varint decode fail:", i, x)
339 }
340
341 o = old()
342 if o.EncodeFixed32(i) != nil {
343 t.Fatal("encFixed32")
344 }
345 x, e = o.DecodeFixed32()
346 if e != nil {
347 t.Fatal("decFixed32")
348 }
349 if x != i {
350 t.Fatal("fixed32 decode fail:", i, x)
351 }
352
353 o = old()
354 if o.EncodeFixed64(i*1234567) != nil {
355 t.Error("encFixed64")
356 break
357 }
358 x, e = o.DecodeFixed64()
359 if e != nil {
360 t.Error("decFixed64")
361 break
362 }
363 if x != i*1234567 {
364 t.Error("fixed64 decode fail:", i*1234567, x)
365 break
366 }
367
368 o = old()
369 i32 := int32(i - 12345)
370 if o.EncodeZigzag32(uint64(i32)) != nil {
371 t.Fatal("EncodeZigzag32")
372 }
373 x, e = o.DecodeZigzag32()
374 if e != nil {
375 t.Fatal("DecodeZigzag32")
376 }
377 if x != uint64(uint32(i32)) {
378 t.Fatal("zigzag32 decode fail:", i32, x)
379 }
380
381 o = old()
382 i64 := int64(i - 12345)
383 if o.EncodeZigzag64(uint64(i64)) != nil {
384 t.Fatal("EncodeZigzag64")
385 }
386 x, e = o.DecodeZigzag64()
387 if e != nil {
388 t.Fatal("DecodeZigzag64")
389 }
390 if x != uint64(i64) {
391 t.Fatal("zigzag64 decode fail:", i64, x)
392 }
393 }
394}
395
396// Simple tests for bytes
397func TestBytesPrimitives(t *testing.T) {
398 o := old()
399 bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'}
400 if o.EncodeRawBytes(bytes) != nil {
401 t.Error("EncodeRawBytes")
402 }
403 decb, e := o.DecodeRawBytes(false)
404 if e != nil {
405 t.Error("DecodeRawBytes")
406 }
407 equalbytes(bytes, decb, t)
408}
409
410// Simple tests for strings
411func TestStringPrimitives(t *testing.T) {
412 o := old()
413 s := "now is the time"
414 if o.EncodeStringBytes(s) != nil {
415 t.Error("enc_string")
416 }
417 decs, e := o.DecodeStringBytes()
418 if e != nil {
419 t.Error("dec_string")
420 }
421 if s != decs {
422 t.Error("string encode/decode fail:", s, decs)
423 }
424}
425
426// Do we catch the "required bit not set" case?
427func TestRequiredBit(t *testing.T) {
428 o := old()
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700429 pb := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700430 if o.Marshal(pb) != ErrRequiredNotSet {
431 t.Errorf("did not catch missing required fields")
432 }
433}
434
435// Check that all fields are nil.
436// Clearly silly, and a residue from a more interesting test with an earlier,
437// different initialization property, but it once caught a compiler bug so
438// it lives.
439func checkInitialized(pb *GoTest, t *testing.T) {
440 if pb.F_BoolDefaulted != nil {
441 t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted)
442 }
443 if pb.F_Int32Defaulted != nil {
444 t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted)
445 }
446 if pb.F_Int64Defaulted != nil {
447 t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted)
448 }
449 if pb.F_Fixed32Defaulted != nil {
450 t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted)
451 }
452 if pb.F_Fixed64Defaulted != nil {
453 t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted)
454 }
455 if pb.F_Uint32Defaulted != nil {
456 t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted)
457 }
458 if pb.F_Uint64Defaulted != nil {
459 t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted)
460 }
461 if pb.F_FloatDefaulted != nil {
462 t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted)
463 }
464 if pb.F_DoubleDefaulted != nil {
465 t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted)
466 }
467 if pb.F_StringDefaulted != nil {
468 t.Error("New or Reset did not set string:", *pb.F_StringDefaulted)
469 }
470 if pb.F_BytesDefaulted != nil {
471 t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted))
472 }
473 if pb.F_Sint32Defaulted != nil {
474 t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted)
475 }
476 if pb.F_Sint64Defaulted != nil {
477 t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted)
478 }
479}
480
481// Does Reset() reset?
482func TestReset(t *testing.T) {
483 pb := initGoTest(true)
484 // muck with some values
485 pb.F_BoolDefaulted = Bool(false)
486 pb.F_Int32Defaulted = Int32(237)
487 pb.F_Int64Defaulted = Int64(12346)
488 pb.F_Fixed32Defaulted = Uint32(32000)
489 pb.F_Fixed64Defaulted = Uint64(666)
490 pb.F_Uint32Defaulted = Uint32(323232)
491 pb.F_Uint64Defaulted = nil
492 pb.F_FloatDefaulted = nil
493 pb.F_DoubleDefaulted = Float64(0)
494 pb.F_StringDefaulted = String("gotcha")
495 pb.F_BytesDefaulted = []byte("asdfasdf")
496 pb.F_Sint32Defaulted = Int32(123)
497 pb.F_Sint64Defaulted = Int64(789)
498 pb.Reset()
499 checkInitialized(pb, t)
500}
501
502// All required fields set, no defaults provided.
503func TestEncodeDecode1(t *testing.T) {
504 pb := initGoTest(false)
505 overify(t, pb,
506 "0807"+ // field 1, encoding 0, value 7
507 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
508 "5001"+ // field 10, encoding 0, value 1
509 "5803"+ // field 11, encoding 0, value 3
510 "6006"+ // field 12, encoding 0, value 6
511 "6d20000000"+ // field 13, encoding 5, value 0x20
512 "714000000000000000"+ // field 14, encoding 1, value 0x40
513 "78a019"+ // field 15, encoding 0, value 0xca0 = 3232
514 "8001c032"+ // field 16, encoding 0, value 0x1940 = 6464
515 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
516 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
517 "9a0106"+"737472696e67"+ // field 19, encoding 2, string "string"
518 "aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes"
519 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
520 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
521 "b304"+ // field 70, encoding 3, start group
522 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
523 "b404") // field 70, encoding 4, end group
524}
525
526// All required fields set, defaults provided.
527func TestEncodeDecode2(t *testing.T) {
528 pb := initGoTest(true)
529 overify(t, pb,
530 "0807"+ // field 1, encoding 0, value 7
531 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
532 "5001"+ // field 10, encoding 0, value 1
533 "5803"+ // field 11, encoding 0, value 3
534 "6006"+ // field 12, encoding 0, value 6
535 "6d20000000"+ // field 13, encoding 5, value 32
536 "714000000000000000"+ // field 14, encoding 1, value 64
537 "78a019"+ // field 15, encoding 0, value 3232
538 "8001c032"+ // field 16, encoding 0, value 6464
539 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
540 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
541 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
542 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
543 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
544 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
545 "c00201"+ // field 40, encoding 0, value 1
546 "c80220"+ // field 41, encoding 0, value 32
547 "d00240"+ // field 42, encoding 0, value 64
548 "dd0240010000"+ // field 43, encoding 5, value 320
549 "e1028002000000000000"+ // field 44, encoding 1, value 640
550 "e8028019"+ // field 45, encoding 0, value 3200
551 "f0028032"+ // field 46, encoding 0, value 6400
552 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
553 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
554 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
555 "90193f"+ // field 402, encoding 0, value 63
556 "98197f"+ // field 403, encoding 0, value 127
557 "b304"+ // start group field 70 level 1
558 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
559 "b404") // end group field 70 level 1
560
561}
562
563// All default fields set to their default value by hand
564func TestEncodeDecode3(t *testing.T) {
565 pb := initGoTest(false)
566 pb.F_BoolDefaulted = Bool(true)
567 pb.F_Int32Defaulted = Int32(32)
568 pb.F_Int64Defaulted = Int64(64)
569 pb.F_Fixed32Defaulted = Uint32(320)
570 pb.F_Fixed64Defaulted = Uint64(640)
571 pb.F_Uint32Defaulted = Uint32(3200)
572 pb.F_Uint64Defaulted = Uint64(6400)
573 pb.F_FloatDefaulted = Float32(314159)
574 pb.F_DoubleDefaulted = Float64(271828)
575 pb.F_StringDefaulted = String("hello, \"world!\"\n")
576 pb.F_BytesDefaulted = []byte("Bignose")
577 pb.F_Sint32Defaulted = Int32(-32)
578 pb.F_Sint64Defaulted = Int64(-64)
579
580 overify(t, pb,
581 "0807"+ // field 1, encoding 0, value 7
582 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
583 "5001"+ // field 10, encoding 0, value 1
584 "5803"+ // field 11, encoding 0, value 3
585 "6006"+ // field 12, encoding 0, value 6
586 "6d20000000"+ // field 13, encoding 5, value 32
587 "714000000000000000"+ // field 14, encoding 1, value 64
588 "78a019"+ // field 15, encoding 0, value 3232
589 "8001c032"+ // field 16, encoding 0, value 6464
590 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
591 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
592 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
593 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
594 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
595 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
596 "c00201"+ // field 40, encoding 0, value 1
597 "c80220"+ // field 41, encoding 0, value 32
598 "d00240"+ // field 42, encoding 0, value 64
599 "dd0240010000"+ // field 43, encoding 5, value 320
600 "e1028002000000000000"+ // field 44, encoding 1, value 640
601 "e8028019"+ // field 45, encoding 0, value 3200
602 "f0028032"+ // field 46, encoding 0, value 6400
603 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
604 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
605 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
606 "90193f"+ // field 402, encoding 0, value 63
607 "98197f"+ // field 403, encoding 0, value 127
608 "b304"+ // start group field 70 level 1
609 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
610 "b404") // end group field 70 level 1
611
612}
613
614// All required fields set, defaults provided, all non-defaulted optional fields have values.
615func TestEncodeDecode4(t *testing.T) {
616 pb := initGoTest(true)
617 pb.Table = String("hello")
618 pb.Param = Int32(7)
619 pb.OptionalField = initGoTestField()
620 pb.F_BoolOptional = Bool(true)
621 pb.F_Int32Optional = Int32(32)
622 pb.F_Int64Optional = Int64(64)
623 pb.F_Fixed32Optional = Uint32(3232)
624 pb.F_Fixed64Optional = Uint64(6464)
625 pb.F_Uint32Optional = Uint32(323232)
626 pb.F_Uint64Optional = Uint64(646464)
627 pb.F_FloatOptional = Float32(32.)
628 pb.F_DoubleOptional = Float64(64.)
629 pb.F_StringOptional = String("hello")
630 pb.F_BytesOptional = []byte("Bignose")
631 pb.F_Sint32Optional = Int32(-32)
632 pb.F_Sint64Optional = Int64(-64)
633 pb.Optionalgroup = initGoTest_OptionalGroup()
634
635 overify(t, pb,
636 "0807"+ // field 1, encoding 0, value 7
637 "1205"+"68656c6c6f"+ // field 2, encoding 2, string "hello"
638 "1807"+ // field 3, encoding 0, value 7
639 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
640 "320d"+"0a056c6162656c120474797065"+ // field 6, encoding 2 (GoTestField)
641 "5001"+ // field 10, encoding 0, value 1
642 "5803"+ // field 11, encoding 0, value 3
643 "6006"+ // field 12, encoding 0, value 6
644 "6d20000000"+ // field 13, encoding 5, value 32
645 "714000000000000000"+ // field 14, encoding 1, value 64
646 "78a019"+ // field 15, encoding 0, value 3232
647 "8001c032"+ // field 16, encoding 0, value 6464
648 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
649 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
650 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
651 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
652 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
653 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
654 "f00101"+ // field 30, encoding 0, value 1
655 "f80120"+ // field 31, encoding 0, value 32
656 "800240"+ // field 32, encoding 0, value 64
657 "8d02a00c0000"+ // field 33, encoding 5, value 3232
658 "91024019000000000000"+ // field 34, encoding 1, value 6464
659 "9802a0dd13"+ // field 35, encoding 0, value 323232
660 "a002c0ba27"+ // field 36, encoding 0, value 646464
661 "ad0200000042"+ // field 37, encoding 5, value 32.0
662 "b1020000000000005040"+ // field 38, encoding 1, value 64.0
663 "ba0205"+"68656c6c6f"+ // field 39, encoding 2, string "hello"
664 "ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose"
665 "f0123f"+ // field 302, encoding 0, value 63
666 "f8127f"+ // field 303, encoding 0, value 127
667 "c00201"+ // field 40, encoding 0, value 1
668 "c80220"+ // field 41, encoding 0, value 32
669 "d00240"+ // field 42, encoding 0, value 64
670 "dd0240010000"+ // field 43, encoding 5, value 320
671 "e1028002000000000000"+ // field 44, encoding 1, value 640
672 "e8028019"+ // field 45, encoding 0, value 3200
673 "f0028032"+ // field 46, encoding 0, value 6400
674 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
675 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
676 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
677 "90193f"+ // field 402, encoding 0, value 63
678 "98197f"+ // field 403, encoding 0, value 127
679 "b304"+ // start group field 70 level 1
680 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
681 "b404"+ // end group field 70 level 1
682 "d305"+ // start group field 90 level 1
683 "da0508"+"6f7074696f6e616c"+ // field 91, encoding 2, string "optional"
684 "d405") // end group field 90 level 1
685
686}
687
688// All required fields set, defaults provided, all repeated fields given two values.
689func TestEncodeDecode5(t *testing.T) {
690 pb := initGoTest(true)
691 pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()}
692 pb.F_BoolRepeated = []bool{false, true}
693 pb.F_Int32Repeated = []int32{32, 33}
694 pb.F_Int64Repeated = []int64{64, 65}
695 pb.F_Fixed32Repeated = []uint32{3232, 3333}
696 pb.F_Fixed64Repeated = []uint64{6464, 6565}
697 pb.F_Uint32Repeated = []uint32{323232, 333333}
698 pb.F_Uint64Repeated = []uint64{646464, 656565}
699 pb.F_FloatRepeated = []float32{32., 33.}
700 pb.F_DoubleRepeated = []float64{64., 65.}
701 pb.F_StringRepeated = []string{"hello", "sailor"}
702 pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")}
703 pb.F_Sint32Repeated = []int32{32, -32}
704 pb.F_Sint64Repeated = []int64{64, -64}
705 pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()}
706
707 overify(t, pb,
708 "0807"+ // field 1, encoding 0, value 7
709 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
710 "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
711 "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
712 "5001"+ // field 10, encoding 0, value 1
713 "5803"+ // field 11, encoding 0, value 3
714 "6006"+ // field 12, encoding 0, value 6
715 "6d20000000"+ // field 13, encoding 5, value 32
716 "714000000000000000"+ // field 14, encoding 1, value 64
717 "78a019"+ // field 15, encoding 0, value 3232
718 "8001c032"+ // field 16, encoding 0, value 6464
719 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
720 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
721 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
722 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
723 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
724 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
725 "a00100"+ // field 20, encoding 0, value 0
726 "a00101"+ // field 20, encoding 0, value 1
727 "a80120"+ // field 21, encoding 0, value 32
728 "a80121"+ // field 21, encoding 0, value 33
729 "b00140"+ // field 22, encoding 0, value 64
730 "b00141"+ // field 22, encoding 0, value 65
731 "bd01a00c0000"+ // field 23, encoding 5, value 3232
732 "bd01050d0000"+ // field 23, encoding 5, value 3333
733 "c1014019000000000000"+ // field 24, encoding 1, value 6464
734 "c101a519000000000000"+ // field 24, encoding 1, value 6565
735 "c801a0dd13"+ // field 25, encoding 0, value 323232
736 "c80195ac14"+ // field 25, encoding 0, value 333333
737 "d001c0ba27"+ // field 26, encoding 0, value 646464
738 "d001b58928"+ // field 26, encoding 0, value 656565
739 "dd0100000042"+ // field 27, encoding 5, value 32.0
740 "dd0100000442"+ // field 27, encoding 5, value 33.0
741 "e1010000000000005040"+ // field 28, encoding 1, value 64.0
742 "e1010000000000405040"+ // field 28, encoding 1, value 65.0
743 "ea0105"+"68656c6c6f"+ // field 29, encoding 2, string "hello"
744 "ea0106"+"7361696c6f72"+ // field 29, encoding 2, string "sailor"
745 "ca0c03"+"626967"+ // field 201, encoding 2, string "big"
746 "ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose"
747 "d00c40"+ // field 202, encoding 0, value 64
748 "d00c3f"+ // field 202, encoding 0, value 63
749 "d80c8001"+ // field 203, encoding 0, value 128
750 "d80c7f"+ // field 203, encoding 0, value 127
751 "c00201"+ // field 40, encoding 0, value 1
752 "c80220"+ // field 41, encoding 0, value 32
753 "d00240"+ // field 42, encoding 0, value 64
754 "dd0240010000"+ // field 43, encoding 5, value 320
755 "e1028002000000000000"+ // field 44, encoding 1, value 640
756 "e8028019"+ // field 45, encoding 0, value 3200
757 "f0028032"+ // field 46, encoding 0, value 6400
758 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
759 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
760 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
761 "90193f"+ // field 402, encoding 0, value 63
762 "98197f"+ // field 403, encoding 0, value 127
763 "b304"+ // start group field 70 level 1
764 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
765 "b404"+ // end group field 70 level 1
766 "8305"+ // start group field 80 level 1
767 "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
768 "8405"+ // end group field 80 level 1
769 "8305"+ // start group field 80 level 1
770 "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
771 "8405") // end group field 80 level 1
772
773}
774
775// All required fields set, defaults provided, all repeated fields given two values.
776func TestSkippingUnrecognizedFields(t *testing.T) {
777 o := old()
778 pb := initGoTestField()
779
780 // Marshal it normally.
781 o.Marshal(pb)
782
783 // Now new a GoSkipTest record.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700784 skip := &GoSkipTest{
785 SkipInt32: Int32(32),
786 SkipFixed32: Uint32(3232),
787 SkipFixed64: Uint64(6464),
788 SkipString: String("skipper"),
789 Skipgroup: &GoSkipTest_SkipGroup{
790 GroupInt32: Int32(75),
791 GroupString: String("wxyz"),
792 },
793 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700794
795 // Marshal it into same buffer.
796 o.Marshal(skip)
797
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700798 pbd := new(GoTestField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700799 o.Unmarshal(pbd)
800
801 // The __unrecognized field should be a marshaling of GoSkipTest
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700802 skipd := new(GoSkipTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700803
804 o.SetBuf(pbd.XXX_unrecognized)
805 o.Unmarshal(skipd)
806
807 if *skipd.SkipInt32 != *skip.SkipInt32 {
808 t.Error("skip int32", skipd.SkipInt32)
809 }
810 if *skipd.SkipFixed32 != *skip.SkipFixed32 {
811 t.Error("skip fixed32", skipd.SkipFixed32)
812 }
813 if *skipd.SkipFixed64 != *skip.SkipFixed64 {
814 t.Error("skip fixed64", skipd.SkipFixed64)
815 }
816 if *skipd.SkipString != *skip.SkipString {
817 t.Error("skip string", *skipd.SkipString)
818 }
819 if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 {
820 t.Error("skip group int32", skipd.Skipgroup.GroupInt32)
821 }
822 if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString {
823 t.Error("skip group string", *skipd.Skipgroup.GroupString)
824 }
825}
826
827// Check that we can grow an array (repeated field) to have many elements.
828// This test doesn't depend only on our encoding; for variety, it makes sure
829// we create, encode, and decode the correct contents explicitly. It's therefore
830// a bit messier.
831// This test also uses (and hence tests) the Marshal/Unmarshal functions
832// instead of the methods.
833func TestBigRepeated(t *testing.T) {
834 pb := initGoTest(true)
835
836 // Create the arrays
837 const N = 50 // Internally the library starts much smaller.
838 pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N)
839 pb.F_Sint64Repeated = make([]int64, N)
840 pb.F_Sint32Repeated = make([]int32, N)
841 pb.F_BytesRepeated = make([][]byte, N)
842 pb.F_StringRepeated = make([]string, N)
843 pb.F_DoubleRepeated = make([]float64, N)
844 pb.F_FloatRepeated = make([]float32, N)
845 pb.F_Uint64Repeated = make([]uint64, N)
846 pb.F_Uint32Repeated = make([]uint32, N)
847 pb.F_Fixed64Repeated = make([]uint64, N)
848 pb.F_Fixed32Repeated = make([]uint32, N)
849 pb.F_Int64Repeated = make([]int64, N)
850 pb.F_Int32Repeated = make([]int32, N)
851 pb.F_BoolRepeated = make([]bool, N)
852 pb.RepeatedField = make([]*GoTestField, N)
853
854 // Fill in the arrays with checkable values.
855 igtf := initGoTestField()
856 igtrg := initGoTest_RepeatedGroup()
857 for i := 0; i < N; i++ {
858 pb.Repeatedgroup[i] = igtrg
859 pb.F_Sint64Repeated[i] = int64(i)
860 pb.F_Sint32Repeated[i] = int32(i)
861 s := fmt.Sprint(i)
862 pb.F_BytesRepeated[i] = []byte(s)
863 pb.F_StringRepeated[i] = s
864 pb.F_DoubleRepeated[i] = float64(i)
865 pb.F_FloatRepeated[i] = float32(i)
866 pb.F_Uint64Repeated[i] = uint64(i)
867 pb.F_Uint32Repeated[i] = uint32(i)
868 pb.F_Fixed64Repeated[i] = uint64(i)
869 pb.F_Fixed32Repeated[i] = uint32(i)
870 pb.F_Int64Repeated[i] = int64(i)
871 pb.F_Int32Repeated[i] = int32(i)
872 pb.F_BoolRepeated[i] = i%2 == 0
873 pb.RepeatedField[i] = igtf
874 }
875
876 // Marshal.
877 buf, _ := Marshal(pb)
878
879 // Now test Unmarshal by recreating the original buffer.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700880 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700881 Unmarshal(buf, pbd)
882
883 // Check the checkable values
884 for i := uint64(0); i < N; i++ {
885 if pbd.Repeatedgroup[i] == nil { // TODO: more checking?
886 t.Error("pbd.Repeatedgroup bad")
887 }
888 var x uint64
889 x = uint64(pbd.F_Sint64Repeated[i])
890 if x != i {
891 t.Error("pbd.F_Sint64Repeated bad", x, i)
892 }
893 x = uint64(pbd.F_Sint32Repeated[i])
894 if x != i {
895 t.Error("pbd.F_Sint32Repeated bad", x, i)
896 }
897 s := fmt.Sprint(i)
898 equalbytes(pbd.F_BytesRepeated[i], []byte(s), t)
899 if pbd.F_StringRepeated[i] != s {
900 t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i)
901 }
902 x = uint64(pbd.F_DoubleRepeated[i])
903 if x != i {
904 t.Error("pbd.F_DoubleRepeated bad", x, i)
905 }
906 x = uint64(pbd.F_FloatRepeated[i])
907 if x != i {
908 t.Error("pbd.F_FloatRepeated bad", x, i)
909 }
910 x = pbd.F_Uint64Repeated[i]
911 if x != i {
912 t.Error("pbd.F_Uint64Repeated bad", x, i)
913 }
914 x = uint64(pbd.F_Uint32Repeated[i])
915 if x != i {
916 t.Error("pbd.F_Uint32Repeated bad", x, i)
917 }
918 x = pbd.F_Fixed64Repeated[i]
919 if x != i {
920 t.Error("pbd.F_Fixed64Repeated bad", x, i)
921 }
922 x = uint64(pbd.F_Fixed32Repeated[i])
923 if x != i {
924 t.Error("pbd.F_Fixed32Repeated bad", x, i)
925 }
926 x = uint64(pbd.F_Int64Repeated[i])
927 if x != i {
928 t.Error("pbd.F_Int64Repeated bad", x, i)
929 }
930 x = uint64(pbd.F_Int32Repeated[i])
931 if x != i {
932 t.Error("pbd.F_Int32Repeated bad", x, i)
933 }
934 if pbd.F_BoolRepeated[i] != (i%2 == 0) {
935 t.Error("pbd.F_BoolRepeated bad", x, i)
936 }
937 if pbd.RepeatedField[i] == nil { // TODO: more checking?
938 t.Error("pbd.RepeatedField bad")
939 }
940 }
941}
942
943// Verify we give a useful message when decoding to the wrong structure type.
944func TestTypeMismatch(t *testing.T) {
945 pb1 := initGoTest(true)
946
947 // Marshal
948 o := old()
949 o.Marshal(pb1)
950
951 // Now Unmarshal it to the wrong type.
952 pb2 := initGoTestField()
953 err := o.Unmarshal(pb2)
954 switch err {
955 case ErrWrongType:
956 // fine
957 case nil:
958 t.Error("expected wrong type error, got no error")
959 default:
960 t.Error("expected wrong type error, got", err)
961 }
962}
963
964func TestProto1RepeatedGroup(t *testing.T) {
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700965 pb := &MessageList{
966 Message: []*MessageList_Message{
967 &MessageList_Message{
968 Name: String("blah"),
969 Count: Int32(7),
970 },
971 // NOTE: pb.Message[1] is a nil
972 nil,
973 },
974 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700975
976 o := old()
977 if err := o.Marshal(pb); err != ErrRepeatedHasNil {
978 t.Fatalf("unexpected or no error when marshaling: %v", err)
979 }
980}
981
Rob Pike9caa5b92010-05-11 16:04:57 -0700982
Rob Pikeaaa3a622010-03-20 22:32:34 -0700983// Test that enums work. Checks for a bug introduced by making enums
984// named types instead of int32: newInt32FromUint64 would crash with
985// a type mismatch in reflect.PointTo.
986func TestEnum(t *testing.T) {
987 pb := new(GoEnum)
988 pb.Foo = NewFOO(FOO_FOO1)
989 o := old()
990 if err := o.Marshal(pb); err != nil {
991 t.Fatalf("error encoding enum:", err)
992 }
993 pb1 := new(GoEnum)
994 if err := o.Unmarshal(pb1); err != nil {
995 t.Fatalf("error decoding enum:", err)
996 }
997 if *pb1.Foo != FOO_FOO1 {
998 t.Errorf("expected 7 but got ", *pb1.Foo)
999 }
1000}
1001
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001002// Verify that absent required fields cause Marshal/Unmarshal to return errors.
1003func TestRequiredFieldEnforcement(t *testing.T) {
1004 pb := new(GoTestField)
1005 _, err := Marshal(pb)
1006 if err == nil || err != ErrRequiredNotSet {
1007 t.Errorf("marshal: expected %q, got %q", ErrRequiredNotSet, err)
1008 }
1009
1010 // A slightly sneaky, yet valid, proto. It encodes the same required field twice,
1011 // so simply counting the required fields is insufficient.
1012 // field 1, encoding 2, value "hi"
1013 buf := []byte("\x0A\x02hi\x0A\x02hi")
1014 err = Unmarshal(buf, pb)
1015 if err == nil || err != ErrRequiredNotSet {
1016 t.Errorf("unmarshal: expected %q, got %q", ErrRequiredNotSet, err)
1017 }
1018}
1019
Rob Pikeaaa3a622010-03-20 22:32:34 -07001020func BenchmarkMarshal(b *testing.B) {
1021 b.StopTimer()
1022
1023 pb := initGoTest(true)
1024
1025 // Create an array
1026 const N = 1000 // Internally the library starts much smaller.
1027 pb.F_Int32Repeated = make([]int32, N)
1028
1029 // Fill in the array with some values.
1030 for i := 0; i < N; i++ {
1031 pb.F_Int32Repeated[i] = int32(i)
1032 }
1033 p := NewBuffer(nil)
1034
1035 b.StartTimer()
1036 for i := 0; i < b.N; i++ {
1037 p.Reset()
1038 p.Marshal(pb)
1039 }
1040}
1041
1042func BenchmarkUnmarshal(b *testing.B) {
1043 b.StopTimer()
1044
1045 pb := initGoTest(true)
1046
1047 // Create an array
1048 const N = 1000 // Internally the library starts much smaller.
1049 pb.F_Int32Repeated = make([]int32, N)
1050
1051 // Fill in the array with some values.
1052 for i := 0; i < N; i++ {
1053 pb.F_Int32Repeated[i] = int32(i)
1054 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001055 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001056 p := NewBuffer(nil)
1057 p.Marshal(pb)
1058 p2 := NewBuffer(nil)
1059
1060 b.StartTimer()
1061 for i := 0; i < b.N; i++ {
1062 p2.SetBuf(p.Bytes())
1063 p2.Unmarshal(pbd)
1064 }
1065}