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

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: Fix bad merge. 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_0000000000000000",
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_0000000000000001",
34 },
35 {
36 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
37 seq: 15,
38 id: "20010101T010101.100000000Z_000000000000000f",
39 },
40 {
41 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
42 seq: 16,
43 id: "20010101T010101.100000000Z_0000000000000010",
44 },
45 {
46 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
47 seq: 255,
48 id: "20010101T010101.100000000Z_00000000000000ff",
49 },
50 {
51 ts: time.Date(2001, time.January, 1, 1, 1, 1, 100000000 , time.UTC),
52 seq: 0xFFFFFFFFFFFFFFFF,
53 id: "20010101T010101.100000000Z_ffffffffffffffff",
54 },
55 }
56 for _, testCase := range testCases {
57 assert.Equal(t, testCase.id, formatId(testCase.ts, testCase.seq) )
58 ts, seq, err := parseId(testCase.id)
59 assert.NoError(t, err)
60 assert.True(t, testCase.ts.Equal(ts))
61 assert.Equal(t, testCase.seq, seq)
62 assert.Equal(t, time.UTC, ts.Location())
63 }
64
65 // Invalid timestamps:
66 for _, invalidId := range []string{
67 // Missing seq num.
68 "20091110T234506.000001500Z",
69 // Two-digit year.
70 "091110T234506.000001500Z_0000000000000000",
71 // Invalid month.
72 "20010001T010101.100000000Z_000000000000000f",
73 // Missing T.
74 "20010101010101.100000000Z_000000000000000f",
75 // Missing Z.
76 "20010101T010101.100000000_000000000000000f",
77 // Empty seq num.
78 "20010101T010101.100000000Z_",
79 // Invalid char in seq num.
80 "20010101T010101.100000000Z_000000000000000g",
81 // Invalid char in seq num.
82 "20010101T010101.100000000Z_g000000000000000",
83 // Empty timestamp.
84 "_000000000000000f",
85 // Sequence num overflows.
86 "20010101T010101.100000000Z_1ffffffffffffffff",
87 } {
88 _, _, err := parseId(invalidId)
89 assert.Error(t, err, "No error for Id: %q", invalidId)
90 }
91 }
92
93 // Create a localDB for testing. Call defer util.RemoveAll() on the second
94 // return value.
95 func makeDB(t *testing.T, name string) (db.DB, string) {
96 //testutils.SkipIfShort(t)
97 tmpdir, err := ioutil.TempDir("", name)
98 assert.NoError(t, err)
99 d, err := NewDB(name, filepath.Join(tmpdir, "task.db"))
100 assert.NoError(t, err)
101 return d, tmpdir
102 }
103
104 // Test that AssignId returns an error if Id is set.
105 func TestAssignIdAlreadyAssigned(t *testing.T) {
106 d, tmpdir := makeDB(t, "TestAssignIdsFromCreatedTs")
107 defer util.RemoveAll(tmpdir)
108 defer testutils.AssertCloses(t, d)
109
110 task := &db.Task{}
111 assert.NoError(t, d.AssignId(task))
112 assert.Error(t, d.AssignId(task))
113 }
114
115 // Test that AssignId uses created timestamp when set, and generates unique IDs
116 // for the same timestamp.
117 func TestAssignIdsFromCreatedTs(t *testing.T) {
118 d, tmpdir := makeDB(t, "TestAssignIdsFromCreatedTs")
119 defer util.RemoveAll(tmpdir)
120 defer testutils.AssertCloses(t, d)
121
122 tasks := []*db.Task{}
123 addTask := func(ts time.Time) {
124 task := &db.Task{
125 Created: ts,
126 }
127 assert.NoError(t, d.AssignId(task))
128 tasks = append(tasks, task)
129 }
130
131 // Add tasks with various creation timestamps.
132 addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC))
133 addTask(time.Date(1776, time.July, 4, 13, 0, 0, 0, time.UTC))
134 addTask(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC))
135 addTask(time.Date(2016, time.December, 31, 23, 59, 59, 999999999, time.U TC))
136 // Repeated timestamps.
137 addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC))
138 addTask(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC))
139 for i := 0; i < 256; i++ {
140 addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC))
141 }
142
143 // Collect IDs. Assert Id is set.
144 ids := make([]string, 0, len(tasks))
145 for _, task := range tasks {
146 assert.NotEqual(t, "", task.Id)
147 ids = append(ids, task.Id)
148 }
149
150 // Stable-sort tasks.
151 sort.Stable(db.TaskSlice(tasks))
152
153 // Sort IDs.
154 sort.Strings(ids)
155
156 // Validate that sorted IDs match sorted Tasks. Check that there are no
157 // duplicate IDs. Check that ID timestamp matches created timestamp.
158 prevId := ""
159 for i := 0; i < len(tasks); i++ {
160 assert.Equal(t, ids[i], tasks[i].Id)
161 assert.NotEqual(t, prevId, ids[i])
162 ts, _, err := parseId(ids[i])
163 assert.NoError(t, err)
164 assert.True(t, ts.Equal(tasks[i].Created))
165 prevId = ids[i]
166 }
167 }
168
169 // Test that AssignId can generate ids when created timestamp is not set, and
170 // generates unique IDs for PutTasks.
171 func TestAssignIdsFromCurrentTime(t *testing.T) {
172 d, tmpdir := makeDB(t, "TestAssignIdsFromCreatedTs")
173 defer util.RemoveAll(tmpdir)
174 defer testutils.AssertCloses(t, d)
175
176 tasks := []*db.Task{}
177 for i := 0; i < 260; i++ {
178 tasks = append(tasks, &db.Task{})
179 }
180
181 begin := time.Now()
182
183 // Test AssignId.
184 assert.NoError(t, d.AssignId(tasks[5]))
185 assert.NoError(t, d.AssignId(tasks[6]))
186 id5, id6 := tasks[5].Id, tasks[6].Id
187
188 // Test PutTasks.
189 assert.NoError(t, d.PutTasks(tasks))
190
191 end := time.Now()
192
193 // Check that PutTasks did not change existing Ids.
194 assert.Equal(t, id5, tasks[5].Id)
195 assert.Equal(t, id6, tasks[6].Id)
196
197 // Order tasks by time of ID assignment.
198 first2 := []*db.Task{tasks[5], tasks[6]}
199 copy(tasks[2:7], tasks[0:5])
200 copy(tasks[0:2], first2)
201
202 // Collect IDs. Assert Id is set.
203 ids := make([]string, 0, len(tasks))
204 for _, task := range tasks {
205 assert.NotEqual(t, "", task.Id)
206 ids = append(ids, task.Id)
207 }
208
209 // Sort IDs.
210 sort.Strings(ids)
211
212 // Validate that sorted IDs match Tasks by insertion order. Check that t here
213 // are no duplicate IDs. Check that begin <= ID timestamp <= end.
214 prevId := ""
215 for i := 0; i < len(tasks); i++ {
216 assert.Equal(t, ids[i], tasks[i].Id)
217 assert.NotEqual(t, prevId, ids[i])
218 ts, _, err := parseId(ids[i])
219 assert.NoError(t, err)
220 assert.True(t, begin.Before(ts) || begin.Equal(ts))
221 assert.True(t, ts.Before(end) || ts.Equal(end))
222 prevId = ids[i]
223 }
224 }
225
226 func TestLocalDB(t *testing.T) {
227 d, tmpdir := makeDB(t, "TestLocalDB")
228 defer util.RemoveAll(tmpdir)
229 db.TestDB(t, d)
230 }
231
232 func TestLocalDBTooManyUsers(t *testing.T) {
233 d, tmpdir := makeDB(t, "TestLocalDBTooManyUsers")
234 defer util.RemoveAll(tmpdir)
235 db.TestTooManyUsers(t, d)
236 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698