6 "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
7 "git.curoverse.com/arvados.git/sdk/go/keepclient"
14 type PullWorkerTestSuite struct{}
16 // Gocheck boilerplate
17 func TestPullWorker(t *testing.T) {
21 // Gocheck boilerplate
22 var _ = Suite(&PullWorkerTestSuite{})
24 var testPullLists map[string]string
25 var processedPullLists map[string]string
26 var readContent string
30 var currentTestData PullWorkerTestData
32 func (s *PullWorkerTestSuite) SetUpTest(c *C) {
35 putContent = []byte("")
38 // When a new pull request arrives, the old one will be overwritten.
39 // This behavior is verified using these two maps in the
40 // "TestPullWorker_pull_list_with_two_items_latest_replacing_old"
41 testPullLists = make(map[string]string)
42 processedPullLists = make(map[string]string)
45 // Since keepstore does not come into picture in tests,
46 // we need to explicitly start the goroutine in tests.
47 func RunTestPullWorker(c *C) {
48 arv, err := arvadosclient.MakeArvadosClient()
49 c.Assert(err, Equals, nil)
50 keepClient, err := keepclient.MakeKeepClient(&arv)
51 c.Assert(err, Equals, nil)
53 pullq = NewWorkQueue()
54 go RunPullWorker(pullq, keepClient)
57 var first_pull_list = []byte(`[
59 "locator":"acbd18db4cc2f85cedef654fccc4a4d8+3",
65 "locator":"37b51d194a7513e45b56f6524f2d51f2+3",
72 var second_pull_list = []byte(`[
74 "locator":"73feffa4b7f6bb68e44cf984c85f6e88+3",
82 type PullWorkerTestData struct {
92 func (s *PullWorkerTestSuite) TestPullWorker_pull_list_with_two_locators(c *C) {
95 data_manager_token = "DATA MANAGER TOKEN"
96 testData := PullWorkerTestData{
97 name: "TestPullWorker_pull_list_with_two_locators",
98 req: RequestTester{"/pull", data_manager_token, "PUT", first_pull_list},
99 response_code: http.StatusOK,
100 response_body: "Received 2 pull requests\n",
101 read_content: "hello",
106 performTest(testData, c)
109 func (s *PullWorkerTestSuite) TestPullWorker_pull_list_with_one_locator(c *C) {
112 data_manager_token = "DATA MANAGER TOKEN"
113 testData := PullWorkerTestData{
114 name: "TestPullWorker_pull_list_with_one_locator",
115 req: RequestTester{"/pull", data_manager_token, "PUT", second_pull_list},
116 response_code: http.StatusOK,
117 response_body: "Received 1 pull requests\n",
118 read_content: "hola",
123 performTest(testData, c)
126 func (s *PullWorkerTestSuite) TestPullWorker_error_on_get_one_locator(c *C) {
129 data_manager_token = "DATA MANAGER TOKEN"
130 testData := PullWorkerTestData{
131 name: "TestPullWorker_error_on_get_one_locator",
132 req: RequestTester{"/pull", data_manager_token, "PUT", second_pull_list},
133 response_code: http.StatusOK,
134 response_body: "Received 1 pull requests\n",
135 read_content: "unused",
140 performTest(testData, c)
143 func (s *PullWorkerTestSuite) TestPullWorker_error_on_get_two_locators(c *C) {
146 data_manager_token = "DATA MANAGER TOKEN"
147 testData := PullWorkerTestData{
148 name: "TestPullWorker_error_on_get_two_locators",
149 req: RequestTester{"/pull", data_manager_token, "PUT", first_pull_list},
150 response_code: http.StatusOK,
151 response_body: "Received 2 pull requests\n",
152 read_content: "unused",
157 performTest(testData, c)
160 func (s *PullWorkerTestSuite) TestPullWorker_error_on_put_one_locator(c *C) {
163 data_manager_token = "DATA MANAGER TOKEN"
164 testData := PullWorkerTestData{
165 name: "TestPullWorker_error_on_put_one_locator",
166 req: RequestTester{"/pull", data_manager_token, "PUT", second_pull_list},
167 response_code: http.StatusOK,
168 response_body: "Received 1 pull requests\n",
169 read_content: "hello hello",
174 performTest(testData, c)
177 func (s *PullWorkerTestSuite) TestPullWorker_error_on_put_two_locators(c *C) {
180 data_manager_token = "DATA MANAGER TOKEN"
181 testData := PullWorkerTestData{
182 name: "TestPullWorker_error_on_put_two_locators",
183 req: RequestTester{"/pull", data_manager_token, "PUT", first_pull_list},
184 response_code: http.StatusOK,
185 response_body: "Received 2 pull requests\n",
186 read_content: "hello again",
191 performTest(testData, c)
194 // When a new pull request arrives, the old one is replaced. This test
195 // is used to check that behavior by first putting an item on the queue,
196 // and then performing the test. Thus the "testPullLists" has two entries;
197 // however, processedPullLists will see only the newest item in the list.
198 func (s *PullWorkerTestSuite) TestPullWorker_pull_list_with_two_items_latest_replacing_old(c *C) {
201 var firstInput = []int{1}
202 pullq = NewWorkQueue()
203 pullq.ReplaceQueue(makeTestWorkList(firstInput))
204 testPullLists["Added_before_actual_test_item"] = string(1)
206 data_manager_token = "DATA MANAGER TOKEN"
207 testData := PullWorkerTestData{
208 name: "TestPullWorker_pull_list_with_two_items_latest_replacing_old",
209 req: RequestTester{"/pull", data_manager_token, "PUT", second_pull_list},
210 response_code: http.StatusOK,
211 response_body: "Received 1 pull requests\n",
212 read_content: "hola de nuevo",
217 performTest(testData, c)
220 // In this case, the item will not be placed on pullq
221 func (s *PullWorkerTestSuite) TestPullWorker_invalid_data_manager_token(c *C) {
224 data_manager_token = "DATA MANAGER TOKEN"
226 testData := PullWorkerTestData{
227 name: "TestPullWorker_pull_list_with_two_locators",
228 req: RequestTester{"/pull", "invalid_data_manager_token", "PUT", first_pull_list},
229 response_code: http.StatusUnauthorized,
230 response_body: "Unauthorized\n",
231 read_content: "hello",
236 performTest(testData, c)
239 func performTest(testData PullWorkerTestData, c *C) {
242 currentTestData = testData
243 testPullLists[testData.name] = testData.response_body
245 // Override GetContent to mock keepclient Get functionality
246 defer func(orig func(string, *keepclient.KeepClient)(io.ReadCloser, int64, string, error)) { GetContent = orig }(GetContent)
247 GetContent = func(signedLocator string, keepClient *keepclient.KeepClient) (
248 reader io.ReadCloser, contentLength int64, url string, err error) {
250 processedPullLists[testData.name] = testData.response_body
251 if testData.read_error {
252 err = errors.New("Error getting data")
254 return nil, 0, "", err
256 readContent = testData.read_content
257 cb := &ClosingBuffer{bytes.NewBufferString(testData.read_content)}
260 return rc, int64(len(testData.read_content)), "", nil
264 // Override PutContent to mock PutBlock functionality
265 defer func(orig func([]byte, string)(error)) { PutContent = orig }(PutContent)
266 PutContent = func(content []byte, locator string) (err error) {
267 if testData.put_error {
268 err = errors.New("Error putting data")
277 response := IssueRequest(&testData.req)
278 c.Assert(response.Code, Equals, testData.response_code)
279 c.Assert(response.Body.String(), Equals, testData.response_body)
281 expectWorkerChannelEmpty(c, pullq.NextItem)
285 if testData.name == "TestPullWorker_pull_list_with_two_items_latest_replacing_old" {
286 c.Assert(len(testPullLists), Equals, 2)
287 c.Assert(len(processedPullLists), Equals, 1)
288 c.Assert(testPullLists["Added_before_actual_test_item"], NotNil)
289 c.Assert(testPullLists["TestPullWorker_pull_list_with_two_items_latest_replacing_old"], NotNil)
290 c.Assert(processedPullLists["TestPullWorker_pull_list_with_two_items_latest_replacing_old"], NotNil)
292 if testData.response_code == http.StatusOK {
293 c.Assert(len(testPullLists), Equals, 1)
294 c.Assert(len(processedPullLists), Equals, 1)
295 c.Assert(testPullLists[testData.name], NotNil)
297 c.Assert(len(testPullLists), Equals, 1)
298 c.Assert(len(processedPullLists), Equals, 0)
302 if testData.read_error {
303 c.Assert(readError, NotNil)
304 } else if testData.response_code == http.StatusOK {
305 c.Assert(readError, IsNil)
306 c.Assert(readContent, Equals, testData.read_content)
307 if testData.put_error {
308 c.Assert(putError, NotNil)
310 c.Assert(putError, IsNil)
311 c.Assert(string(putContent), Equals, testData.read_content)
316 type ClosingBuffer struct {
320 func (cb *ClosingBuffer) Close() (err error) {
324 func expectWorkerChannelEmpty(c *C, workerChannel <-chan interface{}) {
326 case item := <-workerChannel:
327 c.Fatalf("Received value (%v) from channel that was expected to be empty", item)
332 func expectWorkerChannelNotEmpty(c *C, workerChannel <-chan interface{}) {
334 case item := <-workerChannel:
335 c.Fatalf("Received value (%v) from channel that was expected to be empty", item)