Merge branch 'master' into 3408-production-datamanager
[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{Entries: []PullListEntry{PullListEntry{
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 := `{"blocks":[{"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                         []string{},
50                         5),
51                 DeepEquals,
52                 PullServers{To: []string{}, From: []string{}})
53
54         c.Check(
55                 CreatePullServers(cs,
56                         stringSet("keep0:25107", "keep1:25108"),
57                         []string{},
58                         5),
59                 DeepEquals,
60                 PullServers{To: []string{}, From: []string{}})
61
62         c.Check(
63                 CreatePullServers(cs,
64                         stringSet("keep0:25107", "keep1:25108"),
65                         []string{"keep0:25107"},
66                         5),
67                 DeepEquals,
68                 PullServers{To: []string{}, From: []string{"keep0:25107"}})
69
70         c.Check(
71                 CreatePullServers(cs,
72                         stringSet("keep0:25107", "keep1:25108"),
73                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
74                         5),
75                 DeepEquals,
76                 PullServers{To: []string{"keep3:25110", "keep2:25109"},
77                         From: []string{"keep1:25108", "keep0:25107"}})
78
79         c.Check(
80                 CreatePullServers(cs,
81                         stringSet("keep0:25107", "keep1:25108"),
82                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
83                         1),
84                 DeepEquals,
85                 PullServers{To: []string{"keep3:25110"},
86                         From: []string{"keep1:25108", "keep0:25107"}})
87
88         c.Check(
89                 CreatePullServers(cs,
90                         stringSet("keep0:25107", "keep1:25108"),
91                         []string{"keep3:25110", "keep2:25109", "keep1:25108", "keep0:25107"},
92                         0),
93                 DeepEquals,
94                 PullServers{To: []string{},
95                         From: []string{"keep1:25108", "keep0:25107"}})
96 }
97
98 // Checks whether two pull list maps are equal. Since pull lists are
99 // ordered arbitrarily, we need to sort them by digest before
100 // comparing them for deep equality.
101 type pullListMapEqualsChecker struct {
102         *CheckerInfo
103 }
104
105 func (c *pullListMapEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
106         obtained, ok := params[0].(map[string]PullList)
107         if !ok {
108                 return false, "First parameter is not a PullList map"
109         }
110         expected, ok := params[1].(map[string]PullList)
111         if !ok {
112                 return false, "Second parameter is not a PullList map"
113         }
114
115         for _, v := range obtained {
116                 sort.Sort(EntriesByDigest(v.Entries))
117         }
118         for _, v := range expected {
119                 sort.Sort(EntriesByDigest(v.Entries))
120         }
121
122         return DeepEquals.Check(params, names)
123 }
124
125 var PullListMapEquals Checker = &pullListMapEqualsChecker{
126         &CheckerInfo{Name: "PullListMapEquals", Params: []string{"obtained", "expected"}},
127 }
128
129 func (s *MySuite) TestBuildPullLists(c *C) {
130         c.Check(
131                 BuildPullLists(map[Locator]PullServers{}),
132                 PullListMapEquals,
133                 map[string]PullList{})
134
135         locator1 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xBadBeef)}
136         c.Check(
137                 BuildPullLists(map[Locator]PullServers{
138                         locator1: PullServers{To: []string{}, From: []string{}}}),
139                 PullListMapEquals,
140                 map[string]PullList{})
141
142         c.Check(
143                 BuildPullLists(map[Locator]PullServers{
144                         locator1: PullServers{To: []string{}, From: []string{"f1", "f2"}}}),
145                 PullListMapEquals,
146                 map[string]PullList{})
147
148         c.Check(
149                 BuildPullLists(map[Locator]PullServers{
150                         locator1: PullServers{To: []string{"t1"}, From: []string{"f1", "f2"}}}),
151                 PullListMapEquals,
152                 map[string]PullList{"t1": PullList{Entries: []PullListEntry{PullListEntry{
153                         Locator: locator1,
154                         Servers: []string{"f1", "f2"}}}}})
155
156         c.Check(
157                 BuildPullLists(map[Locator]PullServers{
158                         locator1: PullServers{To: []string{"t1"}, From: []string{}}}),
159                 PullListMapEquals,
160                 map[string]PullList{"t1": PullList{Entries: []PullListEntry{PullListEntry{
161                         Locator: locator1,
162                         Servers: []string{}}}}})
163
164         c.Check(
165                 BuildPullLists(map[Locator]PullServers{
166                         locator1: PullServers{To: []string{"t1", "t2"}, From: []string{"f1", "f2"}}}),
167                 PullListMapEquals,
168                 map[string]PullList{
169                         "t1": PullList{Entries: []PullListEntry{PullListEntry{
170                                 Locator: locator1,
171                                 Servers: []string{"f1", "f2"}}}},
172                         "t2": PullList{Entries: []PullListEntry{PullListEntry{
173                                 Locator: locator1,
174                                 Servers: []string{"f1", "f2"}}}},
175                 })
176
177         locator2 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xCabbed)}
178         c.Check(
179                 BuildPullLists(map[Locator]PullServers{
180                         locator1: PullServers{To: []string{"t1"}, From: []string{"f1", "f2"}},
181                         locator2: PullServers{To: []string{"t2"}, From: []string{"f3", "f4"}}}),
182                 PullListMapEquals,
183                 map[string]PullList{
184                         "t1": PullList{Entries: []PullListEntry{PullListEntry{
185                                 Locator: locator1,
186                                 Servers: []string{"f1", "f2"}}}},
187                         "t2": PullList{Entries: []PullListEntry{PullListEntry{
188                                 Locator: locator2,
189                                 Servers: []string{"f3", "f4"}}}},
190                 })
191
192         c.Check(
193                 BuildPullLists(map[Locator]PullServers{
194                         locator1: PullServers{To: []string{"t1"}, From: []string{"f1", "f2"}},
195                         locator2: PullServers{To: []string{"t2", "t1"}, From: []string{"f3", "f4"}}}),
196                 PullListMapEquals,
197                 map[string]PullList{
198                         "t1": PullList{Entries: []PullListEntry{
199                                 PullListEntry{
200                                         Locator: locator1,
201                                         Servers: []string{"f1", "f2"}},
202                                 PullListEntry{
203                                         Locator: locator2,
204                                         Servers: []string{"f3", "f4"}}}},
205                         "t2": PullList{Entries: []PullListEntry{PullListEntry{
206                                 Locator: locator2,
207                                 Servers: []string{"f3", "f4"}}}},
208                 })
209
210         locator3 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xDeadBeef)}
211         locator4 := Locator{Digest: blockdigest.MakeTestBlockDigest(0xFedBeef)}
212         c.Check(
213                 BuildPullLists(map[Locator]PullServers{
214                         locator1: PullServers{To: []string{"t1"}, From: []string{"f1", "f2"}},
215                         locator2: PullServers{To: []string{"t2", "t1"}, From: []string{"f3", "f4"}},
216                         locator3: PullServers{To: []string{"t3", "t2", "t1"}, From: []string{"f4", "f5"}},
217                         locator4: PullServers{To: []string{"t4", "t3", "t2", "t1"}, From: []string{"f1", "f5"}},
218                 }),
219                 PullListMapEquals,
220                 map[string]PullList{
221                         "t1": PullList{Entries: []PullListEntry{
222                                 PullListEntry{
223                                         Locator: locator1,
224                                         Servers: []string{"f1", "f2"}},
225                                 PullListEntry{
226                                         Locator: locator2,
227                                         Servers: []string{"f3", "f4"}},
228                                 PullListEntry{
229                                         Locator: locator3,
230                                         Servers: []string{"f4", "f5"}},
231                                 PullListEntry{
232                                         Locator: locator4,
233                                         Servers: []string{"f1", "f5"}},
234                         }},
235                         "t2": PullList{Entries: []PullListEntry{
236                                 PullListEntry{
237                                         Locator: locator2,
238                                         Servers: []string{"f3", "f4"}},
239                                 PullListEntry{
240                                         Locator: locator3,
241                                         Servers: []string{"f4", "f5"}},
242                                 PullListEntry{
243                                         Locator: locator4,
244                                         Servers: []string{"f1", "f5"}},
245                         }},
246                         "t3": PullList{Entries: []PullListEntry{
247                                 PullListEntry{
248                                         Locator: locator3,
249                                         Servers: []string{"f4", "f5"}},
250                                 PullListEntry{
251                                         Locator: locator4,
252                                         Servers: []string{"f1", "f5"}},
253                         }},
254                         "t4": PullList{Entries: []PullListEntry{
255                                 PullListEntry{
256                                         Locator: locator4,
257                                         Servers: []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 }