github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/gossip/util_test.go (about) 1 // Copyright 2018 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package gossip 12 13 import ( 14 "math/rand" 15 "reflect" 16 "sort" 17 "strconv" 18 "testing" 19 20 "github.com/cockroachdb/cockroach/pkg/config" 21 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 22 "github.com/cockroachdb/cockroach/pkg/roachpb" 23 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 24 "github.com/cockroachdb/cockroach/pkg/util/randutil" 25 ) 26 27 func keyFromInt(i int) roachpb.Key { 28 return roachpb.Key(strconv.Itoa(i)) 29 } 30 31 // addKV adds a random value for the specified key to the system config. 32 func addKV(rng *rand.Rand, cfg *config.SystemConfig, key int) { 33 newKey := keyFromInt(key) 34 modified := false 35 for _, oldKV := range cfg.Values { 36 if !oldKV.Key.Equal(newKey) { 37 modified = true 38 break 39 } 40 } 41 newKVs := cfg.Values 42 if modified { 43 newKVs = make([]roachpb.KeyValue, 0, len(cfg.Values)) 44 for _, oldKV := range cfg.Values { 45 if !oldKV.Key.Equal(newKey) { 46 newKVs = append(newKVs, oldKV) 47 } 48 } 49 } 50 newKVs = append(newKVs, roachpb.KeyValue{ 51 Key: newKey, 52 Value: roachpb.Value{ 53 RawBytes: randutil.RandBytes(rng, 100), 54 }, 55 }) 56 sort.Sort(roachpb.KeyValueByKey(newKVs)) 57 cfg.Values = newKVs 58 } 59 60 // assertModified asserts that the specified keys will be considered "modified" 61 // when passing the new system config through the filter. 62 func assertModified( 63 t *testing.T, df *SystemConfigDeltaFilter, cfg *config.SystemConfig, keys ...int, 64 ) { 65 t.Helper() 66 var modified []int 67 df.ForModified(cfg, func(kv roachpb.KeyValue) { 68 key, err := strconv.Atoi(string(kv.Key)) 69 if err != nil { 70 t.Fatal(err) 71 } 72 modified = append(modified, key) 73 }) 74 if !reflect.DeepEqual(modified, keys) { 75 t.Errorf("expected keys modified=%v, found %v", keys, modified) 76 } 77 } 78 79 func TestSystemConfigDeltaFilter(t *testing.T) { 80 defer leaktest.AfterTest(t)() 81 rng, _ := randutil.NewPseudoRand() 82 83 df := MakeSystemConfigDeltaFilter(nil) 84 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 85 86 // Add one key. 87 addKV(rng, cfg, 1) 88 assertModified(t, &df, cfg, 1) 89 90 // Add two keys. 91 addKV(rng, cfg, 2) 92 addKV(rng, cfg, 3) 93 assertModified(t, &df, cfg, 2, 3) 94 95 // Modify a key. 96 addKV(rng, cfg, 2) 97 assertModified(t, &df, cfg, 2) 98 99 // Add one key at beginning, modify one key. 100 addKV(rng, cfg, 0) 101 addKV(rng, cfg, 1) 102 assertModified(t, &df, cfg, 0, 1) 103 104 // Remove the first key. 105 cfg.Values = cfg.Values[1:] 106 assertModified(t, &df, cfg) 107 } 108 109 func TestSystemConfigDeltaFilterWithKeyPrefix(t *testing.T) { 110 defer leaktest.AfterTest(t)() 111 rng, _ := randutil.NewPseudoRand() 112 113 df := MakeSystemConfigDeltaFilter(keyFromInt(12)) 114 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 115 116 // Add one non-matching key. 117 addKV(rng, cfg, 1) 118 assertModified(t, &df, cfg) 119 120 // Add one matching key. 121 addKV(rng, cfg, 123) 122 assertModified(t, &df, cfg, 123) 123 124 // Add two keys, one matching, one non-matching. 125 addKV(rng, cfg, 125) 126 addKV(rng, cfg, 135) 127 assertModified(t, &df, cfg, 125) 128 129 // Modify two keys, one matching, one non-matching. 130 addKV(rng, cfg, 1) 131 addKV(rng, cfg, 123) 132 assertModified(t, &df, cfg, 123) 133 } 134 135 func BenchmarkSystemConfigDeltaFilter(b *testing.B) { 136 df := MakeSystemConfigDeltaFilter(keyFromInt(1)) 137 rng, _ := randutil.NewPseudoRand() 138 139 // Create two configs. 140 cfg1, cfg2 := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()), config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 141 for i := 0; i < 1000; i++ { 142 key := i + 100000 // +100000 to match filter 143 addKV(rng, cfg1, key) 144 } 145 for i := 0; i < 200; i++ { 146 key := i + 200000 // +200000 to avoid matching filter 147 addKV(rng, cfg1, key) 148 } 149 // Copy to cfg2 so that most kvs are shared. 150 cfg2.Values = append([]roachpb.KeyValue(nil), cfg1.Values...) 151 152 // Make a few modifications to cfg2. 153 for i := 0; i < 20; i++ { 154 key := i + 1000000 // +1000000 to match filter and first group 155 addKV(rng, cfg2, key) 156 } 157 for i := 0; i < 20; i++ { 158 key := i + 10000 // +10000 to match filter 159 addKV(rng, cfg2, key) 160 } 161 162 b.ResetTimer() 163 for i := 0; i < b.N; i++ { 164 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 165 cfg.Values = cfg1.Values 166 if i%2 == 1 { 167 cfg.Values = cfg2.Values 168 } 169 df.ForModified(cfg, func(kv roachpb.KeyValue) { 170 _ = kv 171 }) 172 } 173 }