go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/lucicfg/protos_test.go (about) 1 // Copyright 2018 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lucicfg 16 17 import ( 18 "os" 19 "testing" 20 21 "go.starlark.net/starlark" 22 23 "google.golang.org/protobuf/proto" 24 "google.golang.org/protobuf/types/descriptorpb" 25 26 "go.chromium.org/luci/common/proto/textpb" 27 "go.chromium.org/luci/starlark/starlarkproto" 28 29 . "github.com/smartystreets/goconvey/convey" 30 ) 31 32 // testMessageType represents testproto.Msg from misc/support/test.proto as 33 // loaded through starlarkproto Loader. 34 // 35 // Used by testMessage and testMessageProto. 36 var testMessageType *starlarkproto.MessageType 37 38 func init() { 39 // See testdata/gen.go for where this file is generated. 40 blob, err := os.ReadFile("testdata/misc/support/test_descpb.bin") 41 if err != nil { 42 panic(err) 43 } 44 dspb := &descriptorpb.FileDescriptorSet{} 45 if err := proto.Unmarshal(blob, dspb); err != nil { 46 panic(err) 47 } 48 ds, err := starlarkproto.NewDescriptorSet("test", dspb.GetFile(), []*starlarkproto.DescriptorSet{ 49 luciTypesDescSet, // for "go.chromium.org/luci/common/proto/options.proto" 50 }) 51 if err != nil { 52 panic(err) 53 } 54 testProtoLoader := starlarkproto.NewLoader() 55 if err := testProtoLoader.AddDescriptorSet(ds); err != nil { 56 panic(err) 57 } 58 testproto, err := testProtoLoader.Module("misc/support/test.proto") 59 if err != nil { 60 panic(err) 61 } 62 msgT, err := testproto.Attr("Msg") 63 if err != nil { 64 panic(err) 65 } 66 testMessageType = msgT.(*starlarkproto.MessageType) 67 } 68 69 // testMessage returns new testproto.Msg as a Starlark value to be used from 70 // tests (grabs it via testProtoLoader). 71 func testMessage(i int, f float64) *starlarkproto.Message { 72 msg := testMessageType.Message() 73 if err := msg.SetField("i", starlark.MakeInt(i)); err != nil { 74 panic(err) 75 } 76 if err := msg.SetField("f", starlark.Float(f)); err != nil { 77 panic(err) 78 } 79 return msg 80 } 81 82 // testMessageProto returns new testproto.Msg as proto.Message, deserializing 83 // it from a text proto. 84 func testMessageProto(body string) proto.Message { 85 msg, err := starlarkproto.FromTextPB(testMessageType, []byte(body), false) 86 if err != nil { 87 panic(err) 88 } 89 return msg.ToProto() 90 } 91 92 func TestProtos(t *testing.T) { 93 t.Parallel() 94 95 // Note: testMessage() is used by other tests. This test verifies it works 96 // at all. 97 Convey("testMessage works", t, func() { 98 i, err := testMessage(123, 0).Attr("i") 99 So(err, ShouldBeNil) 100 asInt, err := starlark.AsInt32(i) 101 So(err, ShouldBeNil) 102 So(asInt, ShouldEqual, 123) 103 }) 104 105 Convey("testMessageProto works", t, func() { 106 msg := testMessageProto("i: 456") 107 blob, err := textpb.Marshal(msg) 108 So(err, ShouldBeNil) 109 So(string(blob), ShouldEqual, "i: 456\n") 110 }) 111 112 Convey("Doc URL works", t, func() { 113 name, doc := protoMessageDoc(testMessage(123, 0)) 114 So(name, ShouldEqual, "Msg") 115 So(doc, ShouldEqual, "https://example.com/proto-doc") // see misc/support/test.proto 116 }) 117 118 Convey("semanticallyEqual: true", t, func() { 119 msg1 := testMessageProto(` 120 i: 123 121 nested: { 122 s: "aaa" 123 ignore: "ignore 1" 124 } 125 ignore_scalar: "ignore 1" 126 ignore_rep: "ignore 1" 127 ignore_rep: "ignore 1" 128 ignore_nested: { 129 s: "ignore 1" 130 } 131 `) 132 msg2 := testMessageProto(` 133 i: 123 134 nested: { 135 s: "aaa" 136 ignore: "ignore 2" 137 } 138 ignore_scalar: "ignore 2" 139 ignore_rep: "ignore 2" 140 ignore_rep: "ignore 2" 141 ignore_nested: { 142 s: "ignore 2" 143 } 144 `) 145 So(semanticallyEqual(msg1, msg2), ShouldBeTrue) 146 }) 147 148 Convey("semanticallyEqual: false", t, func() { 149 msg1 := testMessageProto(` 150 i: 123 151 nested: { 152 s: "aaa" 153 ignore: "ignore 1" 154 } 155 ignore_scalar: "ignore 1" 156 ignore_rep: "ignore 1" 157 ignore_rep: "ignore 1" 158 ignore_nested: { 159 s: "ignore 1" 160 } 161 `) 162 msg2 := testMessageProto(` 163 i: 123 164 nested: { 165 s: "bbb" 166 ignore: "ignore 2" 167 } 168 ignore_scalar: "ignore 2" 169 ignore_rep: "ignore 2" 170 ignore_rep: "ignore 2" 171 ignore_nested: { 172 s: "ignore 2" 173 } 174 `) 175 So(semanticallyEqual(msg1, msg2), ShouldBeFalse) 176 }) 177 }