-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgol_test.go
129 lines (113 loc) · 2.89 KB
/
gol_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"fmt"
"io/ioutil"
"strconv"
"strings"
"testing"
"uk.ac.bris.cs/gameoflife/gol"
"uk.ac.bris.cs/gameoflife/util"
)
// TestGol tests 16x16, 64x64 and 512x512 images on 0, 1 and 100 turns using 1-16 worker threads.
func TestGol(t *testing.T) {
tests := []gol.Params{
{ImageWidth: 16, ImageHeight: 16},
{ImageWidth: 64, ImageHeight: 64},
{ImageWidth: 512, ImageHeight: 512},
}
for _, p := range tests {
for _, turns := range []int{0, 1, 100} {
p.Turns = turns
expectedAlive := readAliveCells(
"check/images/"+fmt.Sprintf("%vx%vx%v.pgm", p.ImageWidth, p.ImageHeight, turns),
p.ImageWidth,
p.ImageHeight,
)
for threads := 1; threads <= 16; threads++ {
p.Threads = threads
testName := fmt.Sprintf("%dx%dx%d-%d", p.ImageWidth, p.ImageHeight, p.Turns, p.Threads)
t.Run(testName, func(t *testing.T) {
events := make(chan gol.Event)
go gol.Run(p, events, nil)
var cells []util.Cell
for event := range events {
switch e := event.(type) {
case gol.FinalTurnComplete:
cells = e.Alive
}
}
assertEqualBoard(t, cells, expectedAlive, p)
})
}
}
}
}
func boardFail(t *testing.T, given, expected []util.Cell, p gol.Params) bool {
errorString := fmt.Sprintf("-----------------\n\n FAILED TEST\n %vx%v\n %d Workers\n %d Turns\n", p.ImageWidth, p.ImageHeight, p.Threads, p.Turns)
if p.ImageWidth == 16 && p.ImageHeight == 16 {
errorString = errorString + util.AliveCellsToString(given, expected, p.ImageWidth, p.ImageHeight)
}
t.Error(errorString)
return false
}
func assertEqualBoard(t *testing.T, given, expected []util.Cell, p gol.Params) bool {
givenLen := len(given)
expectedLen := len(expected)
if givenLen != expectedLen {
return boardFail(t, given, expected, p)
}
visited := make([]bool, expectedLen)
for i := 0; i < givenLen; i++ {
element := given[i]
found := false
for j := 0; j < expectedLen; j++ {
if visited[j] {
continue
}
if expected[j] == element {
visited[j] = true
found = true
break
}
}
if !found {
return boardFail(t, given, expected, p)
}
}
return true
}
func readAliveCells(path string, width, height int) []util.Cell {
data, ioError := ioutil.ReadFile(path)
util.Check(ioError)
fields := strings.Fields(string(data))
if fields[0] != "P5" {
panic("Not a pgm file")
}
imageWidth, _ := strconv.Atoi(fields[1])
if imageWidth != width {
panic("Incorrect width")
}
imageHeight, _ := strconv.Atoi(fields[2])
if imageHeight != height {
panic("Incorrect height")
}
maxval, _ := strconv.Atoi(fields[3])
if maxval != 255 {
panic("Incorrect maxval/bit depth")
}
image := []byte(fields[4])
var cells []util.Cell
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
cell := image[0]
if cell != 0 {
cells = append(cells, util.Cell{
X: x,
Y: y,
})
}
image = image[1:]
}
}
return cells
}