go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/logdog/common/storage/bigtable/rowKey_test.go (about) 1 // Copyright 2015 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 bigtable 16 17 import ( 18 "fmt" 19 "testing" 20 21 . "github.com/smartystreets/goconvey/convey" 22 ) 23 24 func TestRowKey(t *testing.T) { 25 t.Parallel() 26 27 Convey(`A row key, constructed from "test-project" and "a/b/+/c/d"`, t, func() { 28 project := "test-project" 29 path := "a/b/+/c/d" 30 31 rk := newRowKey(project, path, 1337, 42) 32 33 Convey(`Shares a path with a row key from the same Path.`, func() { 34 So(rk.sharesPathWith(newRowKey(project, path, 2468, 0)), ShouldBeTrue) 35 }) 36 37 for _, project := range []string{ 38 "", 39 "other-test-project", 40 } { 41 for _, path := range []string{ 42 "a/b/+/c", 43 "asdf", 44 "", 45 } { 46 Convey(fmt.Sprintf(`Does not share a path with project %q, path %q`, project, path), func() { 47 So(rk.sharesPathWith(newRowKey(project, path, 0, 0)), ShouldBeFalse) 48 }) 49 } 50 } 51 52 Convey(`Can be encoded, then decoded into its fields.`, func() { 53 enc := rk.encode() 54 So(len(enc), ShouldBeLessThanOrEqualTo, maxEncodedKeySize) 55 56 drk, err := decodeRowKey(enc) 57 So(err, ShouldBeNil) 58 59 So(drk.pathHash, ShouldResemble, rk.pathHash) 60 So(drk.index, ShouldEqual, rk.index) 61 So(drk.count, ShouldEqual, rk.count) 62 }) 63 }) 64 65 Convey(`A series of ordered row keys`, t, func() { 66 prev := "" 67 for _, i := range []int64{ 68 -1, /* Why not? */ 69 0, 70 7, 71 8, 72 257, 73 1029, 74 1337, 75 } { 76 Convey(fmt.Sprintf(`Row key %d should be ascendingly sorted and parsable.`, i), func() { 77 rk := newRowKey("test-project", "test", i, i) 78 79 // Test that it encodes/decodes back to identity. 80 enc := rk.encode() 81 drk, err := decodeRowKey(enc) 82 So(err, ShouldBeNil) 83 So(drk.index, ShouldEqual, i) 84 85 // Assert that it is ordered. 86 if prev != "" { 87 So(prev, ShouldBeLessThan, enc) 88 89 prevp, err := decodeRowKey(prev) 90 So(err, ShouldBeNil) 91 So(prevp.sharesPathWith(rk), ShouldBeTrue) 92 So(prevp.index, ShouldBeLessThan, drk.index) 93 So(prevp.count, ShouldBeLessThan, drk.count) 94 } 95 }) 96 } 97 }) 98 99 Convey(`Invalid row keys will fail to decode with "errMalformedRowKey".`, t, func() { 100 for _, t := range []struct { 101 name string 102 v string 103 }{ 104 {"No tilde", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd38080"}, 105 {"No path hash", "~8080"}, 106 {"Bad hex path hash", "badhex~8080"}, 107 {"Path has too short", "4a54700540127~8080"}, 108 {"Bad hex index", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3~badhex"}, 109 {"Missing index.", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3~"}, 110 {"Varint overflow", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3~ffffffffffff"}, 111 {"Trailing data", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3~8080badd06"}, 112 } { 113 Convey(fmt.Sprintf(`Row key fails to decode [%s]: %q`, t.name, t.v), func() { 114 _, err := decodeRowKey(t.v) 115 So(err, ShouldEqual, errMalformedRowKey) 116 }) 117 } 118 }) 119 }