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  }