github.com/nsqio/nsq@v1.3.0/nsqlookupd/registration_db_test.go (about)

     1  package nsqlookupd
     2  
     3  import (
     4  	"math/rand"
     5  	"strconv"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/nsqio/nsq/internal/test"
    10  )
    11  
    12  func TestRegistrationDB(t *testing.T) {
    13  	sec30 := 30 * time.Second
    14  	beginningOfTime := time.Unix(1348797047, 0)
    15  	pi1 := &PeerInfo{beginningOfTime.UnixNano(), "1", "remote_addr:1", "host", "b_addr", 1, 2, "v1"}
    16  	pi2 := &PeerInfo{beginningOfTime.UnixNano(), "2", "remote_addr:2", "host", "b_addr", 2, 3, "v1"}
    17  	pi3 := &PeerInfo{beginningOfTime.UnixNano(), "3", "remote_addr:3", "host", "b_addr", 3, 4, "v1"}
    18  	p1 := &Producer{pi1, false, beginningOfTime}
    19  	p2 := &Producer{pi2, false, beginningOfTime}
    20  	p3 := &Producer{pi3, false, beginningOfTime}
    21  	p4 := &Producer{pi1, false, beginningOfTime}
    22  
    23  	db := NewRegistrationDB()
    24  
    25  	// add producers
    26  	db.AddProducer(Registration{"c", "a", ""}, p1)
    27  	db.AddProducer(Registration{"c", "a", ""}, p2)
    28  	db.AddProducer(Registration{"c", "a", "b"}, p2)
    29  	db.AddProducer(Registration{"d", "a", ""}, p3)
    30  	db.AddProducer(Registration{"t", "a", ""}, p4)
    31  
    32  	// find producers
    33  	r := db.FindRegistrations("c", "*", "").Keys()
    34  	test.Equal(t, 1, len(r))
    35  	test.Equal(t, "a", r[0])
    36  
    37  	p := db.FindProducers("t", "*", "")
    38  	t.Logf("%s", p)
    39  	test.Equal(t, 1, len(p))
    40  	p = db.FindProducers("c", "*", "")
    41  	t.Logf("%s", p)
    42  	test.Equal(t, 2, len(p))
    43  	p = db.FindProducers("c", "a", "")
    44  	t.Logf("%s", p)
    45  	test.Equal(t, 2, len(p))
    46  	p = db.FindProducers("c", "*", "b")
    47  	t.Logf("%s", p)
    48  	test.Equal(t, 1, len(p))
    49  	test.Equal(t, p2.peerInfo.id, p[0].peerInfo.id)
    50  
    51  	// filter by active
    52  	test.Equal(t, 0, len(p.FilterByActive(sec30, sec30)))
    53  	p2.peerInfo.lastUpdate = time.Now().UnixNano()
    54  	test.Equal(t, 1, len(p.FilterByActive(sec30, sec30)))
    55  	p = db.FindProducers("c", "*", "")
    56  	t.Logf("%s", p)
    57  	test.Equal(t, 1, len(p.FilterByActive(sec30, sec30)))
    58  
    59  	// tombstoning
    60  	fewSecAgo := time.Now().Add(-5 * time.Second).UnixNano()
    61  	p1.peerInfo.lastUpdate = fewSecAgo
    62  	p2.peerInfo.lastUpdate = fewSecAgo
    63  	test.Equal(t, 2, len(p.FilterByActive(sec30, sec30)))
    64  	p1.Tombstone()
    65  	test.Equal(t, 1, len(p.FilterByActive(sec30, sec30)))
    66  	time.Sleep(10 * time.Millisecond)
    67  	test.Equal(t, 2, len(p.FilterByActive(sec30, 5*time.Millisecond)))
    68  	// make sure we can still retrieve p1 from another registration see #148
    69  	test.Equal(t, 1, len(db.FindProducers("t", "*", "").FilterByActive(sec30, sec30)))
    70  
    71  	// keys and subkeys
    72  	k := db.FindRegistrations("c", "b", "").Keys()
    73  	test.Equal(t, 0, len(k))
    74  	k = db.FindRegistrations("c", "a", "").Keys()
    75  	test.Equal(t, 1, len(k))
    76  	test.Equal(t, "a", k[0])
    77  	k = db.FindRegistrations("c", "*", "b").SubKeys()
    78  	test.Equal(t, 1, len(k))
    79  	test.Equal(t, "b", k[0])
    80  
    81  	// removing producers
    82  	db.RemoveProducer(Registration{"c", "a", ""}, p1.peerInfo.id)
    83  	p = db.FindProducers("c", "*", "*")
    84  	t.Logf("%s", p)
    85  	test.Equal(t, 1, len(p))
    86  
    87  	db.RemoveProducer(Registration{"c", "a", ""}, p2.peerInfo.id)
    88  	db.RemoveProducer(Registration{"c", "a", "b"}, p2.peerInfo.id)
    89  	p = db.FindProducers("c", "*", "*")
    90  	t.Logf("%s", p)
    91  	test.Equal(t, 0, len(p))
    92  
    93  	// do some key removals
    94  	k = db.FindRegistrations("c", "*", "*").Keys()
    95  	test.Equal(t, 2, len(k))
    96  	db.RemoveRegistration(Registration{"c", "a", ""})
    97  	db.RemoveRegistration(Registration{"c", "a", "b"})
    98  	k = db.FindRegistrations("c", "*", "*").Keys()
    99  	test.Equal(t, 0, len(k))
   100  }
   101  
   102  func fillRegDB(registrations int, producers int) *RegistrationDB {
   103  	regDB := NewRegistrationDB()
   104  	for i := 0; i < registrations; i++ {
   105  		regT := Registration{"topic", "t" + strconv.Itoa(i), ""}
   106  		regCa := Registration{"channel", "t" + strconv.Itoa(i), "ca" + strconv.Itoa(i)}
   107  		regCb := Registration{"channel", "t" + strconv.Itoa(i), "cb" + strconv.Itoa(i)}
   108  		for j := 0; j < producers; j++ {
   109  			p := Producer{
   110  				peerInfo: &PeerInfo{
   111  					id: "p" + strconv.Itoa(j),
   112  				},
   113  			}
   114  			regDB.AddProducer(regT, &p)
   115  			regDB.AddProducer(regCa, &p)
   116  			regDB.AddProducer(regCb, &p)
   117  		}
   118  	}
   119  	return regDB
   120  }
   121  
   122  func benchmarkLookupRegistrations(b *testing.B, registrations int, producers int) {
   123  	regDB := fillRegDB(registrations, producers)
   124  	b.ResetTimer()
   125  	for i := 0; i < b.N; i++ {
   126  		j := strconv.Itoa(rand.Intn(producers))
   127  		_ = regDB.LookupRegistrations("p" + j)
   128  	}
   129  }
   130  
   131  func benchmarkRegister(b *testing.B, registrations int, producers int) {
   132  	for i := 0; i < b.N; i++ {
   133  		_ = fillRegDB(registrations, producers)
   134  	}
   135  }
   136  
   137  func benchmarkDoLookup(b *testing.B, registrations int, producers int) {
   138  	regDB := fillRegDB(registrations, producers)
   139  	b.ResetTimer()
   140  	for i := 0; i < b.N; i++ {
   141  		topic := "t" + strconv.Itoa(rand.Intn(registrations))
   142  		_ = regDB.FindRegistrations("topic", topic, "")
   143  		_ = regDB.FindRegistrations("channel", topic, "*").SubKeys()
   144  		_ = regDB.FindProducers("topic", topic, "")
   145  	}
   146  }
   147  
   148  func BenchmarkLookupRegistrations8x8(b *testing.B) {
   149  	benchmarkLookupRegistrations(b, 8, 8)
   150  }
   151  
   152  func BenchmarkLookupRegistrations8x64(b *testing.B) {
   153  	benchmarkLookupRegistrations(b, 8, 64)
   154  }
   155  
   156  func BenchmarkLookupRegistrations64x64(b *testing.B) {
   157  	benchmarkLookupRegistrations(b, 64, 64)
   158  }
   159  
   160  func BenchmarkLookupRegistrations64x512(b *testing.B) {
   161  	benchmarkLookupRegistrations(b, 64, 512)
   162  }
   163  
   164  func BenchmarkLookupRegistrations512x512(b *testing.B) {
   165  	benchmarkLookupRegistrations(b, 512, 512)
   166  }
   167  
   168  func BenchmarkLookupRegistrations512x2048(b *testing.B) {
   169  	benchmarkLookupRegistrations(b, 512, 2048)
   170  }
   171  
   172  func BenchmarkRegister8x8(b *testing.B) {
   173  	benchmarkRegister(b, 8, 8)
   174  }
   175  
   176  func BenchmarkRegister8x64(b *testing.B) {
   177  	benchmarkRegister(b, 8, 64)
   178  }
   179  
   180  func BenchmarkRegister64x64(b *testing.B) {
   181  	benchmarkRegister(b, 64, 64)
   182  }
   183  
   184  func BenchmarkRegister64x512(b *testing.B) {
   185  	benchmarkRegister(b, 64, 512)
   186  }
   187  
   188  func BenchmarkRegister512x512(b *testing.B) {
   189  	benchmarkRegister(b, 512, 512)
   190  }
   191  
   192  func BenchmarkRegister512x2048(b *testing.B) {
   193  	benchmarkRegister(b, 512, 2048)
   194  }
   195  
   196  func BenchmarkDoLookup8x8(b *testing.B) {
   197  	benchmarkDoLookup(b, 8, 8)
   198  }
   199  
   200  func BenchmarkDoLookup8x64(b *testing.B) {
   201  	benchmarkDoLookup(b, 8, 64)
   202  }
   203  
   204  func BenchmarkDoLookup64x64(b *testing.B) {
   205  	benchmarkDoLookup(b, 64, 64)
   206  }
   207  
   208  func BenchmarkDoLookup64x512(b *testing.B) {
   209  	benchmarkDoLookup(b, 64, 512)
   210  }
   211  
   212  func BenchmarkDoLookup512x512(b *testing.B) {
   213  	benchmarkDoLookup(b, 512, 512)
   214  }
   215  
   216  func BenchmarkDoLookup512x2048(b *testing.B) {
   217  	benchmarkDoLookup(b, 512, 2048)
   218  }