blob: 437a373f81ee04e4965ba5054d43bdef8cc24bce [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
12 "v.io/syncbase/x/ref/services/syncbase/server/interfaces"
13 "v.io/syncbase/x/ref/services/syncbase/store"
Raja Daoudd4543072015-06-30 11:15:55 -070014 _ "v.io/x/ref/runtime/factories/generic"
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
26 var wantGen, wantPos uint64 = 1, 0
27 for i := 0; i < 5; i++ {
28 gotGen, gotPos := s.reserveGenAndPosInternal("mockapp", "mockdb", 5, 10)
29 if gotGen != wantGen || gotPos != wantPos {
30 t.Fatalf("reserveGenAndPosInternal failed, gotGen %v wantGen %v, gotPos %v wantPos %v", gotGen, wantGen, gotPos, wantPos)
31 }
32 wantGen += 5
33 wantPos += 10
34
Raja Daoud28d3b602015-06-17 20:02:20 -070035 name := appDbName("mockapp", "mockdb")
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070036 if s.syncState[name].gen != wantGen || s.syncState[name].pos != wantPos {
37 t.Fatalf("reserveGenAndPosInternal failed, gotGen %v wantGen %v, gotPos %v wantPos %v", s.syncState[name].gen, wantGen, s.syncState[name].pos, wantPos)
38 }
39 }
40}
41
42// TestPutGetDbSyncState tests setting and getting sync metadata.
43func TestPutGetDbSyncState(t *testing.T) {
44 svc := createService(t)
Himabindu Pucha03ef3932015-06-26 17:56:09 -070045 defer destroyService(t, svc)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070046 st := svc.St()
47
48 checkDbSyncState(t, st, false, nil)
49
50 gv := interfaces.GenVector{
51 "mocktbl/foo": interfaces.PrefixGenVector{
52 1: 2, 3: 4, 5: 6,
53 },
54 }
55
56 tx := st.NewTransaction()
57 wantSt := &dbSyncState{Gen: 40, GenVec: gv}
58 if err := putDbSyncState(nil, tx, wantSt); err != nil {
59 t.Fatalf("putDbSyncState failed, err %v", err)
60 }
61 if err := tx.Commit(); err != nil {
62 t.Fatalf("cannot commit putting db sync state, err %v", err)
63 }
64
65 checkDbSyncState(t, st, true, wantSt)
66}
67
68// TestPutGetDelLogRec tests setting, getting, and deleting a log record.
69func TestPutGetDelLogRec(t *testing.T) {
70 svc := createService(t)
Himabindu Pucha03ef3932015-06-26 17:56:09 -070071 defer destroyService(t, svc)
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070072 st := svc.St()
73
74 var id uint64 = 10
75 var gen uint64 = 100
76
77 checkLogRec(t, st, id, gen, false, nil)
78
79 tx := st.NewTransaction()
80 wantRec := &localLogRec{
81 Metadata: interfaces.LogRecMetadata{
82 Id: id,
83 Gen: gen,
84 RecType: interfaces.NodeRec,
85 ObjId: "foo",
86 CurVers: "3",
87 Parents: []string{"1", "2"},
Himabindu Pucha53497022015-06-19 11:57:13 -070088 UpdTime: time.Now().UTC(),
Himabindu Pucha2752a7e2015-06-12 14:07:07 -070089 Delete: false,
90 BatchId: 10000,
91 BatchCount: 1,
92 },
93 Pos: 10,
94 }
95 if err := putLogRec(nil, tx, wantRec); err != nil {
96 t.Fatalf("putLogRec(%d:%d) failed err %v", id, gen, err)
97 }
98 if err := tx.Commit(); err != nil {
99 t.Fatalf("cannot commit putting log rec, err %v", err)
100 }
101
102 checkLogRec(t, st, id, gen, true, wantRec)
103
104 tx = st.NewTransaction()
105 if err := delLogRec(nil, tx, id, gen); err != nil {
106 t.Fatalf("delLogRec(%d:%d) failed err %v", id, gen, err)
107 }
108 if err := tx.Commit(); err != nil {
109 t.Fatalf("cannot commit deleting log rec, err %v", err)
110 }
111
112 checkLogRec(t, st, id, gen, false, nil)
113}
114
115//////////////////////////////
116// Helpers
117
Himabindu Pucha53497022015-06-19 11:57:13 -0700118// TODO(hpucha): Look into using v.io/syncbase/v23/syncbase/testutil.Fatalf()
119// for getting the stack trace. Right now cannot import the package due to a
120// cycle.
121
Himabindu Pucha2752a7e2015-06-12 14:07:07 -0700122func checkDbSyncState(t *testing.T, st store.StoreReader, exists bool, wantSt *dbSyncState) {
123 gotSt, err := getDbSyncState(nil, st)
124
125 if (!exists && err == nil) || (exists && err != nil) {
126 t.Fatalf("getDbSyncState failed, exists %v err %v", exists, err)
127 }
128
129 if !reflect.DeepEqual(gotSt, wantSt) {
130 t.Fatalf("getDbSyncState() failed, got %v, want %v", gotSt, wantSt)
131 }
132}
133
134func checkLogRec(t *testing.T, st store.StoreReader, id, gen uint64, exists bool, wantRec *localLogRec) {
135 gotRec, err := getLogRec(nil, st, id, gen)
136
137 if (!exists && err == nil) || (exists && err != nil) {
138 t.Fatalf("getLogRec(%d:%d) failed, exists %v err %v", id, gen, exists, err)
139 }
140
141 if !reflect.DeepEqual(gotRec, wantRec) {
142 t.Fatalf("getLogRec(%d:%d) failed, got %v, want %v", id, gen, gotRec, wantRec)
143 }
144
145 if hasLogRec(st, id, gen) != exists {
146 t.Fatalf("hasLogRec(%d:%d) failed, want %v", id, gen, exists)
147 }
Himabindu Pucha53497022015-06-19 11:57:13 -0700148}