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  }