Merge branch 'master' into 3699-arv-copy
authorTim Pierce <twp@curoverse.com>
Fri, 19 Sep 2014 15:34:46 +0000 (11:34 -0400)
committerTim Pierce <twp@curoverse.com>
Fri, 19 Sep 2014 15:34:46 +0000 (11:34 -0400)
1  2 
sdk/python/setup.py
sdk/python/tests/test_keep_client.py

diff --combined sdk/python/setup.py
index 5df80e422afd29d7d91f797823efc7211b0b1495,e0afe89a81d60abddb77a1c336e521117ff555de..dac09bffd6db60ce01fdd3731424075fe78241ed
@@@ -17,7 -17,6 +17,7 @@@ setup(name='arvados-python-client'
        license='Apache 2.0',
        packages=find_packages(),
        scripts=[
 +        'bin/arv-copy',
          'bin/arv-get',
          'bin/arv-keepdocker',
          'bin/arv-ls',
@@@ -33,5 -32,5 +33,5 @@@
          'ws4py'
          ],
        test_suite='tests',
-       tests_require=['mock', 'PyYAML'],
+       tests_require=['mock>=1.0', 'PyYAML'],
        zip_safe=False)
index 211b73fe001f76dda32b8fa3565752687193163a,8cc22a6ee6ba27e336df7f88dd7ad67ab7ee817f..2a1a87e4cc7ff148d9b150afd362c70869d48fa1
@@@ -5,8 -5,8 +5,8 @@@ import unittes
  
  import arvados
  import arvados.retry
+ import arvados_testutil as tutil
  import run_test_server
- from arvados_testutil import fake_httplib2_response
  
  class KeepTestCase(run_test_server.TestCaseWithServers):
      MAIN_SERVER = {}
                           blob_str,
                           'wrong content from Keep.get(md5(<binarydata>))')
  
 +    def test_KeepEmptyCollectionTest(self):
 +        blob_locator = self.keep_client.put('', copies=1)
 +        self.assertRegexpMatches(
 +            blob_locator,
 +            '^d41d8cd98f00b204e9800998ecf8427e\+0',
 +            ('wrong locator from Keep.put(""): ' + blob_locator))
 +
  
  class KeepPermissionTestCase(run_test_server.TestCaseWithServers):
      MAIN_SERVER = {}
@@@ -239,17 -232,17 +239,17 @@@ class KeepClientRetryTestMixin(object)
      # supporting servers, and prevents side effects in case something hiccups.
      # To use this mixin, define DEFAULT_EXPECT, DEFAULT_EXCEPTION, and
      # run_method().
-     PROXY_ADDR = 'http://[100::]/'
+     PROXY_ADDR = 'http://[%s]:65535/' % (tutil.TEST_HOST,)
      TEST_DATA = 'testdata'
      TEST_LOCATOR = 'ef654c40ab4f1747fc699915d4f70902+8'
  
-     @staticmethod
-     def mock_responses(body, *codes):
-         return mock.patch('httplib2.Http.request', side_effect=(
-                 (fake_httplib2_response(code), body) for code in codes))
+     def setUp(self):
+         self.client_kwargs = {'proxy': self.PROXY_ADDR, 'local_store': ''}
  
-     def new_client(self):
-         return arvados.KeepClient(proxy=self.PROXY_ADDR, local_store='')
+     def new_client(self, **caller_kwargs):
+         kwargs = self.client_kwargs.copy()
+         kwargs.update(caller_kwargs)
+         return arvados.KeepClient(**kwargs)
  
      def run_method(self, *args, **kwargs):
          raise NotImplementedError("test subclasses must define run_method")
          self.assertRaises(error_class, self.run_method, *args, **kwargs)
  
      def test_immediate_success(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 200):
              self.check_success()
  
      def test_retry_then_success(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 500, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 500, 200):
              self.check_success(num_retries=3)
  
      def test_no_default_retry(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 500, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 500, 200):
              self.check_exception()
  
      def test_no_retry_after_permanent_error(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 403, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 403, 200):
              self.check_exception(num_retries=3)
  
      def test_error_after_retries_exhausted(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 500, 500, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 500, 500, 200):
              self.check_exception(num_retries=1)
  
