Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: build_scheduler/go/db/local_db/local_db_test.go

Issue 2246933002: Add Task DB implementation using a local BoltDB. (Closed) Base URL: https://skia.googlesource.com/buildbot@taskdb-impl-track
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 package local_db
2
3 import (
4 "io/ioutil"
5 "path/filepath"
6 "sort"
7 "testing"
8 "time"
9
10 assert "github.com/stretchr/testify/require"
11 "go.skia.org/infra/build_scheduler/go/db"
12 "go.skia.org/infra/go/testutils"
13 "go.skia.org/infra/go/util"
14 )
15
16 // Check that formatId and parseId are inverse operations and produce the
17 // expected result.
18 func TestFormatParseId(t *testing.T) {
19 testCases := []struct {
20 ts time.Time
21 seq uint64
22 id string
23 }{
24 {
25 ts: time.Date(2009, time.November, 10, 23, 45, 6, 1500, time.UTC),
26 seq: 0,
27 id: "20091110T234506.000001500Z_00",
28 },
29 {
30 ts: time.Date(2001, time.February, 3, 4, 5, 6, 0, time. FixedZone("fake", 45*60)),
31 seq: 1,
32 // Subtract 45 minutes due to zone.
33 id: "20010203T032006.000000000Z_01",
34 },
35 {
36 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
37 seq: 15,
38 id: "20010101T010101.100000000Z_0f",
39 },
40 {
41 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
42 seq: 16,
43 id: "20010101T010101.100000000Z_110",
44 },
45 {
46 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
47 seq: 255,
48 id: "20010101T010101.100000000Z_1ff",
49 },
50 {
51 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
52 seq: 256,
53 id: "20010101T010101.100000000Z_2100",
54 },
55 {
56 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
57 seq: 0xFFFFFFFFFFFFFFFF,
58 id: "20010101T010101.100000000Z_fffffffffffffffff",
59 },
60 }
61 for _, testCase := range testCases {
62 assert.Equal(t, testCase.id, formatId(testCase.ts, testCase.seq) )
63 ts, seq, err := parseId(testCase.id)
64 assert.NoError(t, err)
65 assert.True(t, testCase.ts.Equal(ts))
66 assert.Equal(t, testCase.seq, seq)
67 assert.Equal(t, time.UTC, ts.Location())
68 }
69
70 // Invalid timestamps:
71 for _, invalidId := range []string{
72 // Missing seq num.
73 "20091110T234506.000001500Z",
74 // Two-digit year.
75 "091110T234506.000001500Z_00",
76 // Invalid month.
77 "20010001T010101.100000000Z_0f",
78 // Missing T.
79 "20010101010101.100000000Z_0f",
80 // Missing Z.
81 "20010101T010101.100000000_0f",
82 // Empty seq num.
83 "20010101T010101.100000000Z_",
84 // Seq num too short.
85 "20010101T010101.100000000Z_0",
86 // Invalid char in seq num.
87 "20010101T010101.100000000Z_0g",
88 // Empty timestamp.
89 "_0F",
90 // Sequence num overflows.
91 "20010101T010101.100000000Z_f1ffffffffffffffff",
92 } {
93 _, _, err := parseId(invalidId)
94 assert.Error(t, err)
95 }
96 }
97
98 // Create a localDB for testing. Call defer util.RemoveAll() on the second
99 // return value.
100 func makeDB(t *testing.T, name string) (db.DB, string) {
101 //testutils.SkipIfShort(t)
102 tmpdir, err := ioutil.TempDir("", name)
103 assert.NoError(t, err)
104 d, err := NewDB(name, filepath.Join(tmpdir, "task.db"))
105 assert.NoError(t, err)
106 return d, tmpdir
107 }
108
109 // Test that AssignId returns an error if Id is set.
110 func TestAssignIdAlreadyAssigned(t *testing.T) {
111 d, tmpdir := makeDB(t, "TestAssignIdsFromCreatedTs")
112 defer util.RemoveAll(tmpdir)
113 defer testutils.AssertCloses(t, d)
114
115 task := &db.Task{}
116 assert.NoError(t, d.AssignId(task))
117 assert.Error(t, d.AssignId(task))
118 }
119
120 // Test that AssignId uses created timestamp when set, and generates unique IDs
121 // for the same timestamp.
122 func TestAssignIdsFromCreatedTs(t *testing.T) {
123 d, tmpdir := makeDB(t, "TestAssignIdsFromCreatedTs")
124 defer util.RemoveAll(tmpdir)
125 defer testutils.AssertCloses(t, d)
126
127 tasks := []*db.Task{}
128 addTask := func(ts time.Time) {
129 task := &db.Task{
130 Created: ts,
131 }
132 assert.NoError(t, d.AssignId(task))
133 tasks = append(tasks, task)
134 }
135
136 // Add tasks with various creation timestamps.
137 addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC))
138 addTask(time.Date(1776, time.July, 4, 13, 0, 0, 0, time.UTC))
139 addTask(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC))
140 addTask(time.Date(2016, time.December, 31, 23, 59, 59, 999999999, time.U TC))
141 // Repeated timestamps.
142 addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC))
143 addTask(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC))
144 for i := 0; i < 256; i++ {
145 addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC))
146 }
147
148 // Collect IDs. Assert Id is set.
149 ids := make([]string, 0, len(tasks))
150 for _, task := range tasks {
151 assert.NotEqual(t, "", task.Id)
152 ids = append(ids, task.Id)
153 }
154
155 // Stable-sort tasks.
156 sort.Stable(db.TaskSlice(tasks))
157
158 // Sort IDs.
159 sort.Strings(ids)
160
161 // Validate that sorted IDs match sorted Tasks. Check that there are no
162 // duplicate IDs. Check that ID timestamp matches created timestamp.
163 prevId := ""
164 for i := 0; i < len(tasks); i++ {
165 assert.Equal(t, ids[i], tasks[i].Id)
166 assert.NotEqual(t, prevId, ids[i])
167 ts, _, err := parseId(ids[i])
168 assert.NoError(t, err)
169 assert.True(t, ts.Equal(tasks[i].Created))
170 prevId = ids[i]
171 }
172 }
173
174 // Test that AssignId can generate ids when created timestamp is not set, and
175 // generates unique IDs for PutTasks.
176 func TestAssignIdsFromCurrentTime(t *testing.T) {
177 d, tmpdir := makeDB(t, "TestAssignIdsFromCreatedTs")
178 defer util.RemoveAll(tmpdir)
179 defer testutils.AssertCloses(t, d)
180
181 tasks := []*db.Task{}
182 for i := 0; i < 260; i++ {
183 tasks = append(tasks, &db.Task{})
184 }
185
186 begin := time.Now()
187
188 // Test AssignId.
189 assert.NoError(t, d.AssignId(tasks[5]))
190 assert.NoError(t, d.AssignId(tasks[6]))
191 id5, id6 := tasks[5].Id, tasks[6].Id
192
193 // Test PutTasks.
194 assert.NoError(t, d.PutTasks(tasks))
195
196 end := time.Now()
197
198 // Check that PutTasks did not change existing Ids.
199 assert.Equal(t, id5, tasks[5].Id)
200 assert.Equal(t, id6, tasks[6].Id)
201
202 // Order tasks by time of ID assignment.
203 first2 := []*db.Task{tasks[5], tasks[6]}
204 copy(tasks[2:7], tasks[0:5])
205 copy(tasks[0:2], first2)
206
207 // Collect IDs. Assert Id is set.
208 ids := make([]string, 0, len(tasks))
209 for _, task := range tasks {
210 assert.NotEqual(t, "", task.Id)
211 ids = append(ids, task.Id)
212 }
213
214 // Sort IDs.
215 sort.Strings(ids)
216
217 // Validate that sorted IDs match Tasks by insertion order. Check that t here
218 // are no duplicate IDs. Check that begin <= ID timestamp <= end.
219 prevId := ""
220 for i := 0; i < len(tasks); i++ {
221 assert.Equal(t, ids[i], tasks[i].Id)
222 assert.NotEqual(t, prevId, ids[i])
223 ts, _, err := parseId(ids[i])
224 assert.NoError(t, err)
225 assert.True(t, begin.Before(ts) || begin.Equal(ts))
226 assert.True(t, ts.Before(end) || ts.Equal(end))
227 prevId = ids[i]
228 }
229 }
230
231 func TestLocalDB(t *testing.T) {
232 d, tmpdir := makeDB(t, "TestLocalDB")
233 defer util.RemoveAll(tmpdir)
234 db.TestDB(t, d)
235 }
236
237 func TestLocalDBTooManyUsers(t *testing.T) {
238 d, tmpdir := makeDB(t, "TestLocalDBTooManyUsers")
239 defer util.RemoveAll(tmpdir)
240 db.TestTooManyUsers(t, d)
241 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698