github.com/gogo/protobuf@v1.3.2/protoc-gen-gogo/testdata/extension_test.go (about) 1 // Go support for Protocol Buffers - Google's data interchange format 2 // 3 // Copyright 2010 The Go Authors. All rights reserved. 4 // https://github.com/golang/protobuf 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 // Test that we can use protocol buffers that use extensions. 33 34 package testdata 35 36 import ( 37 "bytes" 38 "regexp" 39 "testing" 40 41 "github.com/gogo/protobuf/proto" 42 base "github.com/gogo/protobuf/protoc-gen-gogo/testdata/extension_base" 43 user "github.com/gogo/protobuf/protoc-gen-gogo/testdata/extension_user" 44 ) 45 46 func TestSingleFieldExtension(t *testing.T) { 47 bm := &base.BaseMessage{ 48 Height: proto.Int32(178), 49 } 50 51 // Use extension within scope of another type. 52 vol := proto.Uint32(11) 53 if err := proto.SetExtension(bm, user.E_LoudMessage_Volume, vol); err != nil { 54 t.Fatal("Failed setting extension:", err) 55 } 56 buf, berr := proto.Marshal(bm) 57 if berr != nil { 58 t.Fatal("Failed encoding message with extension:", berr) 59 } 60 bm_new := new(base.BaseMessage) 61 if err := proto.Unmarshal(buf, bm_new); err != nil { 62 t.Fatal("Failed decoding message with extension:", err) 63 } 64 if !proto.HasExtension(bm_new, user.E_LoudMessage_Volume) { 65 t.Fatal("Decoded message didn't contain extension.") 66 } 67 vol_out, err := proto.GetExtension(bm_new, user.E_LoudMessage_Volume) 68 if err != nil { 69 t.Fatal("Failed getting extension:", err) 70 } 71 if v := vol_out.(*uint32); *v != *vol { 72 t.Errorf("vol_out = %v, expected %v", *v, *vol) 73 } 74 proto.ClearExtension(bm_new, user.E_LoudMessage_Volume) 75 if proto.HasExtension(bm_new, user.E_LoudMessage_Volume) { 76 t.Fatal("Failed clearing extension.") 77 } 78 } 79 80 func TestMessageExtension(t *testing.T) { 81 bm := &base.BaseMessage{ 82 Height: proto.Int32(179), 83 } 84 85 // Use extension that is itself a message. 86 um := &user.UserMessage{ 87 Name: proto.String("Dave"), 88 Rank: proto.String("Major"), 89 } 90 if err := proto.SetExtension(bm, user.E_LoginMessage_UserMessage, um); err != nil { 91 t.Fatal("Failed setting extension:", err) 92 } 93 buf, berr := proto.Marshal(bm) 94 if berr != nil { 95 t.Fatal("Failed encoding message with extension:", berr) 96 } 97 bm_new := new(base.BaseMessage) 98 if err := proto.Unmarshal(buf, bm_new); err != nil { 99 t.Fatal("Failed decoding message with extension:", err) 100 } 101 if !proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) { 102 t.Fatal("Decoded message didn't contain extension.") 103 } 104 um_out, err := proto.GetExtension(bm_new, user.E_LoginMessage_UserMessage) 105 if err != nil { 106 t.Fatal("Failed getting extension:", err) 107 } 108 if n := um_out.(*user.UserMessage).Name; *n != *um.Name { 109 t.Errorf("um_out.Name = %q, expected %q", *n, *um.Name) 110 } 111 if r := um_out.(*user.UserMessage).Rank; *r != *um.Rank { 112 t.Errorf("um_out.Rank = %q, expected %q", *r, *um.Rank) 113 } 114 proto.ClearExtension(bm_new, user.E_LoginMessage_UserMessage) 115 if proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) { 116 t.Fatal("Failed clearing extension.") 117 } 118 } 119 120 func TestTopLevelExtension(t *testing.T) { 121 bm := &base.BaseMessage{ 122 Height: proto.Int32(179), 123 } 124 125 width := proto.Int32(17) 126 if err := proto.SetExtension(bm, user.E_Width, width); err != nil { 127 t.Fatal("Failed setting extension:", err) 128 } 129 buf, berr := proto.Marshal(bm) 130 if berr != nil { 131 t.Fatal("Failed encoding message with extension:", berr) 132 } 133 bm_new := new(base.BaseMessage) 134 if err := proto.Unmarshal(buf, bm_new); err != nil { 135 t.Fatal("Failed decoding message with extension:", err) 136 } 137 if !proto.HasExtension(bm_new, user.E_Width) { 138 t.Fatal("Decoded message didn't contain extension.") 139 } 140 width_out, err := proto.GetExtension(bm_new, user.E_Width) 141 if err != nil { 142 t.Fatal("Failed getting extension:", err) 143 } 144 if w := width_out.(*int32); *w != *width { 145 t.Errorf("width_out = %v, expected %v", *w, *width) 146 } 147 proto.ClearExtension(bm_new, user.E_Width) 148 if proto.HasExtension(bm_new, user.E_Width) { 149 t.Fatal("Failed clearing extension.") 150 } 151 } 152 153 func TestMessageSetWireFormat(t *testing.T) { 154 osm := new(base.OldStyleMessage) 155 osp := &user.OldStyleParcel{ 156 Name: proto.String("Dave"), 157 Height: proto.Int32(178), 158 } 159 160 if err := proto.SetExtension(osm, user.E_OldStyleParcel_MessageSetExtension, osp); err != nil { 161 t.Fatal("Failed setting extension:", err) 162 } 163 164 buf, berr := proto.Marshal(osm) 165 if berr != nil { 166 t.Fatal("Failed encoding message:", berr) 167 } 168 169 // Data generated from Python implementation. 170 expected := []byte{ 171 11, 16, 209, 15, 26, 9, 10, 4, 68, 97, 118, 101, 16, 178, 1, 12, 172 } 173 174 if !bytes.Equal(expected, buf) { 175 t.Errorf("Encoding mismatch.\nwant %+v\n got %+v", expected, buf) 176 } 177 178 // Check that it is restored correctly. 179 osm = new(base.OldStyleMessage) 180 if err := proto.Unmarshal(buf, osm); err != nil { 181 t.Fatal("Failed decoding message:", err) 182 } 183 osp_out, err := proto.GetExtension(osm, user.E_OldStyleParcel_MessageSetExtension) 184 if err != nil { 185 t.Fatal("Failed getting extension:", err) 186 } 187 osp = osp_out.(*user.OldStyleParcel) 188 if *osp.Name != "Dave" || *osp.Height != 178 { 189 t.Errorf("Retrieved extension from decoded message is not correct: %+v", osp) 190 } 191 } 192 193 func main() { 194 // simpler than rigging up gotest 195 testing.Main(regexp.MatchString, []testing.InternalTest{ 196 {"TestSingleFieldExtension", TestSingleFieldExtension}, 197 {"TestMessageExtension", TestMessageExtension}, 198 {"TestTopLevelExtension", TestTopLevelExtension}, 199 }, 200 []testing.InternalBenchmark{}, 201 []testing.InternalExample{}) 202 }