+     def test_num_retries_instance_fallback(self):
+         self.client_kwargs['num_retries'] = 3
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 500, 200):
+             self.check_success()
  
- # Don't delay from HTTPRetryLoop's exponential backoff.
- no_backoff = mock.patch('time.sleep', lambda n: None)
- @no_backoff
- class KeepClientRetryGetTestCase(unittest.TestCase, KeepClientRetryTestMixin):
+ @tutil.skip_sleep
+ class KeepClientRetryGetTestCase(KeepClientRetryTestMixin, unittest.TestCase):
      DEFAULT_EXPECT = KeepClientRetryTestMixin.TEST_DATA
      DEFAULT_EXCEPTION = arvados.errors.KeepReadError
      HINTED_LOCATOR = KeepClientRetryTestMixin.TEST_LOCATOR + '+K@xyzzy'
          return self.new_client().get(locator, *args, **kwargs)
  
      def test_specific_exception_when_not_found(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 404, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 404, 200):
              self.check_exception(arvados.errors.NotFoundError, num_retries=3)
  
      def test_general_exception_with_mixed_errors(self):
          # This test rigs up 50/50 disagreement between two servers, and
          # checks that it does not become a NotFoundError.
          client = self.new_client()
-         with self.mock_responses(self.DEFAULT_EXPECT, 404, 500):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 404, 500):
              with self.assertRaises(arvados.errors.KeepReadError) as exc_check:
                  client.get(self.HINTED_LOCATOR)
              self.assertNotIsInstance(
                  "mixed errors raised NotFoundError")
  
      def test_hint_server_can_succeed_without_retries(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 404, 200, 500):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 404, 200, 500):
              self.check_success(locator=self.HINTED_LOCATOR)
  
      def test_try_next_server_after_timeout(self):
-         responses = iter([None, (fake_httplib2_response(200),
-                                  self.DEFAULT_EXPECT)])
-         def side_effect(*args, **kwargs):
-             response = next(responses)
-             if response is None:
-                 raise socket.timeout("timed out")
-             else:
-                 return response
-         with mock.patch('httplib2.Http.request', side_effect=side_effect):
+         side_effects = [
+             socket.timeout("timed out"),
+             (tutil.fake_httplib2_response(200), self.DEFAULT_EXPECT)]
+         with mock.patch('httplib2.Http.request',
+                         side_effect=iter(side_effects)):
+             self.check_success(locator=self.HINTED_LOCATOR)
+     def test_retry_data_with_wrong_checksum(self):
+         side_effects = ((tutil.fake_httplib2_response(200), s)
+                         for s in ['baddata', self.TEST_DATA])
+         with mock.patch('httplib2.Http.request', side_effect=side_effects):
              self.check_success(locator=self.HINTED_LOCATOR)
  
  
- @no_backoff
- class KeepClientRetryPutTestCase(unittest.TestCase, KeepClientRetryTestMixin):
+ @tutil.skip_sleep
+ class KeepClientRetryPutTestCase(KeepClientRetryTestMixin, unittest.TestCase):
      DEFAULT_EXPECT = KeepClientRetryTestMixin.TEST_LOCATOR
      DEFAULT_EXCEPTION = arvados.errors.KeepWriteError
  
          return self.new_client().put(data, copies, *args, **kwargs)
  
      def test_do_not_send_multiple_copies_to_same_server(self):
-         with self.mock_responses(self.DEFAULT_EXPECT, 200):
+         with tutil.mock_responses(self.DEFAULT_EXPECT, 200):
              self.check_exception(copies=2, num_retries=3)