writebehind
2015-03-31
writebehind/writebehind_test.go
First pass implementation. Create our first implementation of this. Use a map of string=>int64 to store our values. The idea here is that users will create one cache for each metric they want to collect--each column that needs updating, in MySQL land. Release it under the MIT license, because why not? Very proud that the first commit carries 100% test coverage, no golint errors, no go vet errors, and has a benchmark.
| paddy@0 | 1 package writebehind |
| paddy@0 | 2 |
| paddy@0 | 3 import ( |
| paddy@0 | 4 "encoding/json" |
| paddy@0 | 5 "testing" |
| paddy@0 | 6 "time" |
| paddy@0 | 7 ) |
| paddy@0 | 8 |
| paddy@0 | 9 func TestSync(t *testing.T) { |
| paddy@0 | 10 m := MemoryIncrementer{} |
| paddy@0 | 11 c := NewCache(&m, time.Millisecond) |
| paddy@0 | 12 defer c.Stop() |
| paddy@0 | 13 c.Sync() // test that unnecessary sync is a no-op |
| paddy@0 | 14 c.Increment("test1", 10) |
| paddy@0 | 15 c.Increment("test2", 100) |
| paddy@0 | 16 time.Sleep(time.Millisecond) |
| paddy@0 | 17 if m.Get("test1") != 10 { |
| paddy@0 | 18 t.Errorf("Expected test1 to be %d, got %d", 10, m.values["test1"]) |
| paddy@0 | 19 } |
| paddy@0 | 20 if m.Get("test2") != 100 { |
| paddy@0 | 21 t.Errorf("Expected test2 to be %d, got %d", 100, m.values["test2"]) |
| paddy@0 | 22 } |
| paddy@0 | 23 c.Increment("test1", 10) |
| paddy@0 | 24 c.Increment("test2", 100) |
| paddy@0 | 25 time.Sleep(time.Millisecond) |
| paddy@0 | 26 if m.Get("test1") != 20 { |
| paddy@0 | 27 t.Errorf("Expected test1 to be %d, got %d", 20, m.values["test1"]) |
| paddy@0 | 28 } |
| paddy@0 | 29 if m.Get("test2") != 200 { |
| paddy@0 | 30 t.Errorf("Expected test2 to be %d, got %d", 200, m.values["test2"]) |
| paddy@0 | 31 } |
| paddy@0 | 32 } |
| paddy@0 | 33 |
| paddy@0 | 34 func TestString(t *testing.T) { |
| paddy@0 | 35 m := MemoryIncrementer{} |
| paddy@0 | 36 c := NewCache(&m, time.Millisecond) |
| paddy@0 | 37 defer c.Stop() |
| paddy@0 | 38 c.Increment("test1", 10) |
| paddy@0 | 39 c.Increment("test2", 100) |
| paddy@0 | 40 c.Increment(`"test3"`, 1000) |
| paddy@0 | 41 str := c.String() |
| paddy@0 | 42 var result map[string]int64 |
| paddy@0 | 43 err := json.Unmarshal([]byte(str), &result) |
| paddy@0 | 44 if err != nil { |
| paddy@0 | 45 t.Errorf("Error unmarshalling returned JSON: %#+v", err) |
| paddy@0 | 46 } |
| paddy@0 | 47 if result["test1"] != 10 { |
| paddy@0 | 48 t.Errorf("Expected test1 to be %d, got %d", 10, result["test1"]) |
| paddy@0 | 49 } |
| paddy@0 | 50 if result["test2"] != 100 { |
| paddy@0 | 51 t.Errorf("Expected test2 to be %d, got %d", 100, result["test2"]) |
| paddy@0 | 52 } |
| paddy@0 | 53 if result["\"test3\""] != 1000 { |
| paddy@0 | 54 t.Errorf("Expected \"test3\" to be %d, got %d", 1000, result["\"test3\""]) |
| paddy@0 | 55 } |
| paddy@0 | 56 } |
| paddy@0 | 57 |
| paddy@0 | 58 func BenchmarkSync(b *testing.B) { |
| paddy@0 | 59 m := MemoryIncrementer{} |
| paddy@0 | 60 c := NewCache(&m, time.Second*5) |
| paddy@0 | 61 defer c.Stop() |
| paddy@0 | 62 |
| paddy@0 | 63 b.RunParallel(func(pb *testing.PB) { |
| paddy@0 | 64 for pb.Next() { |
| paddy@0 | 65 c.Increment("myvalue", 1) |
| paddy@0 | 66 c.Increment("othervalue", 1) |
| paddy@0 | 67 c.Increment("other other value", 1) |
| paddy@0 | 68 c.Increment("weird value", 1) |
| paddy@0 | 69 } |
| paddy@0 | 70 }) |
| paddy@0 | 71 } |