github.com/blong14/gache@v0.0.0-20240124023949-89416fd8bbfa/internal/proxy/proxy_test.go (about) 1 package proxy_test 2 3 import ( 4 "context" 5 "encoding/binary" 6 "fmt" 7 "math/rand" 8 "os" 9 "path/filepath" 10 "testing" 11 "time" 12 13 gdb "github.com/blong14/gache/internal/db" 14 gproxy "github.com/blong14/gache/internal/proxy" 15 ) 16 17 func tearDown(t *testing.T) { 18 err := os.Remove(filepath.Join("testdata", "default-wal.dat")) 19 if err != nil { 20 t.Log(err) 21 } 22 err = os.Remove(filepath.Join("testdata", "default.dat")) 23 if err != nil { 24 t.Log(err) 25 } 26 } 27 28 func TestQueryProxy_Execute(t *testing.T) { 29 ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) 30 qp, err := gproxy.NewQueryProxy() 31 if err != nil { 32 t.Error(err) 33 } 34 gproxy.StartProxy(ctx, qp) 35 t.Cleanup(func() { 36 gproxy.StopProxy(ctx, qp) 37 cancel() 38 tearDown(t) 39 }) 40 41 start := time.Now() 42 query, done := gdb.NewLoadFromFileQuery( 43 ctx, []byte("default"), []byte(filepath.Join("testdata", "i.csv"))) 44 qp.Send(ctx, query) 45 select { 46 case <-ctx.Done(): 47 t.Error(ctx.Err()) 48 case result, ok := <-done: 49 if !ok || !result.Success { 50 t.Error("not ok") 51 return 52 } 53 } 54 t.Logf("finished - %s", time.Since(start)) 55 query = gdb.NewQuery(ctx, nil) 56 query.Header.TableName = []byte("default") 57 query.Header.Inst = gdb.Count 58 qp.Send(ctx, query) 59 resp := query.GetResponse() 60 t.Logf("count %d", resp.Stats.Count) 61 } 62 63 func BenchmarkConcurrent_QueryProxy(b *testing.B) { 64 b.Setenv("DEBUG", "false") 65 b.Setenv("TRACE", "false") 66 for _, i := range []int{3, 5, 7} { 67 readFrac := float32(i) / 10.0 68 ctx, cancel := context.WithTimeout(context.Background(), 500*time.Second) 69 qp, err := gproxy.NewQueryProxy() 70 if err != nil { 71 b.Error(err) 72 } 73 gproxy.StartProxy(ctx, qp) 74 75 b.Run(fmt.Sprintf("skiplist_%v", i*10), func(b *testing.B) { 76 b.ReportAllocs() 77 b.ResetTimer() 78 table := []byte("default") 79 value := []byte{'v'} 80 var hits, misses, gets, sets int 81 b.RunParallel(func(pb *testing.PB) { 82 rng := rand.New(rand.NewSource(time.Now().UnixNano())) 83 buf := make([]byte, 8) 84 for pb.Next() { 85 var query *gdb.Query 86 var done chan gdb.QueryResponse 87 if rng.Float32() < readFrac { 88 query, done = gdb.NewGetValueQuery(ctx, table, randomKey(rng, buf)) 89 } else { 90 query, done = gdb.NewSetValueQuery(ctx, table, randomKey(rng, buf), value) 91 } 92 qp.Send(ctx, query) 93 select { 94 case <-ctx.Done(): 95 b.Error(ctx.Err()) 96 case result := <-done: 97 switch query.Header.Inst { 98 case gdb.GetRange, gdb.GetValue: 99 gets++ 100 if result.Success { 101 hits++ 102 } else { 103 misses++ 104 } 105 case gdb.SetValue: 106 sets++ 107 } 108 } 109 } 110 }) 111 b.ReportMetric(float64(hits), "hits") 112 b.ReportMetric(float64(misses), "misses") 113 b.ReportMetric(float64(gets), "gets") 114 b.ReportMetric(float64(sets), "sets") 115 }) 116 gproxy.StopProxy(ctx, qp) 117 cancel() 118 } 119 } 120 121 func randomKey(rng *rand.Rand, b []byte) []byte { 122 key := rng.Uint32() 123 key2 := rng.Uint32() 124 binary.LittleEndian.PutUint32(b, key) 125 binary.LittleEndian.PutUint32(b[4:], key2) 126 return b 127 }