Example #1
0
    def test_monitor_job_running(self, retry, get_connection):
        conn = get_connection.return_value.__enter__.return_value
        job_id = 'dummy'
        cluster = {
            '_id': 'jill',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'output': []
        }

        conn.execute.return_value = [ 'job-ID  prior   name       user         state submit/start at     queue  slots ja-task-ID',
                             '-----------------------------------------------------------------------------------------',
                             '1 0.00000 hostname   sgeadmin     r     09/09/2009 14:58:14                1']

        def _get_status(url, request):
            content = {
                'status': 'running'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._get_status_called  = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {'status': 'running', 'timings': {}, 'output': []}
            self._set_status_called = json.loads(request.body) == expected

            if not self._set_status_called:
                six.print_(json.loads(request.body), file=sys.stderr)

            return httmock.response(200, None, {}, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(
            path=r'^%s$' % status_url, method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(
            path=r'^%s$' % status_update_url, method='PATCH')(_set_status)

        with httmock.HTTMock(get_status, set_status):
            job.monitor_job(cluster, job_model, **{'girder_token': 's', 'log_write_url': 1})

        self.assertTrue(self._get_status_called, 'Expect get status endpoint to be hit')
        self.assertTrue(self._set_status_called, 'Expect set status endpoint to be hit')
Example #2
0
def mock_response(
    content,
    url=None,
    path="",
    headers=None,
    response_url=None,
    status_code=200,
    cookies=None,
    func=None,
):
    """Universal handler for specify mocks inplace."""
    if func is None:

        def mocked(url, request):
            mock = response(status_code=status_code,
                            content=content,
                            request=request,
                            headers=headers)
            if cookies:
                mock.cookies = cookies
            mock.url = response_url if response_url else url
            return mock

    else:
        mocked = func

    if url:
        parsed = urlparse(url)
        return urlmatch(netloc=parsed.netloc, path=parsed.path)(func=mocked)
    elif path:
        return urlmatch(path=path)(func=mocked)
    else:
        return all_requests(func=mocked)
Example #3
0
    def test_monitor_job_terminated(self, get_connection):
        conn = get_connection.return_value.__enter__.return_value

        job_id = 'dummy'
        cluster = {
            '_id': 'bob',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_model = {
            '_id': job_id,
            'queueJobId': 'dummy',
            'name': 'dummy',
            'output': []
        }

        conn.execute.return_value = 'qstat output'

        def _get_status(url, request):
            content = {
                'status': 'terminating'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._get_status_called  = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {u'status': u'terminated', u'timings': {}, u'output': []}

            self._set_status_called = json.loads(request.body) == expected

            return httmock.response(200, None, {}, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(
            path=r'^%s$' % status_url, method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(
            path=r'^%s$' % status_update_url, method='PATCH')(_set_status)

        with httmock.HTTMock(get_status, set_status):
            job.monitor_job(cluster, job_model, **{'girder_token': 's', 'log_write_url': 1})

        self.assertTrue(self._get_status_called, 'Expect get status endpoint to be hit')
        self.assertTrue(self._set_status_called, 'Expect set status endpoint to be hit')
Example #4
0
    def test_key_generate(self):
        cluster = {
            '_id': '55c3a698f6571011a48f6817'
        }

        key_path = os.path.join(cumulus.config.ssh.keyStore, cluster['_id'])
        try:
            os.remove(key_path)
        except OSError:
            pass

        def _update(url, request):
            request_body = json.loads(request.body)
            passphrase = parse('config.ssh.passphrase').find(request_body)
            public_key = parse('config.ssh.publicKey').find(request_body)
            status = request_body['status'] == 'created'

            self._update = passphrase and public_key and status
            return httmock.response(200, None, {}, request=request)

        update_url = '/api/v1/clusters/%s' % cluster['_id']
        update = httmock.urlmatch(
            path=r'^%s$' % update_url, method='PATCH')(_update)

        with httmock.HTTMock(update):
            key.generate_key_pair(cluster)

        self.assertTrue(os.path.exists(key_path), 'Key was not created')
        os.remove(key_path)
        self.assertTrue(self._update, 'Update was not called')
Example #5
0
    def setUp(self):
        status_url = '%s/login' % newt_base_url

        data = {
            'username': NewtClusterConnectionTestCase.USER,
            'password': NewtClusterConnectionTestCase.PASSWORD
        }

        r = requests.post(status_url, data=data)
        json_resp = r.json()

        self.assertTrue(json_resp['auth'])
        self.session_id = json_resp['newt_sessionid']

        self._cluster = {'type': 'newt', 'config': {'host': 'cori'}}
        self._girder_token = 'dummy'

        def session_id(url, request):
            return self._session_id(url, request)

        url = '/api/v1/newt/sessionId'
        self.me = httmock.urlmatch(path=r'^%s$' % url,
                                   method='GET')(session_id)

        self.scratch_dir = '/global/cscratch1/sd/%s' % NewtClusterConnectionTestCase.USER
        self.test_data = 'nothing to see here!'
        self.test_case_dir = '%s/cumulus' % self.scratch_dir
        self.test_file_path = '%s/test.txt' % self.test_case_dir
        self.test_dir = '%s/cumulus' % self.test_case_dir

        # Create directory for test case
        with httmock.HTTMock(self.me):
            with get_connection(self._girder_token, self._cluster) as conn:
                conn.mkdir(self.test_case_dir)
Example #6
0
    def testPatch(self):
        patchUrl = 'patch'
        patchRequest = {
            'valid': False
        }

        # Test json request
        jsonBody = {
            'foo': 'bar'
        }

        def _patchJson(url, request):
            body = request.body
            if isinstance(body, six.binary_type):
                body = body.decode('utf8')
            patchRequest['valid'] = json.loads(body) == jsonBody

            return httmock.response(200, {}, {}, request=request)

        patch = httmock.urlmatch(
            path=r'^.*%s$' % patchUrl, method='PUT')(_patchJson)

        with httmock.HTTMock(patch):
            client = girder_client.GirderClient()
            client.put(patchUrl, json=jsonBody)

        # Check we got the right request
        self.assertTrue(patchRequest['valid'])

        # Now try raw message body
        patchRequest['valid'] = False
        rawBody = 'raw'

        def _patchRaw(url, request):
            patchRequest['valid'] = request.body == rawBody

            return httmock.response(200, {}, {}, request=request)

        patch = httmock.urlmatch(
            path=r'^.*%s$' % patchUrl, method='PUT')(_patchRaw)

        with httmock.HTTMock(patch):
            client = girder_client.GirderClient()
            client.put(patchUrl, data=rawBody)

        # Check we got the right request
        self.assertTrue(patchRequest['valid'])
Example #7
0
    def testPatch(self):
        patchUrl = 'patch'
        patchRequest = {
            'valid': False
        }

        # Test json request
        jsonBody = {
            'foo': 'bar'
        }

        def _patchJson(url, request):
            body = request.body
            if isinstance(body, bytes):
                body = body.decode('utf8')
            patchRequest['valid'] = json.loads(body) == jsonBody

            return httmock.response(200, {}, {}, request=request)

        patch = httmock.urlmatch(
            path=r'^.*%s$' % patchUrl, method='PUT')(_patchJson)

        with httmock.HTTMock(patch):
            client = girder_client.GirderClient()
            client.put(patchUrl, json=jsonBody)

        # Check we got the right request
        self.assertTrue(patchRequest['valid'])

        # Now try raw message body
        patchRequest['valid'] = False
        rawBody = 'raw'

        def _patchRaw(url, request):
            patchRequest['valid'] = request.body == rawBody

            return httmock.response(200, {}, {}, request=request)

        patch = httmock.urlmatch(
            path=r'^.*%s$' % patchUrl, method='PUT')(_patchRaw)

        with httmock.HTTMock(patch):
            client = girder_client.GirderClient()
            client.put(patchUrl, data=rawBody)

        # Check we got the right request
        self.assertTrue(patchRequest['valid'])
Example #8
0
def json_fixture(path_match=None, response_data={}, status_code=200):

    def fixture_response(url, req):
        return {'status_code': status_code,
                 'content': response_data,
                 'headers': {'content-type': 'application/json'}}
    if path_match is None:
        return all_requests(fixture_response)
    return urlmatch(path=path_match)(fixture_response)
Example #9
0
def json_fixture(path_match=None, response_data={}, status_code=200):
    def fixture_response(url, req):
        return {
            'status_code': status_code,
            'content': response_data,
            'headers': {
                'content-type': 'application/json'
            }
        }

    if path_match is None:
        return all_requests(fixture_response)
    return urlmatch(path=path_match)(fixture_response)
Example #10
0
    def test_key_generate(self, get_ec2_client):
        ec2_client = get_ec2_client.return_value
        ec2_client.create_key_pair.side_effect = Exception('some error')

        profile = {
            '_id': '55c3a698f6571011a48f6817',
            'userId': '55c3a698f6571011a48f6818',
            'name': 'profile'
        }

        key_path = os.path.join(cumulus.config.ssh.keyStore, profile['_id'])
        try:
            os.remove(key_path)
        except OSError:
            pass

        def _update(url, request):
            request_body = json.loads(request.body.decode('utf8'))
            status = parse('status').find(request_body)
            if status:
                status = status[0].value

            self._update = status == self._expected_status

            if status == 'error':
                self._errorMessage = request_body['errorMessage']

            return httmock.response(200, None, {}, request=request)

        update_url = '/api/v1/user/%s/aws/profiles/%s' % (profile['userId'],
                                                         profile['_id'])
        update = httmock.urlmatch(
            path=r'^%s$' % update_url, method='PATCH')(_update)

        self._expected_status = 'error'
        with httmock.HTTMock(update):
            key.generate_key_pair(profile, 'girder-token')

        self.assertTrue(self._update, 'Update was not called')
        self.assertTrue(self._errorMessage, 'No errorMessage set')

        # Now mock out EC2 and check for success
        self._update = False
        self._expected_status = 'available'
        ec2_client.create_key_pair.side_effect = None
        ec2_client.create_key_pair.return_value = {
            'KeyMaterial': 'dummy'
        }
        with httmock.HTTMock(update):
            key.generate_key_pair(profile, 'girder-token')
Example #11
0
    def test_key_generate(self, get_ec2_client):
        ec2_client = get_ec2_client.return_value
        ec2_client.create_key_pair.side_effect = Exception('some error')

        profile = {
            '_id': '55c3a698f6571011a48f6817',
            'userId': '55c3a698f6571011a48f6818',
            'name': 'profile'
        }

        key_path = os.path.join(cumulus.config.ssh.keyStore, profile['_id'])
        try:
            os.remove(key_path)
        except OSError:
            pass

        def _update(url, request):
            request_body = json.loads(request.body)
            status = parse('status').find(request_body)
            if status:
                status = status[0].value

            self._update = status == self._expected_status

            if status == 'error':
                self._errorMessage = request_body['errorMessage']

            return httmock.response(200, None, {}, request=request)

        update_url = '/api/v1/user/%s/aws/profiles/%s' % (profile['userId'],
                                                         profile['_id'])
        update = httmock.urlmatch(
            path=r'^%s$' % update_url, method='PATCH')(_update)

        self._expected_status = 'error'
        with httmock.HTTMock(update):
            key.generate_key_pair(profile, 'girder-token')

        self.assertTrue(self._update, 'Update was not called')
        self.assertTrue(self._errorMessage, 'No errorMessage set')

        # Now mock out EC2 and check for success
        self._update = False
        self._expected_status = 'available'
        ec2_client.create_key_pair.side_effect = None
        ec2_client.create_key_pair.return_value = {
            'KeyMaterial': 'dummy'
        }
        with httmock.HTTMock(update):
            key.generate_key_pair(profile, 'girder-token')
Example #12
0
    def setUp(self):
        status_url = '%s/login' % newt_base_url

        data = {
            'username': NewtClusterConnectionTestCase.USER,
            'password': NewtClusterConnectionTestCase.PASSWORD
        }

        r = requests.post(status_url, data=data)
        json_resp = r.json()

        self.assertTrue(json_resp['auth'])
        self.session_id = json_resp['newt_sessionid']

        self._cluster = {
            'type': 'newt',
            'config': {
                'host': 'cori'
            }
        }
        self._girder_token = 'dummy'

        def session_id(url, request):
            return self._session_id(url, request)

        url = '/api/v1/newt/sessionId'
        self.me = httmock.urlmatch(
            path=r'^%s$' % url, method='GET')(session_id)

        self.scratch_dir = '/global/cscratch1/sd/%s' % NewtClusterConnectionTestCase.USER
        self.test_data = 'nothing to see here!'
        self.test_case_dir = '%s/cumulus' % self.scratch_dir
        self.test_file_path = '%s/test.txt' % self.test_case_dir
        self.test_dir = '%s/cumulus' % self.test_case_dir

        # Create directory for test case
        with httmock.HTTMock(self.me):
            with get_connection(self._girder_token, self._cluster) as conn:
                conn.mkdir(self.test_case_dir)
Example #13
0
    def test_monitor_jobs_queued_no_retry(self, retry, get_connection):
        conn = get_connection.return_value.__enter__.return_value

        cluster = {
            '_id': 'lost',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job1_id = 'dummy1'
        job1_model = {
            '_id': job1_id,
            'queueJobId': '1',
            'name': 'dummy',
            'output': []
        }
        job2_id = 'dummy1'
        job2_model = {
            '_id': job2_id,
            'queueJobId': '2',
            'name': 'dummy',
            'output': []
        }


        conn.execute.return_value = [ 'job-ID  prior   name       user         state submit/start at     queue  slots ja-task-ID',
                             '-----------------------------------------------------------------------------------------']

        self._get_status_calls = {}
        self._set_status_calls = {}

        def _get_status(url, request):
            content = {
                'status': 'complete'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }
            job_id = url.path.split('/')[-2]

            self._get_status_calls[job_id]  = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {'status': 'complete', 'timings': {}, 'output': []}
            job_id = url.path.split('/')[-1]
            self._set_status_calls[job_id] = True
            self._set_status_called = json.loads(request.body) == expected

            return httmock.response(200, None, {}, request=request)

        job1_status_url = '/api/v1/jobs/%s/status' % job1_id
        job1_get_status = httmock.urlmatch(
            path=r'^%s$' % job1_status_url, method='GET')(_get_status)

        job1_status_update_url = '/api/v1/jobs/%s' % job1_id
        job1_set_status = httmock.urlmatch(
            path=r'^%s$' % job1_status_update_url, method='PATCH')(_set_status)

        job2_status_url = '/api/v1/jobs/%s/status' % job2_id
        job2_get_status = httmock.urlmatch(
            path=r'^%s$' % job2_status_url, method='GET')(_get_status)

        job2_status_update_url = '/api/v1/jobs/%s' % job2_id
        job2_set_status = httmock.urlmatch(
            path=r'^%s$' % job2_status_update_url, method='PATCH')(_set_status)

        with httmock.HTTMock(job1_get_status, job1_set_status,
                             job2_get_status, job2_set_status):
            job.monitor_jobs(cluster, [job1_model, job2_model], **{'girder_token': 's', 'log_write_url': 1})

        self.assertTrue(self._get_status_calls[job1_id])
        self.assertTrue(self._set_status_calls[job1_id])
        self.assertTrue(self._get_status_calls[job2_id])
        self.assertTrue(self._set_status_calls[job2_id])
        # All jobs are complete fo we shouldn't resheduled
        self.assertFalse(retry.call_args_list)
Example #14
0
from httmock import urlmatch

cim_url_match = urlmatch(scheme='https',
                         netloc=r'^api\.authorize\.net$',
                         path=r'^/xml/v1/request\.api$')

delete_success = (
    '<?xml version="1.0" encoding="utf-8"?>'
    '<{0}>'
    '<messages>'
    '<resultCode>Ok</resultCode>'
    '<message><code>I00001</code><text>Successful.</text></message>'
    '</messages>'
    '</{0}>')

customer_profile_success = (
    '<?xml version="1.0" encoding="utf-8"?>'
    '<{0}>'
    '<messages>'
    '<resultCode>Ok</resultCode>'
    '<message><code>I00001</code><text>Successful.</text></message>'
    '</messages>'
    '<customerProfileId>6666</customerProfileId>'
    '<customerPaymentProfileIdList>'
    '<numericString>7777</numericString>'
    '</customerPaymentProfileIdList>'
    '<customerShippingAddressIdList />'
    '<validationDirectResponseList />'
    '</{0}>')

payment_profile_success = (
Example #15
0
    def test_submit_job(self, get_connection, *args):

        cluster = {
            '_id': 'bob',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            },

        }
        job_id = 'dummy'
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{'tail': True,  'path': 'dummy/file/path'}]
        }

        qconf_output = ['pe_name            orte',
                        'slots              10\n',
                        'user_lists         NONE',
                        'xuser_lists        NONE',
                        'start_proc_args    /bin/true',
                        'stop_proc_args     /bin/true',
                        'allocation_rule    $pe_slots',
                        'control_slaves     FALSE',
                        'job_is_first_task  TRUE',
                        'urgency_slots      min',
                        'accounting_summary FALSE']

        qsub_output = ['Your job 74 ("test.sh") has been submitted']

        conn = get_connection.return_value.__enter__.return_value
        conn.execute.side_effect = [['/home/test'], qconf_output, qsub_output]

        def _get_status(url, request):
            content = {
                'status': 'queued'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            content = {
                'status': 'queued'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)

        def _log(url, request):
            content = {
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)


        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(
            path=r'^%s$' % status_url, method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(
            path=r'^%s$' % status_update_url, method='PATCH')(_set_status)

        log_url = '/api/v1/jobs/%s/log' % job_id
        log = httmock.urlmatch(
            path=r'^%s$' % log_url, method='POST')(_log)

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster, job_model, log_write_url='log_write_url',
                           girder_token='girder_token')

        self.assertEqual(conn.execute.call_args_list[1],
                         mock.call('qconf -sp orte'), 'Unexpected qconf command: %s' %
                         str(conn.execute.call_args_list[0]))

        # Specifying and parallel environment
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{'tail': True,  'path': 'dummy/file/path'}],
            'params': {
                'parallelEnvironment': 'mype'
            }
        }

        qconf_output = ['pe_name            mype',
                        'slots              10\n',
                        'user_lists         NONE',
                        'xuser_lists        NONE',
                        'start_proc_args    /bin/true',
                        'stop_proc_args     /bin/true',
                        'allocation_rule    $pe_slots',
                        'control_slaves     FALSE',
                        'job_is_first_task  TRUE',
                        'urgency_slots      min',
                        'accounting_summary FALSE']

        conn.reset_mock()
        conn.execute.side_effect = [['/home/test'], qconf_output, qsub_output]

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster, job_model, log_write_url='log_write_url',
                           girder_token='girder_token')
        self.assertEqual(conn.execute.call_args_list[1],
                         mock.call('qconf -sp mype'), 'Unexpected qconf command: %s' %
                         str(conn.execute.call_args_list[0]))

        # For traditional clusters we shouldn't try to extract slot from orte
        cluster = {
            '_id': 'dummy',
            'type': 'trad',
            'name': 'dummy',
            'config': {
                'host': 'dummy',
                'ssh': {
                    'user': '******',
                    'passphrase': 'its a secret'
                },
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_id = 'dummy'
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{'tail': True,  'path': 'dummy/file/path'}]
        }

        conn.reset_mock()
        conn.execute.side_effect = [['/home/test'], ['Your job 74 ("test.sh") has been submitted']]

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster, job_model, log_write_url='log_write_url',
                           girder_token='girder_token')

        # Assert that we don't try and get the number of slots
        self.assertFalse('qconf' in str(conn.execute.call_args_list), 'qconf should not be called')

        # For traditional clusters define a parallel env
        cluster = {
            '_id': 'dummy',
            'type': 'trad',
            'name': 'dummy',
            'config': {
                'host': 'dummy',
                'ssh': {
                    'user': '******',
                    'passphrase': 'its a secret'
                },
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_id = 'dummy'
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{'tail': True,  'path': 'dummy/file/path'}],
            'params': {
                'parallelEnvironment': 'mype'
            }
        }

        conn.reset_mock()
        conn.execute.side_effect = [['/home/test'], qconf_output, ['Your job 74 ("test.sh") has been submitted']]

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster, job_model, log_write_url='log_write_url',
                           girder_token='girder_token')

        self.assertEqual(conn.execute.call_args_list[1], mock.call('qconf -sp mype'))
        self.assertEqual(job_model['params']['numberOfSlots'], 10)
Example #16
0
    def test_monitor_job_tail_output(self, get_connection, retry, *args):

        job_id = 'dummy'
        cluster = {
            '_id': 'bill',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'output': [{
                'tail': True,
                'path': 'dummy/file/path'
            }],
            'dir': '/home/test'
        }

        conn = get_connection.return_value.__enter__.return_value
        conn.execute.side_effect = [
            'job-ID  prior   name       user         state submit/start at     queue  slots ja-task-ID',
            '-----------------------------------------------------------------------------------------',
            '1 0.00000 hostname   sgeadmin     r     09/09/2009 14:58:14                1'
        ], ['i have a tail', 'asdfas']

        def _get_status(url, request):
            content = {'status': 'running'}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._get_status_called = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {
                u'status':
                u'running',
                u'output': [{
                    u'content': [u'i have a tail', u'asdfas'],
                    u'path': u'dummy/file/path',
                    u'tail': True
                }],
                u'timings': {}
            }
            self._set_status_called = json.loads(
                request.body.decode('utf8')) == expected

            if not self._set_status_called:
                six.print_(json.loads(request.body.decode('utf8')),
                           file=sys.stderr)

            return httmock.response(200, None, {}, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(path=r'^%s$' % status_url,
                                      method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(path=r'^%s$' % status_update_url,
                                      method='PATCH')(_set_status)

        with httmock.HTTMock(get_status, set_status):
            job.monitor_job(cluster, job_model, **{
                'girder_token': 's',
                'log_write_url': 1
            })

        self.assertTrue(self._get_status_called,
                        'Expect get status endpoint to be hit')
        self.assertTrue(self._set_status_called,
                        'Expect set status endpoint to be hit')
Example #17
0
def common_interceptor(callback, **kwargs):
    decorator = urlmatch(**kwargs) if kwargs else all_requests
    mock = decorator(callback)
    return HTTMock(mock)
Example #18
0
from httmock import urlmatch


cim_url_match = urlmatch(scheme='https', netloc=r'^api\.authorize\.net$',
                         path=r'^/xml/v1/request\.api$')


delete_success = (
    '<?xml version="1.0" encoding="utf-8"?>'
    '<{0}>'
    '<messages>'
    '<resultCode>Ok</resultCode>'
    '<message><code>I00001</code><text>Successful.</text></message>'
    '</messages>'
    '</{0}>'
)


customer_profile_success = (
    '<?xml version="1.0" encoding="utf-8"?>'
    '<{0}>'
    '<messages>'
    '<resultCode>Ok</resultCode>'
    '<message><code>I00001</code><text>Successful.</text></message>'
    '</messages>'
    '<customerProfileId>6666</customerProfileId>'
    '<customerPaymentProfileIdList>'
    '<numericString>7777</numericString>'
    '</customerPaymentProfileIdList>'
    '<customerShippingAddressIdList />'
    '<validationDirectResponseList />'
Example #19
0
    def test_monitor_jobs_queued_no_retry(self, retry, get_connection):
        conn = get_connection.return_value.__enter__.return_value

        cluster = {
            '_id': 'lost',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job1_id = 'dummy1'
        job1_model = {
            '_id': job1_id,
            'queueJobId': '1',
            'name': 'dummy',
            'output': []
        }
        job2_id = 'dummy1'
        job2_model = {
            '_id': job2_id,
            'queueJobId': '2',
            'name': 'dummy',
            'output': []
        }

        conn.execute.return_value = [
            'job-ID  prior   name       user         state submit/start at     queue  slots ja-task-ID',
            '-----------------------------------------------------------------------------------------'
        ]

        self._get_status_calls = {}
        self._set_status_calls = {}

        def _get_status(url, request):
            content = {'status': 'complete'}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }
            job_id = url.path.split('/')[-2]

            self._get_status_calls[job_id] = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {'status': 'complete', 'timings': {}, 'output': []}
            job_id = url.path.split('/')[-1]
            self._set_status_calls[job_id] = True
            self._set_status_called = json.loads(
                request.body.decode('utf8')) == expected

            return httmock.response(200, None, {}, request=request)

        job1_status_url = '/api/v1/jobs/%s/status' % job1_id
        job1_get_status = httmock.urlmatch(path=r'^%s$' % job1_status_url,
                                           method='GET')(_get_status)

        job1_status_update_url = '/api/v1/jobs/%s' % job1_id
        job1_set_status = httmock.urlmatch(path=r'^%s$' %
                                           job1_status_update_url,
                                           method='PATCH')(_set_status)

        job2_status_url = '/api/v1/jobs/%s/status' % job2_id
        job2_get_status = httmock.urlmatch(path=r'^%s$' % job2_status_url,
                                           method='GET')(_get_status)

        job2_status_update_url = '/api/v1/jobs/%s' % job2_id
        job2_set_status = httmock.urlmatch(path=r'^%s$' %
                                           job2_status_update_url,
                                           method='PATCH')(_set_status)

        with httmock.HTTMock(job1_get_status, job1_set_status, job2_get_status,
                             job2_set_status):
            job.monitor_jobs(cluster, [job1_model, job2_model], **{
                'girder_token': 's',
                'log_write_url': 1
            })

        self.assertTrue(self._get_status_calls[job1_id])
        self.assertTrue(self._set_status_calls[job1_id])
        self.assertTrue(self._get_status_calls[job2_id])
        self.assertTrue(self._set_status_calls[job2_id])
        # All jobs are complete fo we shouldn't resheduled
        self.assertFalse(retry.call_args_list)
Example #20
0
    def test_monitor_job_terminated(self, get_connection):
        conn = get_connection.return_value.__enter__.return_value

        job_id = 'dummy'
        cluster = {
            '_id': 'bob',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_model = {
            '_id': job_id,
            'queueJobId': 'dummy',
            'name': 'dummy',
            'output': []
        }

        conn.execute.return_value = 'qstat output'

        def _get_status(url, request):
            content = {'status': 'terminating'}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._get_status_called = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {
                u'status': u'terminated',
                u'timings': {},
                u'output': []
            }

            self._set_status_called = json.loads(
                request.body.decode('utf8')) == expected

            return httmock.response(200, None, {}, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(path=r'^%s$' % status_url,
                                      method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(path=r'^%s$' % status_update_url,
                                      method='PATCH')(_set_status)

        with httmock.HTTMock(get_status, set_status):
            job.monitor_job(cluster, job_model, **{
                'girder_token': 's',
                'log_write_url': 1
            })

        self.assertTrue(self._get_status_called,
                        'Expect get status endpoint to be hit')
        self.assertTrue(self._set_status_called,
                        'Expect set status endpoint to be hit')
Example #21
0
    def test_submit_job(self, get_connection, *args):

        cluster = {
            '_id': 'bob',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            },
        }
        job_id = 'dummy'
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{
                'tail': True,
                'path': 'dummy/file/path'
            }]
        }

        qconf_output = [
            'pe_name            orte', 'slots              10\n',
            'user_lists         NONE', 'xuser_lists        NONE',
            'start_proc_args    /bin/true', 'stop_proc_args     /bin/true',
            'allocation_rule    $pe_slots', 'control_slaves     FALSE',
            'job_is_first_task  TRUE', 'urgency_slots      min',
            'accounting_summary FALSE'
        ]

        qsub_output = ['Your job 74 ("test.sh") has been submitted']

        conn = get_connection.return_value.__enter__.return_value
        conn.execute.side_effect = [['/home/test'], qconf_output, qsub_output]

        def _get_status(url, request):
            content = {'status': 'queued'}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            content = {'status': 'queued'}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)

        def _log(url, request):
            content = {}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(path=r'^%s$' % status_url,
                                      method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(path=r'^%s$' % status_update_url,
                                      method='PATCH')(_set_status)

        log_url = '/api/v1/jobs/%s/log' % job_id
        log = httmock.urlmatch(path=r'^%s$' % log_url, method='POST')(_log)

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster,
                           job_model,
                           log_write_url='log_write_url',
                           girder_token='girder_token')

        self.assertEqual(
            conn.execute.call_args_list[1], mock.call('qconf -sp orte'),
            'Unexpected qconf command: %s' %
            str(conn.execute.call_args_list[0]))

        # Specifying and parallel environment
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{
                'tail': True,
                'path': 'dummy/file/path'
            }],
            'params': {
                'parallelEnvironment': 'mype'
            }
        }

        qconf_output = [
            'pe_name            mype', 'slots              10\n',
            'user_lists         NONE', 'xuser_lists        NONE',
            'start_proc_args    /bin/true', 'stop_proc_args     /bin/true',
            'allocation_rule    $pe_slots', 'control_slaves     FALSE',
            'job_is_first_task  TRUE', 'urgency_slots      min',
            'accounting_summary FALSE'
        ]

        conn.reset_mock()
        conn.execute.side_effect = [['/home/test'], qconf_output, qsub_output]

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster,
                           job_model,
                           log_write_url='log_write_url',
                           girder_token='girder_token')
        self.assertEqual(
            conn.execute.call_args_list[1], mock.call('qconf -sp mype'),
            'Unexpected qconf command: %s' %
            str(conn.execute.call_args_list[0]))

        # For traditional clusters we shouldn't try to extract slot from orte
        cluster = {
            '_id': 'dummy',
            'type': 'trad',
            'name': 'dummy',
            'config': {
                'host': 'dummy',
                'ssh': {
                    'user': '******',
                    'passphrase': 'its a secret'
                },
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_id = 'dummy'
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{
                'tail': True,
                'path': 'dummy/file/path'
            }]
        }

        conn.reset_mock()
        conn.execute.side_effect = [[
            '/home/test'
        ], ['Your job 74 ("test.sh") has been submitted']]

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster,
                           job_model,
                           log_write_url='log_write_url',
                           girder_token='girder_token')

        # Assert that we don't try and get the number of slots
        self.assertFalse('qconf' in str(conn.execute.call_args_list),
                         'qconf should not be called')

        # For traditional clusters define a parallel env
        cluster = {
            '_id': 'dummy',
            'type': 'trad',
            'name': 'dummy',
            'config': {
                'host': 'dummy',
                'ssh': {
                    'user': '******',
                    'passphrase': 'its a secret'
                },
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_id = 'dummy'
        job_model = {
            '_id': job_id,
            'queueJobId': '1',
            'name': 'dummy',
            'commands': ['ls'],
            'output': [{
                'tail': True,
                'path': 'dummy/file/path'
            }],
            'params': {
                'parallelEnvironment': 'mype'
            }
        }

        conn.reset_mock()
        conn.execute.side_effect = [[
            '/home/test'
        ], qconf_output, ['Your job 74 ("test.sh") has been submitted']]

        with httmock.HTTMock(get_status, set_status, log):
            job.submit_job(cluster,
                           job_model,
                           log_write_url='log_write_url',
                           girder_token='girder_token')

        self.assertEqual(conn.execute.call_args_list[1],
                         mock.call('qconf -sp mype'))
        self.assertEqual(job_model['params']['numberOfSlots'], 10)
Example #22
0
    def test_monitor_job_complete(self, get_connection):
        conn = get_connection.return_value.__enter__.return_value
        conn.stat.return_value.st_size = 0

        job_id = 'dummy'
        cluster = {
            '_id': 'dummy',
            'type': 'ec2',
            'name': 'dummy',
             'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_model = {
            '_id': job_id,
            'queueJobId': 'dummy',
            'name': 'dummy',
            'output': [{
                'itemId': 'dummy'
            }],
            'dir': '/home/test/%s' % job_id
        }

        conn.execute.return_value = 'qstat output'

        def _get_status(url, request):
            content = {
                'status': 'running'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._get_status_called  = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {'status': 'uploading', 'timings': {}, 'output': [{'itemId': u'dummy'}]}
            self._set_status_called = json.loads(request.body) == expected

            return httmock.response(200, None, {}, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(
            path=r'^%s$' % status_url, method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(
            path=r'^%s$' % status_update_url, method='PATCH')(_set_status)

        with httmock.HTTMock(get_status, set_status):
            job.monitor_job(cluster, job_model, **{'girder_token': 's', 'log_write_url': 1})

        self.assertTrue(self._get_status_called, 'Expect get status endpoint to be hit')
        self.assertTrue(self._set_status_called, 'Expect set status endpoint to be hit')
        expected_calls = [[[{u'config': {u'_id': u'dummy', u'scheduler': {u'type': u'sge'}}, u'name': u'dummy', u'type': u'ec2', u'_id': u'dummy'}, {u'status': u'uploading', u'output': [{u'itemId': u'dummy'}], u'_id': u'dummy', u'queueJobId': u'dummy', u'name': u'dummy', u'dir': u'/home/test/dummy'}], {u'girder_token': u's', u'log_write_url': 1, u'job_dir': u'/home/test/dummy'}]]
        self.assertCalls(self._upload_job_output.call_args_list, expected_calls)
Example #23
0
    def test_connection(self, get_connection):

        def valid(self):
            return True

        cluster_id = 'dummy_id'
        cluster_model = {
            'type': 'trad',
            'name': 'my trad cluster',
            'config': {
                'conn': {
                    'user': '******'
                },
                'host': 'myhost'
            },
            '_id': cluster_id
        }

        self._set_call_value_index = 0
        def _set_status(url, request):
            expected = {'status': self._expected_status}
            self._set_status_called = True
            self._set_status_valid = json.loads(request.body) == expected
            self._set_status_request = request.body

            return httmock.response(200, None, {}, request=request)

        status_update_url = '/api/v1/clusters/%s' % cluster_id
        set_status = httmock.urlmatch(
            path=r'^%s$' % status_update_url, method='PATCH')(_set_status)

        def _log(url, request):
            return httmock.response(200, None, {}, request=request)

        log_url = '/api/v1/clusters/%s/log' % cluster_id
        log = httmock.urlmatch(
            path=r'^%s$' % log_url, method='POST')(_log)

        with httmock.HTTMock(set_status, log):
            cluster.test_connection(cluster_model, **{'girder_token': 's'})

        self.assertTrue(self._set_status_called, 'Set status endpoint not called')
        self.assertTrue(self._set_status_valid,
                        'Set status endpoint called with incorrect content: %s'
                            % self._set_status_request)

        # Mock our conn calls and try again
        def _get_cluster(url, request):
            content =   {
                "_id": "55ef53bff657104278e8b185",
                "config": {
                    "host": "ulmus",
                    "conn": {
                        "publicKey": "conn-rsa dummy",
                        'passphrase': 'dummy',
                        "user": "******"
                    }
                }
            }

            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }
            return httmock.response(200, content, headers, request=request)

        cluster_url = '/api/v1/clusters/%s' % cluster_id
        get_cluster = httmock.urlmatch(
            path=r'^%s$' % cluster_url, method='GET')(_get_cluster)


        conn = get_connection.return_value.__enter__.return_value
        conn.execute.return_value = ['/usr/bin/qsub']
        self._expected_status = 'running'
        with httmock.HTTMock(set_status, get_cluster):
            cluster.test_connection(cluster_model, **{'girder_token': 's', 'log_write_url': 'http://localhost/log'})

        self.assertTrue(self._set_status_called, 'Set status endpoint not called')
        self.assertTrue(self._set_status_valid,
                        'Set status endpoint called in incorrect content: %s'
                            % self._set_status_request)
Example #24
0
    def test_import_path(self):
        file = {
                'name': 'test.txt',
                'mode': 1,
                'size': 123
        }

        folder = {
                  'name':  'folder',
                  'mode': stat.S_IFDIR,
                  'size': 1234
        }

        cluster_connection = mock.MagicMock()
        cluster_connection.list.side_effect = [[file, folder], [file]]

        girder_token = 'dummy'
        parent = {
            '_id': 'dummy_id'
        }
        path = '/my/path'
        assetstore_id = 'dummy_id'

        # Mock create item
        def _create_item(url, request):
            content = {
                '_id': 'dummy'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._item_requests.append(request)

            return httmock.response(200, content, headers, request=request)

        item_url = '/api/v1/item'
        create_item = httmock.urlmatch(
            path=r'^%s$' % item_url, method='POST')(_create_item)

        # Mock create file
        def _create_file(url, request):
            content = {
                '_id': 'dummy'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._file_requests.append(request)

            return httmock.response(200, content, headers, request=request)

        file_url = '/api/v1/sftp_assetstores/%s/files' % assetstore_id
        create_file = httmock.urlmatch(
            path=r'^%s$' % file_url, method='POST')(_create_file)

        # Mock create folder
        def _create_folder(url, request):
            content = {
                '_id': 'dummy'
            }
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._folder_requests.append(request)

            return httmock.response(200, content, headers, request=request)

        folder_url = '/api/v1/folder'
        create_folder = httmock.urlmatch(
            path=r'^%s$' % folder_url, method='POST')(_create_folder)

        # Mock list folder
        def _list_folder(url, request):
            content = []
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            return httmock.response(200, content, headers, request=request)

        folder_url = '/api/v1/folder'
        list_folder = httmock.urlmatch(
            path=r'^%s$' % folder_url, method='GET')(_list_folder)

        with httmock.HTTMock(create_item, create_file, create_folder, list_folder):
            download_path(cluster_connection, girder_token, parent, path,
                'sftp_assetstores', assetstore_id, upload=False)


        self.assertEqual(len(self._item_requests), 2)
        self.assertEqual(len(self._file_requests), 2)
        self.assertEqual(len(self._folder_requests), 1)
    def test_connection(self, get_connection):

        def valid(self):
            return True

        cluster_id = 'dummy_id'
        cluster_model = {
            'type': 'trad',
            'name': 'my trad cluster',
            'config': {
                'conn': {
                    'user': '******'
                },
                'host': 'myhost'
            },
            '_id': cluster_id
        }

        self._set_call_value_index = 0
        def _set_status(url, request):
            expected = {'status': self._expected_status}
            self._set_status_called = True
            self._set_status_valid = json.loads(request.body.decode('utf8')) == expected
            self._set_status_request = request.body.decode('utf8')

            return httmock.response(200, None, {}, request=request)

        status_update_url = '/api/v1/clusters/%s' % cluster_id
        set_status = httmock.urlmatch(
            path=r'^%s$' % status_update_url, method='PATCH')(_set_status)

        def _log(url, request):
            return httmock.response(200, None, {}, request=request)

        log_url = '/api/v1/clusters/%s/log' % cluster_id
        log = httmock.urlmatch(
            path=r'^%s$' % log_url, method='POST')(_log)

        with httmock.HTTMock(set_status, log):
            cluster.test_connection(cluster_model, **{'girder_token': 's'})

        self.assertTrue(self._set_status_called, 'Set status endpoint not called')
        self.assertTrue(self._set_status_valid,
                        'Set status endpoint called with incorrect content: %s'
                            % self._set_status_request)

        # Mock our conn calls and try again
        def _get_cluster(url, request):
            content =   {
                "_id": "55ef53bff657104278e8b185",
                "config": {
                    "host": "ulmus",
                    "conn": {
                        "publicKey": "conn-rsa dummy",
                        'passphrase': 'dummy',
                        "user": "******"
                    }
                }
            }

            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }
            return httmock.response(200, content, headers, request=request)

        cluster_url = '/api/v1/clusters/%s' % cluster_id
        get_cluster = httmock.urlmatch(
            path=r'^%s$' % cluster_url, method='GET')(_get_cluster)


        conn = get_connection.return_value.__enter__.return_value
        conn.execute.return_value = ['/usr/bin/qsub']
        self._expected_status = 'running'
        with httmock.HTTMock(set_status, get_cluster):
            cluster.test_connection(cluster_model, **{'girder_token': 's', 'log_write_url': 'http://localhost/log'})

        self.assertTrue(self._set_status_called, 'Set status endpoint not called')
        self.assertTrue(self._set_status_valid,
                        'Set status endpoint called in incorrect content: %s'
                            % self._set_status_request)
Example #26
0
    def test_monitor_job_complete(self, get_connection):
        conn = get_connection.return_value.__enter__.return_value
        conn.stat.return_value.st_size = 0

        job_id = 'dummy'
        cluster = {
            '_id': 'dummy',
            'type': 'ec2',
            'name': 'dummy',
            'config': {
                '_id': 'dummy',
                'scheduler': {
                    'type': 'sge'
                }
            }
        }
        job_model = {
            '_id': job_id,
            'queueJobId': 'dummy',
            'name': 'dummy',
            'output': [{
                'itemId': 'dummy'
            }],
            'dir': '/home/test/%s' % job_id
        }

        conn.execute.return_value = 'qstat output'

        def _get_status(url, request):
            content = {'status': 'running'}
            content = json.dumps(content).encode('utf8')
            headers = {
                'content-length': len(content),
                'content-type': 'application/json'
            }

            self._get_status_called = True
            return httmock.response(200, content, headers, request=request)

        def _set_status(url, request):
            expected = {
                'status': 'uploading',
                'timings': {},
                'output': [{
                    'itemId': u'dummy'
                }]
            }
            print('set_status')
            self._set_status_called = json.loads(
                request.body.decode('utf8')) == expected

            return httmock.response(200, None, {}, request=request)

        status_url = '/api/v1/jobs/%s/status' % job_id
        get_status = httmock.urlmatch(path=r'^%s$' % status_url,
                                      method='GET')(_get_status)

        status_update_url = '/api/v1/jobs/%s' % job_id
        set_status = httmock.urlmatch(path=r'^%s$' % status_update_url,
                                      method='PATCH')(_set_status)

        with httmock.HTTMock(get_status, set_status):
            job.monitor_job(cluster, job_model, **{
                'girder_token': 's',
                'log_write_url': 1
            })

        self.assertTrue(self._get_status_called,
                        'Expect get status endpoint to be hit')
        self.assertTrue(self._set_status_called,
                        'Expect set status endpoint to be hit')
        expected_calls = [[[{
            u'config': {
                u'_id': u'dummy',
                u'scheduler': {
                    u'type': u'sge'
                }
            },
            u'name': u'dummy',
            u'type': u'ec2',
            u'_id': u'dummy'
        }, {
            u'status': u'uploading',
            u'output': [{
                u'itemId': u'dummy'
            }],
            u'_id': u'dummy',
            u'queueJobId': u'dummy',
            u'name': u'dummy',
            u'dir': u'/home/test/dummy'
        }], {
            u'girder_token': u's',
            u'log_write_url': 1,
            u'job_dir': u'/home/test/dummy'
        }]]
        self.assertCalls(self._upload_job_output.call_args_list,
                         expected_calls)