blob: 16bc176afa2a3dbd4aec4ded81c85576296458a9 [file] [log] [blame]
Sabina Leaverc5fd2772022-01-29 17:00:23 -08001package db
2
3import (
Philipp Schrader83fc2722022-03-10 21:59:20 -08004 "fmt"
Philipp Schrader7365d322022-03-06 16:40:08 -08005 "log"
Philipp Schrader4953cc32022-02-25 18:09:02 -08006 "os"
Philipp Schrader7365d322022-03-06 16:40:08 -08007 "os/exec"
Sabina Leaverc5fd2772022-01-29 17:00:23 -08008 "reflect"
9 "testing"
Philipp Schrader7365d322022-03-06 16:40:08 -080010 "time"
Sabina Leaverc5fd2772022-01-29 17:00:23 -080011)
12
Philipp Schrader83fc2722022-03-10 21:59:20 -080013// Shortcut for error checking. If the specified error is non-nil, print the
14// error message and exit the test.
15func check(t *testing.T, err error, message string) {
16 if err != nil {
17 t.Fatal(message, ":", err)
18 }
19}
20
Philipp Schrader7365d322022-03-06 16:40:08 -080021type dbFixture struct {
22 db *Database
23 server *exec.Cmd
24}
25
26func (fixture dbFixture) TearDown() {
27 fixture.db.Delete()
28 fixture.db.Close()
29 log.Println("Shutting down testdb")
30 fixture.server.Process.Signal(os.Interrupt)
31 fixture.server.Process.Wait()
32 log.Println("Successfully shut down testdb")
33}
34
35func createDatabase(t *testing.T) dbFixture {
36 var fixture dbFixture
37
38 log.Println("Starting up postgres.")
39 fixture.server = exec.Command("testdb_server/testdb_server_/testdb_server")
40 fixture.server.Stdout = os.Stdout
41 fixture.server.Stderr = os.Stderr
42 err := fixture.server.Start()
43 check(t, err, "Failed to run postgres")
44
45 // Wait until the server is ready. We cannot rely on the TCP socket
46 // alone because postgres creates the socket before it's actually ready
47 // to service requests.
48 for {
49 fixture.db, err = NewDatabase("test", "password", 5432)
50 if err == nil {
51 break
52 }
53 time.Sleep(50 * time.Millisecond)
54 }
55 log.Println("Connected to postgres.")
56
57 return fixture
Philipp Schrader4953cc32022-02-25 18:09:02 -080058}
59
60func TestAddToMatchDB(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -080061 fixture := createDatabase(t)
62 defer fixture.TearDown()
Philipp Schrader4953cc32022-02-25 18:09:02 -080063
Philipp Schrader83fc2722022-03-10 21:59:20 -080064 correct := []Match{
65 Match{
66 MatchNumber: 7,
67 Round: 1,
68 CompLevel: "quals",
69 R1: 9999, R2: 1000, R3: 777, B1: 0000, B2: 4321, B3: 1234,
70 r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
71 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -080072 }
Philipp Schrader83fc2722022-03-10 21:59:20 -080073
Philipp Schrader7365d322022-03-06 16:40:08 -080074 err := fixture.db.AddToMatch(correct[0])
Philipp Schrader83fc2722022-03-10 21:59:20 -080075 check(t, err, "Failed to add match data")
76
Philipp Schrader7365d322022-03-06 16:40:08 -080077 got, err := fixture.db.ReturnMatches()
Philipp Schrader83fc2722022-03-10 21:59:20 -080078 check(t, err, "Failed ReturnMatches()")
79
Sabina Leaverc5fd2772022-01-29 17:00:23 -080080 if !reflect.DeepEqual(correct, got) {
81 t.Fatalf("Got %#v,\nbut expected %#v.", got, correct)
82 }
Sabina Leaverc5fd2772022-01-29 17:00:23 -080083}
84
85func TestAddToStatsDB(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -080086 fixture := createDatabase(t)
87 defer fixture.TearDown()
Philipp Schrader4953cc32022-02-25 18:09:02 -080088
Sabina Leaverc5fd2772022-01-29 17:00:23 -080089 correct := []Stats{
Philipp Schrader83fc2722022-03-10 21:59:20 -080090 Stats{
91 TeamNumber: 1236, MatchNumber: 7,
92 ShotsMissed: 9, UpperGoalShots: 5, LowerGoalShots: 4,
93 ShotsMissedAuto: 3, UpperGoalAuto: 2, LowerGoalAuto: 1,
94 PlayedDefense: 2, Climbing: 3,
95 },
96 Stats{
97 TeamNumber: 1001, MatchNumber: 7,
98 ShotsMissed: 6, UpperGoalShots: 9, LowerGoalShots: 9,
99 ShotsMissedAuto: 0, UpperGoalAuto: 0, LowerGoalAuto: 0,
100 PlayedDefense: 0, Climbing: 0,
101 },
102 Stats{
103 TeamNumber: 777, MatchNumber: 7,
104 ShotsMissed: 5, UpperGoalShots: 7, LowerGoalShots: 12,
105 ShotsMissedAuto: 0, UpperGoalAuto: 4, LowerGoalAuto: 0,
106 PlayedDefense: 0, Climbing: 0,
107 },
108 Stats{
109 TeamNumber: 1000, MatchNumber: 7,
110 ShotsMissed: 12, UpperGoalShots: 6, LowerGoalShots: 10,
111 ShotsMissedAuto: 0, UpperGoalAuto: 7, LowerGoalAuto: 0,
112 PlayedDefense: 0, Climbing: 0,
113 },
114 Stats{
115 TeamNumber: 4321, MatchNumber: 7,
116 ShotsMissed: 14, UpperGoalShots: 12, LowerGoalShots: 3,
117 ShotsMissedAuto: 0, UpperGoalAuto: 7, LowerGoalAuto: 0,
118 PlayedDefense: 0, Climbing: 0,
119 },
120 Stats{
121 TeamNumber: 1234, MatchNumber: 7,
122 ShotsMissed: 3, UpperGoalShots: 4, LowerGoalShots: 0,
123 ShotsMissedAuto: 0, UpperGoalAuto: 9, LowerGoalAuto: 0,
124 PlayedDefense: 0, Climbing: 0,
125 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800126 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800127
Philipp Schrader7365d322022-03-06 16:40:08 -0800128 err := fixture.db.AddToMatch(Match{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800129 MatchNumber: 7, Round: 1, CompLevel: "quals",
130 R1: 1236, R2: 1001, R3: 777, B1: 1000, B2: 4321, B3: 1234,
Philipp Schrader7365d322022-03-06 16:40:08 -0800131 r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
132 })
Philipp Schrader83fc2722022-03-10 21:59:20 -0800133 check(t, err, "Failed to add match")
134
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800135 for i := 0; i < len(correct); i++ {
Philipp Schrader7365d322022-03-06 16:40:08 -0800136 err = fixture.db.AddToStats(correct[i])
Philipp Schrader83fc2722022-03-10 21:59:20 -0800137 check(t, err, "Failed to add stats to DB")
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800138 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800139
Philipp Schrader7365d322022-03-06 16:40:08 -0800140 got, err := fixture.db.ReturnStats()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800141 check(t, err, "Failed ReturnStats()")
142
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800143 if !reflect.DeepEqual(correct, got) {
144 t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
145 }
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800146}
147
148func TestQueryMatchDB(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -0800149 fixture := createDatabase(t)
150 defer fixture.TearDown()
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800151
152 testDatabase := []Match{
Philipp Schrader1e6c0a92022-02-27 23:30:57 -0800153 Match{MatchNumber: 2, Round: 1, CompLevel: "quals", R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149},
154 Match{MatchNumber: 4, Round: 1, CompLevel: "quals", R1: 198, R2: 135, R3: 777, B1: 999, B2: 434, B3: 698},
155 Match{MatchNumber: 3, Round: 1, CompLevel: "quals", R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262},
156 Match{MatchNumber: 6, Round: 1, CompLevel: "quals", R1: 191, R2: 132, R3: 773, B1: 994, B2: 435, B3: 696},
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800157 }
158
159 for i := 0; i < len(testDatabase); i++ {
Philipp Schrader7365d322022-03-06 16:40:08 -0800160 err := fixture.db.AddToMatch(testDatabase[i])
Philipp Schrader83fc2722022-03-10 21:59:20 -0800161 check(t, err, fmt.Sprint("Failed to add match", i))
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800162 }
163
164 correct := []Match{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800165 Match{
166 MatchNumber: 2, Round: 1, CompLevel: "quals",
167 R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149,
168 r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
169 },
170 Match{
171 MatchNumber: 3, Round: 1, CompLevel: "quals",
172 R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262,
173 r1ID: 13, r2ID: 14, r3ID: 15, b1ID: 16, b2ID: 17, b3ID: 18,
174 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800175 }
176
Philipp Schrader7365d322022-03-06 16:40:08 -0800177 got, err := fixture.db.QueryMatches(538)
Philipp Schrader83fc2722022-03-10 21:59:20 -0800178 check(t, err, "Failed to query matches for 538")
179
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800180 if !reflect.DeepEqual(correct, got) {
181 t.Fatalf("Got %#v,\nbut expected %#v.", got, correct)
182 }
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800183}
184
185func TestQueryStatsDB(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -0800186 fixture := createDatabase(t)
187 defer fixture.TearDown()
Philipp Schrader4953cc32022-02-25 18:09:02 -0800188
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800189 testDatabase := []Stats{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800190 Stats{
191 TeamNumber: 1235, MatchNumber: 94,
192 ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2,
193 ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2,
194 PlayedDefense: 2, Climbing: 2},
195 Stats{
196 TeamNumber: 1234, MatchNumber: 94,
197 ShotsMissed: 4, UpperGoalShots: 4, LowerGoalShots: 4,
198 ShotsMissedAuto: 4, UpperGoalAuto: 4, LowerGoalAuto: 4,
199 PlayedDefense: 7, Climbing: 2,
200 },
201 Stats{
202 TeamNumber: 1233, MatchNumber: 94,
203 ShotsMissed: 3, UpperGoalShots: 3, LowerGoalShots: 3,
204 ShotsMissedAuto: 3, UpperGoalAuto: 3, LowerGoalAuto: 3,
205 PlayedDefense: 3, Climbing: 3,
206 },
207 Stats{
208 TeamNumber: 1232, MatchNumber: 94,
209 ShotsMissed: 5, UpperGoalShots: 5, LowerGoalShots: 5,
210 ShotsMissedAuto: 5, UpperGoalAuto: 5, LowerGoalAuto: 5,
211 PlayedDefense: 7, Climbing: 1,
212 },
213 Stats{
214 TeamNumber: 1231, MatchNumber: 94,
215 ShotsMissed: 6, UpperGoalShots: 6, LowerGoalShots: 6,
216 ShotsMissedAuto: 6, UpperGoalAuto: 6, LowerGoalAuto: 6,
217 PlayedDefense: 7, Climbing: 1,
218 },
219 Stats{
220 TeamNumber: 1239, MatchNumber: 94,
221 ShotsMissed: 7, UpperGoalShots: 7, LowerGoalShots: 7,
222 ShotsMissedAuto: 7, UpperGoalAuto: 7, LowerGoalAuto: 3,
223 PlayedDefense: 7, Climbing: 1,
224 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800225 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800226
Philipp Schrader7365d322022-03-06 16:40:08 -0800227 err := fixture.db.AddToMatch(Match{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800228 MatchNumber: 94, Round: 1, CompLevel: "quals",
229 R1: 1235, R2: 1234, R3: 1233, B1: 1232, B2: 1231, B3: 1239})
230 check(t, err, "Failed to add match")
231
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800232 for i := 0; i < len(testDatabase); i++ {
Philipp Schrader7365d322022-03-06 16:40:08 -0800233 err = fixture.db.AddToStats(testDatabase[i])
Philipp Schrader83fc2722022-03-10 21:59:20 -0800234 check(t, err, fmt.Sprint("Failed to add stats", i))
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800235 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800236
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800237 correct := []Stats{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800238 Stats{
239 TeamNumber: 1235, MatchNumber: 94,
240 ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2,
241 ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2,
242 PlayedDefense: 2, Climbing: 2,
243 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800244 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800245
Philipp Schrader7365d322022-03-06 16:40:08 -0800246 got, err := fixture.db.QueryStats(1235)
Philipp Schrader83fc2722022-03-10 21:59:20 -0800247 check(t, err, "Failed QueryStats()")
248
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800249 if !reflect.DeepEqual(correct, got) {
250 t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
251 }
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800252}
253
254func TestReturnMatchDB(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -0800255 fixture := createDatabase(t)
256 defer fixture.TearDown()
Philipp Schrader4953cc32022-02-25 18:09:02 -0800257
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800258 correct := []Match{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800259 Match{
260 MatchNumber: 2, Round: 1, CompLevel: "quals",
261 R1: 251, R2: 169, R3: 286, B1: 253, B2: 538, B3: 149,
262 r1ID: 1, r2ID: 2, r3ID: 3, b1ID: 4, b2ID: 5, b3ID: 6,
263 },
264 Match{
265 MatchNumber: 3, Round: 1, CompLevel: "quals",
266 R1: 147, R2: 421, R3: 538, B1: 126, B2: 448, B3: 262,
267 r1ID: 7, r2ID: 8, r3ID: 9, b1ID: 10, b2ID: 11, b3ID: 12,
268 },
269 Match{
270 MatchNumber: 4, Round: 1, CompLevel: "quals",
271 R1: 251, R2: 169, R3: 286, B1: 653, B2: 538, B3: 149,
272 r1ID: 13, r2ID: 14, r3ID: 15, b1ID: 16, b2ID: 17, b3ID: 18,
273 },
274 Match{
275 MatchNumber: 5, Round: 1, CompLevel: "quals",
276 R1: 198, R2: 1421, R3: 538, B1: 26, B2: 448, B3: 262,
277 r1ID: 19, r2ID: 20, r3ID: 21, b1ID: 22, b2ID: 23, b3ID: 24,
278 },
279 Match{
280 MatchNumber: 6, Round: 1, CompLevel: "quals",
281 R1: 251, R2: 188, R3: 286, B1: 555, B2: 538, B3: 149,
282 r1ID: 25, r2ID: 26, r3ID: 27, b1ID: 28, b2ID: 29, b3ID: 30,
283 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800284 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800285
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800286 for i := 0; i < len(correct); i++ {
Philipp Schrader7365d322022-03-06 16:40:08 -0800287 err := fixture.db.AddToMatch(correct[i])
Philipp Schrader83fc2722022-03-10 21:59:20 -0800288 check(t, err, fmt.Sprint("Failed to add match", i))
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800289 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800290
Philipp Schrader7365d322022-03-06 16:40:08 -0800291 got, err := fixture.db.ReturnMatches()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800292 check(t, err, "Failed ReturnMatches()")
293
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800294 if !reflect.DeepEqual(correct, got) {
295 t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
296 }
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800297}
298
299func TestReturnStatsDB(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -0800300 fixture := createDatabase(t)
301 defer fixture.TearDown()
Philipp Schrader4953cc32022-02-25 18:09:02 -0800302
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800303 correct := []Stats{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800304 Stats{
305 TeamNumber: 1235, MatchNumber: 94,
306 ShotsMissed: 2, UpperGoalShots: 2, LowerGoalShots: 2,
307 ShotsMissedAuto: 2, UpperGoalAuto: 2, LowerGoalAuto: 2,
308 PlayedDefense: 2, Climbing: 2,
309 },
310 Stats{
311 TeamNumber: 1236, MatchNumber: 94,
312 ShotsMissed: 4, UpperGoalShots: 4, LowerGoalShots: 4,
313 ShotsMissedAuto: 4, UpperGoalAuto: 4, LowerGoalAuto: 4,
314 PlayedDefense: 7, Climbing: 2,
315 },
316 Stats{
317 TeamNumber: 1237, MatchNumber: 94,
318 ShotsMissed: 3, UpperGoalShots: 3, LowerGoalShots: 3,
319 ShotsMissedAuto: 3, UpperGoalAuto: 3, LowerGoalAuto: 3,
320 PlayedDefense: 3, Climbing: 3,
321 },
322 Stats{
323 TeamNumber: 1238, MatchNumber: 94,
324 ShotsMissed: 5, UpperGoalShots: 5, LowerGoalShots: 5,
325 ShotsMissedAuto: 5, UpperGoalAuto: 5, LowerGoalAuto: 5,
326 PlayedDefense: 7, Climbing: 1,
327 },
328 Stats{
329 TeamNumber: 1239, MatchNumber: 94,
330 ShotsMissed: 6, UpperGoalShots: 6, LowerGoalShots: 6,
331 ShotsMissedAuto: 6, UpperGoalAuto: 6, LowerGoalAuto: 6,
332 PlayedDefense: 7, Climbing: 1,
333 },
334 Stats{
335 TeamNumber: 1233, MatchNumber: 94,
336 ShotsMissed: 7, UpperGoalShots: 7, LowerGoalShots: 7,
337 ShotsMissedAuto: 7, UpperGoalAuto: 7, LowerGoalAuto: 3,
338 PlayedDefense: 7, Climbing: 1,
339 },
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800340 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800341
Philipp Schrader7365d322022-03-06 16:40:08 -0800342 err := fixture.db.AddToMatch(Match{
Philipp Schrader83fc2722022-03-10 21:59:20 -0800343 MatchNumber: 94, Round: 1, CompLevel: "quals",
344 R1: 1235, R2: 1236, R3: 1237, B1: 1238, B2: 1239, B3: 1233})
345 check(t, err, "Failed to add match")
346
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800347 for i := 0; i < len(correct); i++ {
Philipp Schrader7365d322022-03-06 16:40:08 -0800348 err = fixture.db.AddToStats(correct[i])
Philipp Schrader83fc2722022-03-10 21:59:20 -0800349 check(t, err, fmt.Sprint("Failed to add stats", i))
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800350 }
Philipp Schrader83fc2722022-03-10 21:59:20 -0800351
Philipp Schrader7365d322022-03-06 16:40:08 -0800352 got, err := fixture.db.ReturnStats()
Philipp Schrader83fc2722022-03-10 21:59:20 -0800353 check(t, err, "Failed ReturnStats()")
354
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800355 if !reflect.DeepEqual(correct, got) {
356 t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
357 }
Sabina Leaverc5fd2772022-01-29 17:00:23 -0800358}
Alex Perry871eab92022-03-12 17:43:52 -0800359
360func TestNotes(t *testing.T) {
Philipp Schrader7365d322022-03-06 16:40:08 -0800361 fixture := createDatabase(t)
362 defer fixture.TearDown()
Alex Perry871eab92022-03-12 17:43:52 -0800363
364 expected := NotesData{
365 TeamNumber: 1234,
366 Notes: []string{"Note 1", "Note 3"},
367 }
368
Philipp Schrader7365d322022-03-06 16:40:08 -0800369 err := fixture.db.AddNotes(NotesData{1234, []string{"Note 1"}})
Alex Perry871eab92022-03-12 17:43:52 -0800370 check(t, err, "Failed to add Note")
Philipp Schrader7365d322022-03-06 16:40:08 -0800371 err = fixture.db.AddNotes(NotesData{1235, []string{"Note 2"}})
Alex Perry871eab92022-03-12 17:43:52 -0800372 check(t, err, "Failed to add Note")
Philipp Schrader7365d322022-03-06 16:40:08 -0800373 err = fixture.db.AddNotes(NotesData{1234, []string{"Note 3"}})
Alex Perry871eab92022-03-12 17:43:52 -0800374 check(t, err, "Failed to add Note")
375
Philipp Schrader7365d322022-03-06 16:40:08 -0800376 actual, err := fixture.db.QueryNotes(1234)
Alex Perry871eab92022-03-12 17:43:52 -0800377 check(t, err, "Failed to get Notes")
378
379 if !reflect.DeepEqual(expected, actual) {
380 t.Errorf("Got %#v,\nbut expected %#v.", actual, expected)
381 }
382}