14 "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
15 "git.curoverse.com/arvados.git/sdk/go/arvadostest"
16 "git.curoverse.com/arvados.git/sdk/go/blockdigest"
17 "git.curoverse.com/arvados.git/sdk/go/keepclient"
22 // Gocheck boilerplate
23 func Test(t *testing.T) {
27 type KeepSuite struct{}
29 var _ = Suite(&KeepSuite{})
31 type TestHandler struct {
35 func (ts *TestHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
36 r := json.NewDecoder(req.Body)
40 func (s *KeepSuite) TestSendTrashLists(c *C) {
42 server := httptest.NewServer(&th)
45 tl := map[string]TrashList{
46 server.URL: TrashList{TrashRequest{"000000000000000000000000deadbeef", 99}}}
48 arv := arvadosclient.ArvadosClient{ApiToken: "abc123"}
49 kc := keepclient.KeepClient{Arvados: &arv, Client: &http.Client{}}
50 kc.SetServiceRoots(map[string]string{"xxxx": server.URL},
51 map[string]string{"xxxx": server.URL},
54 err := SendTrashLists(nil, &kc, tl, false)
64 type TestHandlerError struct {
67 func (tse *TestHandlerError) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
68 http.Error(writer, "I'm a teapot", 418)
71 func sendTrashListError(c *C, server *httptest.Server) {
72 tl := map[string]TrashList{
73 server.URL: TrashList{TrashRequest{"000000000000000000000000deadbeef", 99}}}
75 arv := arvadosclient.ArvadosClient{ApiToken: "abc123"}
76 kc := keepclient.KeepClient{Arvados: &arv, Client: &http.Client{}}
77 kc.SetServiceRoots(map[string]string{"xxxx": server.URL},
78 map[string]string{"xxxx": server.URL},
81 err := SendTrashLists(nil, &kc, tl, false)
84 c.Check(err[0], NotNil)
87 func (s *KeepSuite) TestSendTrashListErrorResponse(c *C) {
88 server := httptest.NewServer(&TestHandlerError{})
89 sendTrashListError(c, server)
93 func (s *KeepSuite) TestSendTrashListUnreachable(c *C) {
94 sendTrashListError(c, httptest.NewUnstartedServer(&TestHandler{}))
97 type APITestData struct {
103 func (s *KeepSuite) TestGetKeepServers_UnsupportedServiceType(c *C) {
104 testGetKeepServersFromAPI(c, APITestData{1, "notadisk", 200}, "Found no keepservices with the service type disk")
107 func (s *KeepSuite) TestGetKeepServers_ReceivedTooFewServers(c *C) {
108 testGetKeepServersFromAPI(c, APITestData{2, "disk", 200}, "Did not receive all available keep servers")
111 func (s *KeepSuite) TestGetKeepServers_ServerError(c *C) {
112 testGetKeepServersFromAPI(c, APITestData{-1, "disk", -1}, "arvados API server error")
115 func testGetKeepServersFromAPI(c *C, testData APITestData, expectedError string) {
116 keepServers := ServiceList{
117 ItemsAvailable: testData.numServers,
118 KeepServers: []ServerAddress{{
123 ServiceType: testData.serverType,
127 ksJSON, _ := json.Marshal(keepServers)
128 apiStubResponses := make(map[string]arvadostest.StubResponse)
129 apiStubResponses["/arvados/v1/keep_services"] = arvadostest.StubResponse{testData.statusCode, string(ksJSON)}
130 apiStub := arvadostest.ServerStub{apiStubResponses}
132 api := httptest.NewServer(&apiStub)
135 arv := arvadosclient.ArvadosClient{
137 ApiServer: api.URL[7:],
139 Client: &http.Client{Transport: &http.Transport{}},
142 kc := keepclient.KeepClient{Arvados: &arv, Client: &http.Client{}}
143 kc.SetServiceRoots(map[string]string{"xxxx": "http://example.com:23456"},
144 map[string]string{"xxxx": "http://example.com:23456"},
147 params := GetKeepServersParams{
153 _, err := GetKeepServersAndSummarize(params)
154 c.Assert(err, NotNil)
155 c.Assert(err, ErrorMatches, fmt.Sprintf(".*%s.*", expectedError))
158 type KeepServerTestData struct {
159 // handle /status.json
164 indexResponseBody string
166 // expected error, if any
170 func (s *KeepSuite) TestGetKeepServers_ErrorGettingKeepServerStatus(c *C) {
171 testGetKeepServersAndSummarize(c, KeepServerTestData{500, 200, "ok",
172 ".*http://.* 500 Internal Server Error"})
175 func (s *KeepSuite) TestGetKeepServers_GettingIndex(c *C) {
176 testGetKeepServersAndSummarize(c, KeepServerTestData{200, -1, "notok",
177 ".*redirect-loop.*"})
180 func (s *KeepSuite) TestGetKeepServers_ErrorReadServerResponse(c *C) {
181 testGetKeepServersAndSummarize(c, KeepServerTestData{200, 500, "notok",
182 ".*http://.* 500 Internal Server Error"})
185 func (s *KeepSuite) TestGetKeepServers_ReadServerResponseTuncatedAtLineOne(c *C) {
186 testGetKeepServersAndSummarize(c, KeepServerTestData{200, 200,
187 "notterminatedwithnewline", "Index from http://.* truncated at line 1"})
190 func (s *KeepSuite) TestGetKeepServers_InvalidBlockLocatorPattern(c *C) {
191 testGetKeepServersAndSummarize(c, KeepServerTestData{200, 200, "testing\n",
192 "Error parsing BlockInfo from index line.*"})
195 func (s *KeepSuite) TestGetKeepServers_ReadServerResponseEmpty(c *C) {
196 testGetKeepServersAndSummarize(c, KeepServerTestData{200, 200, "\n", ""})
199 func (s *KeepSuite) TestGetKeepServers_ReadServerResponseWithTwoBlocks(c *C) {
200 testGetKeepServersAndSummarize(c, KeepServerTestData{200, 200,
201 "51752ba076e461ec9ec1d27400a08548+20 1447526361\na048cc05c02ba1ee43ad071274b9e547+52 1447526362\n\n", ""})
204 func testGetKeepServersAndSummarize(c *C, testData KeepServerTestData) {
205 ksStubResponses := make(map[string]arvadostest.StubResponse)
206 ksStubResponses["/status.json"] = arvadostest.StubResponse{testData.statusStatusCode, string(`{}`)}
207 ksStubResponses["/index"] = arvadostest.StubResponse{testData.indexStatusCode, testData.indexResponseBody}
208 ksStub := arvadostest.ServerStub{ksStubResponses}
209 ks := httptest.NewServer(&ksStub)
212 ksURL, err := url.Parse(ks.URL)
214 ksHost, port, err := net.SplitHostPort(ksURL.Host)
215 ksPort, err := strconv.Atoi(port)
218 servers_list := ServiceList{
220 KeepServers: []ServerAddress{{
228 ksJSON, _ := json.Marshal(servers_list)
229 apiStubResponses := make(map[string]arvadostest.StubResponse)
230 apiStubResponses["/arvados/v1/keep_services"] = arvadostest.StubResponse{200, string(ksJSON)}
231 apiStub := arvadostest.ServerStub{apiStubResponses}
233 api := httptest.NewServer(&apiStub)
236 arv := arvadosclient.ArvadosClient{
238 ApiServer: api.URL[7:],
240 Client: &http.Client{Transport: &http.Transport{}},
243 kc := keepclient.KeepClient{Arvados: &arv, Client: &http.Client{}}
244 kc.SetServiceRoots(map[string]string{"xxxx": ks.URL},
245 map[string]string{"xxxx": ks.URL},
248 params := GetKeepServersParams{
254 // GetKeepServersAndSummarize
255 results, err := GetKeepServersAndSummarize(params)
257 if testData.expectedError == "" {
259 c.Assert(results, NotNil)
261 blockToServers := results.BlockToServers
263 blockLocators := strings.Split(testData.indexResponseBody, "\n")
264 for _, loc := range blockLocators {
265 locator := strings.Split(loc, " ")[0]
267 blockLocator, err := blockdigest.ParseBlockLocator(locator)
270 blockDigestWithSize := blockdigest.DigestWithSize{blockLocator.Digest, uint32(blockLocator.Size)}
271 blockServerInfo := blockToServers[blockDigestWithSize]
272 c.Assert(blockServerInfo[0].Mtime, NotNil)
276 c.Assert(err, ErrorMatches, testData.expectedError)