blob: 5a3b2c89e62bd5960f293724f97867175e487d7a [file] [log] [blame]
Himabindu Pucha2752a7e2015-06-12 14:07:07 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vsync
6
7import (
8 "reflect"
9 "testing"
10 "time"
11
Raja Daoudd4543072015-06-30 11:15:55 -070012 _ "v.io/x/ref/runtime/factories/generic"
Adam Sadovskyf2efeb52015-08-31 14:17:49 -070013 "v.io/x/ref/services/syncbase/server/interfaces"
14 "v.io/x/ref/services/syncbase/store"
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070015)
16
17// Tests for sync state management and storage in Syncbase.
18
19// TestReserveGenAndPos tests reserving generation numbers and log positions in a
20// Database log.
21func TestReserveGenAndPos(t *testing.T) {
22 svc := createService(t)
Himabindu Pucha03ef3932015-06-26 17:56:09 -070023 defer destroyService(t, svc)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070024 s := svc.sync
25
Himabindu Puchab41fc142015-09-10 17:10:57 -070026 sgids := []string{"", "100", "200"}
27 for _, sgid := range sgids {
28 var wantGen, wantPos uint64 = 1, 0
29 for i := 0; i < 5; i++ {
30 gotGen, gotPos := s.reserveGenAndPosInternal("mockapp", "mockdb", sgid, 5, 10)
31 if gotGen != wantGen || gotPos != wantPos {
32 t.Fatalf("reserveGenAndPosInternal failed, gotGen %v wantGen %v, gotPos %v wantPos %v", gotGen, wantGen, gotPos, wantPos)
33 }
34 wantGen += 5
35 wantPos += 10
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070036
Himabindu Puchab41fc142015-09-10 17:10:57 -070037 name := appDbName("mockapp", "mockdb")
38 var info *localGenInfoInMem
39 if sgid == "" {
40 info = s.syncState[name].data
41 } else {
Himabindu Puchaf2796e12015-10-01 19:05:10 -070042 info = s.syncState[name].sgs[sgid]
Himabindu Puchab41fc142015-09-10 17:10:57 -070043 }
44 if info.gen != wantGen || info.pos != wantPos {
45 t.Fatalf("reserveGenAndPosInternal failed, gotGen %v wantGen %v, gotPos %v wantPos %v", info.gen, wantGen, info.pos, wantPos)
46 }
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070047 }
48 }
49}
50
51// TestPutGetDbSyncState tests setting and getting sync metadata.
52func TestPutGetDbSyncState(t *testing.T) {
53 svc := createService(t)
Himabindu Pucha03ef3932015-06-26 17:56:09 -070054 defer destroyService(t, svc)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070055 st := svc.St()
56
57 checkDbSyncState(t, st, false, nil)
58
59 gv := interfaces.GenVector{
60 "mocktbl/foo": interfaces.PrefixGenVector{
61 1: 2, 3: 4, 5: 6,
62 },
63 }
Himabindu Puchab41fc142015-09-10 17:10:57 -070064 sggv := interfaces.GenVector{
65 "mocksg1": interfaces.PrefixGenVector{
66 10: 20, 30: 40, 50: 60,
67 },
68 "mocksg2": interfaces.PrefixGenVector{
69 100: 200, 300: 400, 500: 600,
70 },
71 }
Himabindu Puchaf2796e12015-10-01 19:05:10 -070072 localsgs := make(map[string]localGenInfo)
73 localsgs["8888"] = localGenInfo{Gen: 56, CheckptGen: 2000}
74 localsgs["1008888"] = localGenInfo{Gen: 25890, CheckptGen: 100}
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070075
76 tx := st.NewTransaction()
Himabindu Puchab41fc142015-09-10 17:10:57 -070077 wantSt := &dbSyncState{
78 Data: localGenInfo{Gen: 40},
79 Sgs: localsgs,
80 GenVec: gv,
81 SgGenVec: sggv,
82 }
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070083 if err := putDbSyncState(nil, tx, wantSt); err != nil {
84 t.Fatalf("putDbSyncState failed, err %v", err)
85 }
86 if err := tx.Commit(); err != nil {
87 t.Fatalf("cannot commit putting db sync state, err %v", err)
88 }
89
90 checkDbSyncState(t, st, true, wantSt)
91}
92
93// TestPutGetDelLogRec tests setting, getting, and deleting a log record.
94func TestPutGetDelLogRec(t *testing.T) {
95 svc := createService(t)
Himabindu Pucha03ef3932015-06-26 17:56:09 -070096 defer destroyService(t, svc)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070097 st := svc.St()
98
99 var id uint64 = 10
100 var gen uint64 = 100
101
102 checkLogRec(t, st, id, gen, false, nil)
103
104 tx := st.NewTransaction()
105 wantRec := &localLogRec{
106 Metadata: interfaces.LogRecMetadata{
107 Id: id,
108 Gen: gen,
109 RecType: interfaces.NodeRec,
110 ObjId: "foo",
111 CurVers: "3",
112 Parents: []string{"1", "2"},
Himabindu Pucha53497022015-06-19 11:57:13 -0700113 UpdTime: time.Now().UTC(),
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700114 Delete: false,
115 BatchId: 10000,
116 BatchCount: 1,
117 },
118 Pos: 10,
119 }
Himabindu Puchab41fc142015-09-10 17:10:57 -0700120 if err := putLogRec(nil, tx, logDataPrefix, wantRec); err != nil {
121 t.Fatalf("putLogRec(%s:%d:%d) failed err %v", logDataPrefix, id, gen, err)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700122 }
123 if err := tx.Commit(); err != nil {
124 t.Fatalf("cannot commit putting log rec, err %v", err)
125 }
126
127 checkLogRec(t, st, id, gen, true, wantRec)
128
129 tx = st.NewTransaction()
Himabindu Puchab41fc142015-09-10 17:10:57 -0700130 if err := delLogRec(nil, tx, logDataPrefix, id, gen); err != nil {
131 t.Fatalf("delLogRec(%s:%d:%d) failed err %v", logDataPrefix, id, gen, err)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700132 }
133 if err := tx.Commit(); err != nil {
134 t.Fatalf("cannot commit deleting log rec, err %v", err)
135 }
136
137 checkLogRec(t, st, id, gen, false, nil)
138}
139
Himabindu Pucha0ff9b0c2015-07-14 11:40:45 -0700140func TestLogRecKeyUtils(t *testing.T) {
Himabindu Puchab41fc142015-09-10 17:10:57 -0700141 invalid := []string{"$sync:100:bb", "log:100:bb", "$sync:log:data:100:xx", "$sync:log:data:aa:bb", "$sync:log:xx:100:bb"}
Himabindu Pucha0ff9b0c2015-07-14 11:40:45 -0700142
143 for _, k := range invalid {
Himabindu Puchab41fc142015-09-10 17:10:57 -0700144 if _, _, _, err := splitLogRecKey(nil, k); err == nil {
Himabindu Pucha0ff9b0c2015-07-14 11:40:45 -0700145 t.Fatalf("splitting log rec key didn't fail %q", k)
146 }
147 }
148
149 valid := []struct {
Himabindu Puchab41fc142015-09-10 17:10:57 -0700150 pfx string
Himabindu Pucha0ff9b0c2015-07-14 11:40:45 -0700151 id uint64
152 gen uint64
153 }{
Himabindu Puchab41fc142015-09-10 17:10:57 -0700154 {logDataPrefix, 10, 20},
155 {"2500", 190, 540},
156 {"4200", 9999, 999999},
Himabindu Pucha0ff9b0c2015-07-14 11:40:45 -0700157 }
158
159 for _, v := range valid {
Himabindu Puchab41fc142015-09-10 17:10:57 -0700160 gotPfx, gotId, gotGen, err := splitLogRecKey(nil, logRecKey(v.pfx, v.id, v.gen))
161 if gotPfx != v.pfx || gotId != v.id || gotGen != v.gen || err != nil {
162 t.Fatalf("failed key conversion pfx got %v want %v, id got %v want %v, gen got %v want %v, err %v", gotPfx, v.pfx, gotId, v.id, gotGen, v.gen, err)
Himabindu Pucha0ff9b0c2015-07-14 11:40:45 -0700163 }
164 }
165}
166
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700167//////////////////////////////
168// Helpers
169
Adam Sadovsky6a6214f2015-09-03 18:20:18 -0700170// TODO(hpucha): Look into using v.io/x/ref/services/syncbase/testutil.Fatalf()
Himabindu Pucha53497022015-06-19 11:57:13 -0700171// for getting the stack trace. Right now cannot import the package due to a
172// cycle.
173
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700174func checkDbSyncState(t *testing.T, st store.StoreReader, exists bool, wantSt *dbSyncState) {
175 gotSt, err := getDbSyncState(nil, st)
176
177 if (!exists && err == nil) || (exists && err != nil) {
178 t.Fatalf("getDbSyncState failed, exists %v err %v", exists, err)
179 }
180
181 if !reflect.DeepEqual(gotSt, wantSt) {
182 t.Fatalf("getDbSyncState() failed, got %v, want %v", gotSt, wantSt)
183 }
184}
185
186func checkLogRec(t *testing.T, st store.StoreReader, id, gen uint64, exists bool, wantRec *localLogRec) {
Himabindu Puchab41fc142015-09-10 17:10:57 -0700187 gotRec, err := getLogRec(nil, st, logDataPrefix, id, gen)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700188
189 if (!exists && err == nil) || (exists && err != nil) {
190 t.Fatalf("getLogRec(%d:%d) failed, exists %v err %v", id, gen, exists, err)
191 }
192
193 if !reflect.DeepEqual(gotRec, wantRec) {
194 t.Fatalf("getLogRec(%d:%d) failed, got %v, want %v", id, gen, gotRec, wantRec)
195 }
196
Himabindu Puchab41fc142015-09-10 17:10:57 -0700197 if ok, err := hasLogRec(st, logDataPrefix, id, gen); err != nil || ok != exists {
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700198 t.Fatalf("hasLogRec(%d:%d) failed, want %v", id, gen, exists)
199 }
Himabindu Pucha53497022015-06-19 11:57:13 -0700200}