Changes in response to code review.
[arvados.git] / services / datamanager / summary / pull_list_test.go
1 package summary
2
3 import (
4         "encoding/json"
5         "git.curoverse.com/arvados.git/sdk/go/blockdigest"
6         . "gopkg.in/check.v1"
7         "sort"
8         "testing"
9 )
10
11 // Gocheck boilerplate
12 func Test(t *testing.T) {
13         TestingT(t)
14 }
15
16 type MySuite struct{}
17
18 var _ = Suite(&MySuite{})
19
20 // Helper method to declare string sets more succinctly
21 // Could be placed somewhere more general.
22 func stringSet(slice ...string) (m map[string]struct{}) {
23         m = map[string]struct{}{}
24         for _, s := range slice {
25                 m[s] = struct{}{}
26         }
27         return
28 }
29
30 func (s *MySuite) TestPullListPrintsJSONCorrectly(c *C) {
31         pl := PullList{PullRequest{
32                 Locator: Locator{Digest: blockdigest.MakeTestBlockDigest(0xBadBeef)},
33                 Servers: []string{"keep0.qr1hi.arvadosapi.com:25107",
34                         "keep1.qr1hi.arvadosapi.com:25108"}}}
35
36         b, err := json.Marshal(pl)
37         c.Assert(err, IsNil)
38         expectedOutput := `[{"locator":"0000000000000000000000000badbeef",` +
39                 `"servers":["keep0.qr1hi.arvadosapi.com:25107",` +
40                 `"keep1.qr1hi.arvadosapi.com:25108"]}]`
41         c.Check(string(b), Equals, expectedOutput)
42 }
43
44 func (s *MySuite) TestCreatePullServers(c *C) {
45         var cs CanonicalString
46         c.Check(
47                 CreatePullServers(cs,
48                         stringSet(),
49                         stringSet(),
50                         []string{},
51                         5),
52                 DeepEquals,
53                 PullServers{To: []string{}, From: []string{}})
54
55         c.Check(
56                 CreatePullServers(cs,
57                         stringSet("keep0:25107", "keep1:25108"),
58                         stringSet(),
59                         []string{},
60                         5),
61                 DeepEquals,
62                 PullServers{To: []string{}, From: []string{}})
63
64         c.Check(
65                 CreatePullServers(cs,
66                         stringSet("keep0:25107", "keep1:25108"),
67                         stringSet("keep0:25107"),
68                         []string{"keep0:25107"},
69                         5),
70                 DeepEquals,
71                 PullServers{To: []string{}, From: []string{"keep0:25107"}})
72
73         c.Check(
74                 CreatePullServers(cs,
75                         stringSet("keep0:25107", "keep1:25108"),
76                         stringSet("keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"),
77                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
78                         5),
79                 DeepEquals,
80                 PullServers{To: []string{"keep3:25110", "keep2:25109"},
81                         From: []string{"keep1:25108", "keep0:25107"}})
82
83         c.Check(
84                 CreatePullServers(cs,
85                         stringSet("keep0:25107", "keep1:25108"),
86                         stringSet("keep3:25110", "keep1:25108", "keep0:25107"),
87                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
88                         5),
89                 DeepEquals,
90                 PullServers{To: []string{"keep3:25110"},
91                         From: []string{"keep1:25108", "keep0:25107"}})
92
93         c.Check(
94                 CreatePullServers(cs,
95                         stringSet("keep0:25107", "keep1:25108"),
96                         stringSet("keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"),
97                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
98                         1),
99                 DeepEquals,
100                 PullServers{To: []string{"keep3:25110"},
101                         From: []string{"keep1:25108", "keep0:25107"}})
102
103         c.Check(
104                 CreatePullServers(cs,
105                         stringSet("keep0:25107", "keep1:25108"),
106                         stringSet("keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"),
107                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
108                         0),
109                 DeepEquals,
110                 PullServers{To: []string{},
111                         From: []string{"keep1:25108", "keep0:25107"}})
112 }
113
114 // Checks whether two pull list maps are equal. Since pull lists are
115 // ordered arbitrarily, we need to sort them by digest before
116 // comparing them for deep equality.
117 type pullListMapEqualsChecker struct {
118         *CheckerInfo
119 }
120
121 func (c *pullListMapEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
122         obtained, ok := params[0].(map[string]PullList)
123         if !ok {
124                 return false, "First parameter is not a PullList map"
125         }
126         expected, ok := params[1].(map[string]PullList)
127         if !ok {
128                 return false, "Second parameter is not a PullList map"
129         }
130
131         for _, v := range obtained {
132                 sort.Sort(PullListByDigest(v))
133         }
134         for _, v := range expected {
135                 sort.Sort(PullListByDigest(v))
136         }
137
138         return DeepEquals.Check(params, names)
139 }
140
141 var PullListMapEquals Checker = &pullListMapEqualsChecker{&CheckerInfo{
142         Name:   "PullListMapEquals",
143         Params: []string{"obtained", "expected"},
144 }}
145
146 func (s *MySuite) TestBuildPullLists(c *C) {
147         c.Check(
148                 BuildPullLists(map[Locator]PullServers{}),
149                 PullListMapEquals,
150                 map[string]PullList{})
151
152         locator1 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xBadBeef)}
153         c.Check(
154                 BuildPullLists(map[Locator]PullServers{
155                         locator1: PullServers{To: []string{}, From: []string{}}}),
156                 PullListMapEquals,
157                 map[string]PullList{})
158
159         c.Check(
160                 BuildPullLists(map[Locator]PullServers{
161                         locator1: PullServers{To: []string{}, From: []string{"f1", "f2"}}}),
162                 PullListMapEquals,
163                 map[string]PullList{})
164
165         c.Check(
166                 BuildPullLists(map[Locator]PullServers{
167                         locator1: PullServers{To: []string{"t1"}, From: []string{"f1", "f2"}}}),
168                 PullListMapEquals,
169                 map[string]PullList{
170                         "t1": PullList{PullRequest{locator1, []string{"f1", "f2"}}}})
171
172         c.Check(
173                 BuildPullLists(map[Locator]PullServers{
174                         locator1: PullServers{To: []string{"t1"}, From: []string{}}}),
175                 PullListMapEquals,
176                 map[string]PullList{"t1": PullList{
177                         PullRequest{locator1, []string{}}}})
178
179         c.Check(
180                 BuildPullLists(map[Locator]PullServers{
181                         locator1: PullServers{
182                                 To:   []string{"t1", "t2"},
183                                 From: []string{"f1", "f2"},
184                         }}),
185                 PullListMapEquals,
186                 map[string]PullList{
187                         "t1": PullList{PullRequest{locator1, []string{"f1", "f2"}}},
188                         "t2": PullList{PullRequest{locator1, []string{"f1", "f2"}}},
189                 })
190
191         locator2 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xCabbed)}
192         c.Check(
193                 BuildPullLists(map[Locator]PullServers{
194                         locator1: PullServers{To: []string{"t1"}, From: []string{"f1", "f2"}},
195                         locator2: PullServers{To: []string{"t2"}, From: []string{"f3", "f4"}}}),
196                 PullListMapEquals,
197                 map[string]PullList{
198                         "t1": PullList{PullRequest{locator1, []string{"f1", "f2"}}},
199                         "t2": PullList{PullRequest{locator2, []string{"f3", "f4"}}},
200                 })
201
202         c.Check(
203                 BuildPullLists(map[Locator]PullServers{
204                         locator1: PullServers{
205                                 To:   []string{"t1"},
206                                 From: []string{"f1", "f2"}},
207                         locator2: PullServers{
208                                 To:   []string{"t2", "t1"},
209                                 From: []string{"f3", "f4"}},
210                 }),
211                 PullListMapEquals,
212                 map[string]PullList{
213                         "t1": PullList{
214                                 PullRequest{locator1, []string{"f1", "f2"}},
215                                 PullRequest{locator2, []string{"f3", "f4"}},
216                         },
217                         "t2": PullList{
218                                 PullRequest{locator2, []string{"f3", "f4"}},
219                         },
220                 })
221
222         locator3 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xDeadBeef)}
223         locator4 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xFedBeef)}
224         c.Check(
225                 BuildPullLists(map[Locator]PullServers{
226                         locator1: PullServers{
227                                 To:   []string{"t1"},
228                                 From: []string{"f1", "f2"}},
229                         locator2: PullServers{
230                                 To:   []string{"t2", "t1"},
231                                 From: []string{"f3", "f4"}},
232                         locator3: PullServers{
233                                 To:   []string{"t3", "t2", "t1"},
234                                 From: []string{"f4", "f5"}},
235                         locator4: PullServers{
236                                 To:   []string{"t4", "t3", "t2", "t1"},
237                                 From: []string{"f1", "f5"}},
238                 }),
239                 PullListMapEquals,
240                 map[string]PullList{
241                         "t1": PullList{
242                                 PullRequest{locator1, []string{"f1", "f2"}},
243                                 PullRequest{locator2, []string{"f3", "f4"}},
244                                 PullRequest{locator3, []string{"f4", "f5"}},
245                                 PullRequest{locator4, []string{"f1", "f5"}},
246                         },
247                         "t2": PullList{
248                                 PullRequest{locator2, []string{"f3", "f4"}},
249                                 PullRequest{locator3, []string{"f4", "f5"}},
250                                 PullRequest{locator4, []string{"f1", "f5"}},
251                         },
252                         "t3": PullList{
253                                 PullRequest{locator3, []string{"f4", "f5"}},
254                                 PullRequest{locator4, []string{"f1", "f5"}},
255                         },
256                         "t4": PullList{
257                                 PullRequest{locator4, []string{"f1", "f5"}},
258                         },
259                 })
260 }
261
262 func (s *MySuite) TestRemoveProtocolPrefix(c *C) {
263         c.Check(RemoveProtocolPrefix("blah"), Equals, "blah")
264         c.Check(RemoveProtocolPrefix("bl/ah"), Equals, "ah")
265         c.Check(RemoveProtocolPrefix("http://blah.com"), Equals, "blah.com")
266         c.Check(RemoveProtocolPrefix("https://blah.com:8900"), Equals, "blah.com:8900")
267 }