go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/proto/stable_hash_test.go (about) 1 // Copyright 2023 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 proto 16 17 import ( 18 "crypto/sha256" 19 "fmt" 20 "testing" 21 22 . "github.com/smartystreets/goconvey/convey" 23 "go.chromium.org/luci/common/proto/internal/testingpb" 24 "google.golang.org/protobuf/types/known/anypb" 25 ) 26 27 func TestStableHash(t *testing.T) { 28 Convey("stable hash for proto message", t, func() { 29 h := sha256.New() 30 Convey("simple proto", func() { 31 err := StableHash(h, &testingpb.Simple{ 32 Id: 1, 33 Some: &testingpb.Some{I: 2}, 34 }) 35 So(err, ShouldBeNil) 36 So(fmt.Sprintf("%x", h.Sum(nil)), ShouldEqual, "09abb21ea7df951884db3c940c10866cc7949d4b93c3b498e39144e1e2e7a50e") 37 }) 38 Convey("full proto", func() { 39 err := StableHash(h, &testingpb.Full{ 40 Nums: []int32{1, 2, 3}, 41 Strs: []string{"a", "b"}, 42 Msg: &testingpb.Full{I32: -1, I64: -2, U32: 1, U64: 2, F32: 1.0, F64: 2.0}, 43 MapStrNum: map[string]int32{"x": 1, "y": 2}, 44 MapNumStr: map[int32]string{1: "x", 2: "y"}, 45 MapBoolStr: map[bool]string{true: "x", false: "y"}, 46 }) 47 So(err, ShouldBeNil) 48 So(fmt.Sprintf("%x", h.Sum(nil)), ShouldEqual, "a03f498e9953da367ad852a7cc3a5825c4b5d37b31108065efc90542ee14bcfd") 49 }) 50 Convey("full proto - empty", func() { 51 err := StableHash(h, &testingpb.Full{}) 52 So(err, ShouldBeNil) 53 So(fmt.Sprintf("%x", h.Sum(nil)), ShouldEqual, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") 54 }) 55 Convey("any proto", func() { 56 msg, err := anypb.New(&testingpb.Simple{}) 57 So(err, ShouldBeNil) 58 err = StableHash(h, msg) 59 So(err, ShouldBeNil) 60 }) 61 Convey("any proto without type", func() { 62 err := StableHash(h, &anypb.Any{}) 63 So(err, ShouldNotBeNil) 64 So(err.Error(), ShouldContainSubstring, "invalid empty type URL") 65 }) 66 Convey("unknown field", func() { 67 drv := &testingpb.Simple{} 68 drv.ProtoReflect().SetUnknown([]byte{0}) 69 err := StableHash(h, drv) 70 So(err, ShouldNotBeNil) 71 So(err.Error(), ShouldContainSubstring, "unknown fields cannot be hashed") 72 }) 73 }) 74 }