def test_eta_min_is_ignored_on_first_poll(self):
        "eta_min/earliest_estimated_completion should not be used anymore"

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            now = datetime_in_future(0)
            eta_min, eta_max = datetime_in_future(10), datetime_in_future(30)
            session = mock.Mock()
            session.post = lambda path, _: choose_reply(path, {
                'problems/': '[%s]' % continue_reply(
                    '1', 'abc123', eta_min=eta_min, eta_max=eta_max, now=now)
            }, date=now)
            session.get = lambda path: choose_reply(path, {
                'problems/?id=1': '[%s]' % complete_no_answer_reply(
                    '1', 'abc123'),
                'problems/1/': complete_reply(
                    '1', 'abc123')
            }, date=now)
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                def assert_no_delay(s):
                    s and self.assertTrue(
                        abs(s - client.poll_backoff_min) < client.DEFAULTS['poll_backoff_min'])

                with mock.patch('time.sleep', assert_no_delay):
                    future = solver.sample_qubo({})
                    future.result()
    def test_submit_continue_then_ok_reply(self):
        """Handle polling for a complete problem."""

        now = datetime_in_future(0)
        eta_min, eta_max = datetime_in_future(10), datetime_in_future(30)

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {
                'problems/': '[%s]' % continue_reply(
                    '123', 'abc123', eta_min=eta_min, eta_max=eta_max, now=now)
            }, date=now)
            session.get = lambda a: choose_reply(a, {
                'problems/?id=123': '[%s]' % complete_no_answer_reply(
                    '123', 'abc123'),
                'problems/123/': complete_reply(
                    '123', 'abc123')
            }, date=now)
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                params = dict(num_reads=100)
                results = solver.sample_ising(linear, quadratic, **params)

                self._check(results, linear, quadratic, **params)

                # test future has eta_min and eta_max parsed correctly
                self.assertEqual(results.eta_min, eta_min)
                self.assertEqual(results.eta_max, eta_max)
    def test_immediate_polling_with_local_clock_unsynced(self):
        """First poll happens with minimal delay if local clock is way off from
        the remote/server clock."""

        with Client('endpoint', 'token') as client:
            badnow = datetime_in_future(100)
            client.session = mock.Mock()
            client.session.post = lambda path, _: choose_reply(
                path,
                {'endpoint/problems/': '[%s]' % continue_reply('1', 'abc123')},
                date=badnow)
            client.session.get = lambda path: choose_reply(path, {
                'endpoint/problems/?id=1':
                '[%s]' % complete_no_answer_reply('1', 'abc123'),
                'endpoint/problems/1/':
                complete_reply('1', 'abc123')
            },
                                                           date=badnow)

            solver = Solver(client, solver_data('abc123'))

            def assert_no_delay(s):
                s and self.assertTrue(
                    abs(s - client._POLL_BACKOFF_MIN) <
                    client._POLL_BACKOFF_MIN / 10.0)

            with mock.patch('time.sleep', assert_no_delay):
                future = solver.sample_qubo({})
                future.result()
    def test_submit_offset_wrong_offset_in_answer(self):
        """Energy levels don't match because offset in answer is respected, even if wrong"""

        # ising problem energy offset
        offset = 3
        answer_offset = 2 * offset      # make it wrong

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {
                'problems/': '[%s]' % complete_no_answer_reply(
                    '123', 'abc123')})
            session.get = lambda a: choose_reply(a, {
                'problems/123/': complete_reply(
                    '123', 'abc123', answer=dict(offset=answer_offset))})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                params = dict(num_reads=100)
                results = solver.sample_ising(linear, quadratic, offset, **params)

                # since SAPI response includes offset, Future shouldn't patch it;
                # but because the offset in answer is wrong, energies are off
                with self.assertRaises(AssertionError):
                    self._check(results, linear, quadratic, offset=offset, **params)
    def test_submit_continue_then_ok_reply(self):
        """Handle polling for a complete problem."""
        with Client('endpoint', 'token') as client:
            now = datetime_in_future(0)
            eta_min, eta_max = datetime_in_future(10), datetime_in_future(30)
            client.session = mock.Mock()
            client.session.post = lambda a, _: choose_reply(a, {
                'endpoint/problems/':
                '[%s]' % continue_reply(
                    '123', 'abc123', eta_min=eta_min, eta_max=eta_max, now=now)
            },
                                                            date=now)
            client.session.get = lambda a: choose_reply(a, {
                'endpoint/problems/?id=123':
                '[%s]' % complete_no_answer_reply('123', 'abc123'),
                'endpoint/problems/123/':
                complete_reply('123', 'abc123')
            },
                                                        date=now)
            solver = Solver(client, solver_data('abc123'))

            # Build a problem
            linear = {index: 1 for index in solver.nodes}
            quad = {key: -1 for key in solver.undirected_edges}
            results = solver.sample_ising(linear, quad, num_reads=100)

            self._check(results, linear, quad, 100)

            # test future has eta_min and eta_max parsed correctly
            self.assertEqual(results.eta_min, eta_min)
            self.assertEqual(results.eta_max, eta_max)
    def test_submit_bqm_qubo_ok_reply(self):
        """Handle a normal query and response."""

        qubo_msg_diff = dict(type="qubo")
        qubo_answer_diff = {
            'energies': 'AAAAAAAAAAA=',
            'solutions': 'AA==',
            'active_variables': 'AAAAAAQAAAA='
        }

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {
                'problems/': '[%s]' % complete_no_answer_reply(
                    '123', 'abc123')})
            session.get = lambda a: choose_reply(a, {
                'problems/123/': complete_reply(
                    '123', 'abc123', answer=qubo_answer_diff, msg=qubo_msg_diff)})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                qubo = {(0, 0): 4.0, (0, 4): -4, (4, 4): 4.0}
                offset = -2.0
                params = dict(num_reads=100)

                results = solver.sample_qubo(qubo, offset, **params)

                # make sure energies are correct in raw results
                for energy, sample in zip(results.energies, results.samples):
                    self.assertEqual(energy, evaluate_ising({}, qubo, sample, offset=offset))
    def test_eta_min_is_ignored_on_first_poll(self):
        "eta_min/earliest_estimated_completion should not be used anymore"

        with Client('endpoint', 'token') as client:
            now = datetime_in_future(0)
            eta_min, eta_max = datetime_in_future(10), datetime_in_future(30)
            client.session = mock.Mock()
            client.session.post = lambda path, _: choose_reply(path, {
                'endpoint/problems/':
                '[%s]' % continue_reply(
                    '1', 'abc123', eta_min=eta_min, eta_max=eta_max, now=now)
            },
                                                               date=now)
            client.session.get = lambda path: choose_reply(path, {
                'endpoint/problems/?id=1':
                '[%s]' % complete_no_answer_reply('1', 'abc123'),
                'endpoint/problems/1/':
                complete_reply('1', 'abc123')
            },
                                                           date=now)

            solver = Solver(client, solver_data('abc123'))

            def assert_no_delay(s):
                s and self.assertTrue(
                    abs(s - client._POLL_BACKOFF_MIN) <
                    client._POLL_BACKOFF_MIN / 10.0)

            with mock.patch('time.sleep', assert_no_delay):
                future = solver.sample_qubo({})
                future.result()
    def test_immediate_polling_without_eta_min(self):
        "First poll happens with minimal delay if eta_min missing"

        # each thread can have its instance of a session because
        # responses are stateless
        def create_mock_session(client):
            now = datetime_in_future(0)
            session = mock.Mock()
            session.post = lambda path, _: choose_reply(
                path, {'problems/': '[%s]' % continue_reply('1', 'abc123')},
                date=now)
            session.get = lambda path: choose_reply(path, {
                'problems/?id=1':
                '[%s]' % complete_no_answer_reply('1', 'abc123'),
                'problems/1/':
                complete_reply('1', 'abc123')
            },
                                                    date=now)
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                def assert_no_delay(s):
                    s and self.assertTrue(
                        abs(s - client.poll_backoff_min) <
                        client._DEFAULT_POLL_BACKOFF_MIN)

                with mock.patch('time.sleep', assert_no_delay):
                    future = solver.sample_qubo({})
                    future.result()
Esempio n. 9
0
    def test_immediate_polling_with_local_clock_unsynced(self):
        """First poll happens with minimal delay if local clock is way off from
        the remote/server clock."""

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            badnow = datetime_in_future(100)
            session = mock.Mock()
            session.post = lambda path, _: choose_reply(
                path, {'problems/': '[%s]' % continue_reply('1', 'abc123')},
                date=badnow)
            session.get = lambda path: choose_reply(path, {
                'problems/?id=1':
                '[%s]' % complete_no_answer_reply('1', 'abc123'),
                'problems/1/':
                complete_reply('1', 'abc123')
            },
                                                    date=badnow)
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                def assert_no_delay(s):
                    s and self.assertTrue(
                        abs(s - client._POLL_BACKOFF_MIN) <
                        client._POLL_BACKOFF_MIN / 10.0)

                with mock.patch('time.sleep', assert_no_delay):
                    future = solver.sample_qubo({})
                    future.result()
Esempio n. 10
0
    def test_cancel_with_id(self):
        """Make sure the cancel method submits to the right endpoint.

        When cancel is called after the submission is finished.
        """
        submission_id = 'test-id'

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            reply_body = '[%s]' % continue_reply(submission_id, 'solver')
            session.get = lambda a: choose_reply(
                a, {'problems/?id={}'.format(submission_id): reply_body})
            session.delete = DeleteEvent.handle
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))
                future = solver._retrieve_problem(submission_id)
                future.cancel()

                try:
                    self.assertTrue(future.id is not None)
                    future.samples
                    self.fail()
                except DeleteEvent as event:
                    if event.url == 'problems/':
                        self.assertEqual(event.body,
                                         '["{}"]'.format(submission_id))
                    else:
                        self.assertEqual(event.url,
                                         'problems/{}/'.format(submission_id))
    def test_answer_load_error(self):
        """Answer load error is propagated as exception."""

        error_code = 404
        error_message = 'Problem not found'

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda path, _: choose_reply(
                path, {
                    'problems/': '[%s]' % complete_no_answer_reply(
                        '123', 'abc123')
                })
            session.get = lambda path: choose_reply(
                path,
                replies={'problems/123/': error_message},
                statuses={'problems/123/': iter([error_code])})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                future = solver.sample_ising(linear, quadratic)

                with self.assertRaises(SolverError) as exc:
                    future.result()

                self.assertEqual(str(exc.exception), error_message)
    def test_cancel_with_id(self):
        """Make sure the cancel method submits to the right endpoint.

        When cancel is called after the submission is finished.
        """
        submission_id = 'test-id'
        reply_body = '[%s]' % continue_reply(submission_id, 'solver')

        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()

            client.session.get = lambda a: choose_reply(
                a,
                {'endpoint/problems/?id={}'.format(submission_id): reply_body})
            client.session.delete = DeleteEvent.handle

            solver = Solver(client, solver_data('abc123'))
            future = solver._retrieve_problem(submission_id)
            future.cancel()

            try:
                self.assertTrue(future.id is not None)
                future.samples
                self.fail()
            except DeleteEvent as event:
                if event.url == 'endpoint/problems/':
                    self.assertEqual(event.body,
                                     '["{}"]'.format(submission_id))
                else:
                    self.assertEqual(
                        event.url,
                        'endpoint/problems/{}/'.format(submission_id))
    def test_submit_bqm_ising_ok_reply(self):
        """Handle a normal query and response."""

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {
                'problems/':
                '[%s]' % complete_no_answer_reply('123', 'abc123')
            })
            session.get = lambda a: choose_reply(
                a, {'problems/123/': complete_reply('123', 'abc123')})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                h, J = test_problem(solver)
                bqm = dimod.BinaryQuadraticModel.from_ising(h, J)

                params = dict(num_reads=100)
                results = solver.sample_bqm(bqm, **params)

                self._check(results, h, J, **params)
    def test_deprecations(self):
        """Proper deprecation warnings are raised."""
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {
                'problems/':
                '[%s]' % complete_no_answer_reply('123', 'abc123')
            })
            session.get = lambda a: choose_reply(
                a, {'problems/123/': complete_reply('123', 'abc123')})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                params = dict(num_reads=100)
                results = solver.sample_ising(linear, quadratic, **params)

                # aliased keys are deprecated in 0.8.0
                with self.assertWarns(DeprecationWarning):
                    results['samples']
                with self.assertWarns(DeprecationWarning):
                    results['occurrences']

                # .error is deprecated in 0.7.x, scheduled for removal in 0.9.0
                with self.assertWarns(DeprecationWarning):
                    results.error

                # .occurrences is deprecated in 0.8.0, scheduled for removal in 0.10.0+
                with self.assertWarns(DeprecationWarning):
                    results.occurrences
    def test_submit_offset_answer_does_not_include_it(self):
        """Handle a normal query with offset and response that doesn't include it."""

        # ising problem energy offset
        offset = 3

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {
                'problems/':
                '[%s]' % complete_no_answer_reply('123', 'abc123')
            })
            session.get = lambda a: choose_reply(
                a, {'problems/123/': complete_reply('123', 'abc123')})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                params = dict(num_reads=100)
                results = solver.sample_ising(linear, quadratic, offset,
                                              **params)

                # although SAPI response doesn't include offset, Future should patch it on-the-fly
                self._check(results,
                            linear,
                            quadratic,
                            offset=offset,
                            **params)
Esempio n. 16
0
    def test_submit_continue_then_error_reply(self):
        """Handle polling for an error message."""

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(
                a, {'problems/': '[%s]' % continue_reply('123', 'abc123')})
            session.get = lambda a: choose_reply(
                a, {
                    'problems/?id=123':
                    '[%s]' % error_reply('123', 'abc123', "error message")
                })
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                results = solver.sample_ising(linear, quadratic, num_reads=100)

                with self.assertRaises(SolverFailureError):
                    self._check(results, linear, quadratic, 100)
Esempio n. 17
0
    def test_polling_recovery_after_5xx(self):
        "Polling shouldn't be aborted on 5xx responses."

        # we need a "global session", because mocked responses are stateful
        def global_mock_session():
            session = mock.Mock()

            # on submit, return status pending
            session.post = lambda path, _: choose_reply(
                path, {'problems/': '[%s]' % continue_reply('123', 'abc123')})

            # on first and second status poll, fail with 503 and 504
            # on third status poll, return completed
            statuses = iter([503, 504])

            def continue_then_complete(path, state={'count': 0}):
                state['count'] += 1
                if state['count'] < 3:
                    return choose_reply(path,
                                        replies={
                                            'problems/?id=123':
                                            '[%s]' %
                                            continue_reply('123', 'abc123'),
                                            'problems/123/':
                                            continue_reply('123', 'abc123')
                                        },
                                        statuses={
                                            'problems/?id=123': statuses,
                                            'problems/123/': statuses
                                        })
                else:
                    return choose_reply(
                        path, {
                            'problems/?id=123':
                            '[%s]' % complete_no_answer_reply('123', 'abc123'),
                            'problems/123/':
                            complete_reply('123', 'abc123')
                        })

            session.get = continue_then_complete

            return session

        session = global_mock_session()

        with mock.patch.object(Client, 'create_session', lambda self: session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                future = solver.sample_qubo({})
                future.result()

                # after third poll, back-off interval should be 4 x initial back-off
                self.assertEqual(future._poll_backoff,
                                 Client._POLL_BACKOFF_MIN * 2**2)
    def test_submit_null_reply(self):
        """Get an error when the server's response is incomplete."""
        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            client.session.post = lambda a, _: choose_reply(
                a, {'endpoint/problems/': ''})
            solver = Solver(client, solver_data('abc123'))

            # Build a problem
            linear = {index: 1 for index in solver.nodes}
            quad = {key: -1 for key in solver.undirected_edges}
            results = solver.sample_ising(linear, quad, num_reads=100)

            with self.assertRaises(ValueError):
                results.samples
    def test_exponential_backoff_polling(self):
        "After each poll, back-off should double"

        # we need a "global session", because mocked responses are stateful
        def global_mock_session():
            session = mock.Mock()

            # on submit, return status pending
            session.post = lambda path, _: choose_reply(
                path, {'problems/': '[%s]' % continue_reply('123', 'abc123')})

            # on first and second status poll, return pending
            # on third status poll, return completed
            def continue_then_complete(path, state={'count': 0}):
                state['count'] += 1
                if state['count'] < 3:
                    return choose_reply(
                        path, {
                            'problems/?id=123':
                            '[%s]' % continue_reply('123', 'abc123'),
                            'problems/123/':
                            continue_reply('123', 'abc123')
                        })
                else:
                    return choose_reply(
                        path, {
                            'problems/?id=123':
                            '[%s]' % complete_no_answer_reply('123', 'abc123'),
                            'problems/123/':
                            complete_reply('123', 'abc123')
                        })

            session.get = continue_then_complete

            return session

        session = global_mock_session()

        with mock.patch.object(Client, 'create_session', lambda self: session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                future = solver.sample_qubo({})
                future.result()

                # after third poll, back-off interval should be 4 x initial back-off
                self.assertEqual(future._poll_backoff,
                                 client.poll_backoff_min * 2**2)
    def test_label_is_received(self, name, label):
        """Problem label is set from response in result/sampleset."""
        def make_session_generator(label):
            def create_mock_session(client):
                session = mock.Mock()
                session.post = lambda a, _: choose_reply(
                    a, {
                        'problems/':
                        '[%s]' % complete_no_answer_reply(
                            '123', 'abc123', label=None)
                    })
                session.get = lambda a: choose_reply(a, {
                    'problems/123/':
                    complete_reply('123', 'abc123', label=label)
                })
                return session

            return create_mock_session

        with mock.patch.object(Client, 'create_session',
                               make_session_generator(label)):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))
                problems = self.generate_sample_problems(solver)

                for method_name, problem_args in problems:
                    with self.subTest(method_name=method_name):
                        sample = getattr(solver, method_name)

                        future = sample(*problem_args, label=label)
                        info = future.sampleset.info  # ensure future is resolved

                        self.assertEqual(future.label, label)
                        self.assertEqual(info.get('problem_label'), label)
    def test_submit_cancel_reply(self):
        """Handle a response for a canceled job."""
        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            client.session.post = lambda a, _: choose_reply(
                a,
                {'endpoint/problems/': '[%s]' % cancel_reply('123', 'abc123')})
            solver = Solver(client, solver_data('abc123'))

            # Build a problem
            linear = {index: 1 for index in solver.nodes}
            quad = {key: -1 for key in solver.undirected_edges}
            results = solver.sample_ising(linear, quad, num_reads=100)

            with self.assertRaises(CanceledFutureError):
                results.samples
Esempio n. 22
0
    def test_cancel_without_id(self):
        """Make sure the cancel method submits to the right endpoint.

        When cancel is called before the submission has returned the problem id.
        """
        submission_id = 'test-id'
        release_reply = threading.Event()

        # each thread can have its instance of a session because
        # we use a global lock (event) in the mocked responses
        def create_mock_session(client):
            reply_body = '[%s]' % continue_reply(submission_id, 'solver')

            session = mock.Mock()
            session.get = lambda a: choose_reply(
                a, {'problems/?id={}'.format(submission_id): reply_body})

            def post(a, _):
                release_reply.wait()
                return choose_reply(a, {'problems/': reply_body})

            session.post = post
            session.delete = DeleteEvent.handle

            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)

                future = solver.sample_ising(linear, quadratic)
                future.cancel()

                try:
                    release_reply.set()
                    future.samples
                    self.fail()
                except DeleteEvent as event:
                    if event.url == 'problems/':
                        self.assertEqual(event.body,
                                         '["{}"]'.format(submission_id))
                    else:
                        self.assertEqual(event.url,
                                         'problems/{}/'.format(submission_id))
    def test_submit_immediate_error_reply(self):
        """Handle an (obvious) error on problem submission."""
        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            client.session.post = lambda a, _: choose_reply(
                a, {
                    'endpoint/problems/':
                    '[%s]' % immediate_error_reply(
                        400, "Missing parameter 'num_reads' in problem JSON")
                })
            solver = Solver(client, solver_data('abc123'))

            linear, quad = generate_random_ising_problem(solver)
            results = solver.sample_ising(linear, quad)

            with self.assertRaises(SolverFailureError):
                results.samples
    def test_submit_ok_reply(self):
        """Handle a normal query and response."""
        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            client.session.post = lambda a, _: choose_reply(
                a, {
                    'endpoint/problems/':
                    '[%s]' % complete_no_answer_reply('123', 'abc123')
                })
            client.session.get = lambda a: choose_reply(
                a, {'endpoint/problems/123/': complete_reply('123', 'abc123')})
            solver = Solver(client, solver_data('abc123'))

            # Build a problem
            linear = {index: 1 for index in solver.nodes}
            quad = {key: -1 for key in solver.undirected_edges}
            results = solver.sample_ising(linear, quad, num_reads=100)

            self._check(results, linear, quad, 100)
    def test_submit_error_reply(self):
        """Handle an error on problem submission."""
        error_body = 'An error message'
        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            client.session.post = lambda a, _: choose_reply(
                a, {
                    'endpoint/problems/':
                    '[%s]' % error_reply('123', 'abc123', error_body)
                })
            solver = Solver(client, solver_data('abc123'))

            # Build a problem
            linear = {index: 1 for index in solver.nodes}
            quad = {key: -1 for key in solver.undirected_edges}
            results = solver.sample_ising(linear, quad, num_reads=100)

            with self.assertRaises(SolverFailureError):
                results.samples
    def test_exponential_backoff_polling(self):
        "After each poll, back-off should double"

        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            # on submit, return status pending
            client.session.post = lambda path, _: choose_reply(
                path, {
                    'endpoint/problems/': '[%s]' % continue_reply(
                        '123', 'abc123')
                })

            # on first and second status poll, return pending
            # on third status poll, return completed
            def continue_then_complete(path, state={'count': 0}):
                state['count'] += 1
                if state['count'] < 3:
                    return choose_reply(
                        path, {
                            'endpoint/problems/?id=123':
                            '[%s]' % continue_reply('123', 'abc123'),
                            'endpoint/problems/123/':
                            continue_reply('123', 'abc123')
                        })
                else:
                    return choose_reply(
                        path, {
                            'endpoint/problems/?id=123':
                            '[%s]' % complete_no_answer_reply('123', 'abc123'),
                            'endpoint/problems/123/':
                            complete_reply('123', 'abc123')
                        })

            client.session.get = continue_then_complete

            solver = Solver(client, solver_data('abc123'))

            future = solver.sample_qubo({})
            future.result()

            # after third poll, back-off interval should be 4 x initial back-off
            self.assertEqual(future._poll_backoff,
                             Client._POLL_BACKOFF_MIN * 2**2)
Esempio n. 27
0
    def test_submit_null_reply(self):
        """Get an error when the server's response is incomplete."""

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(a, {'problems/': ''})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                results = solver.sample_ising(linear, quadratic, num_reads=100)

                with self.assertRaises(ValueError):
                    results.samples
Esempio n. 28
0
    def test_solver_feature_properties(self):
        self.assertTrue(solver_object('solver', 'qpu').qpu)
        self.assertTrue(solver_object('solver', 'QPU').qpu)
        self.assertFalse(solver_object('solver', 'qpu').software)
        self.assertFalse(solver_object('solver', 'qpu').hybrid)
        self.assertFalse(solver_object('solver', 'software').qpu)
        self.assertTrue(solver_object('solver', 'software').software)
        self.assertFalse(solver_object('solver', 'software').hybrid)
        self.assertTrue(solver_object('solver', 'hybrid').hybrid)
        self.assertFalse(solver_object('solver', 'hybrid').qpu)
        self.assertFalse(solver_object('solver', 'hybrid').software)

        self.assertFalse(solver_object('solver').is_vfyc)
        self.assertEqual(solver_object('solver').num_qubits, 3)
        self.assertFalse(solver_object('solver').has_flux_biases)

        # test .num_qubits vs .num_actual_qubits
        data = json.loads(structured_solver_data('test'))
        data['properties']['num_qubits'] = 7
        solver = Solver(None, data)
        self.assertEqual(solver.num_qubits, 7)
        self.assertEqual(solver.num_active_qubits, 3)

        # test .is_vfyc
        data = json.loads(structured_solver_data('test'))
        data['properties']['vfyc'] = 'error'
        self.assertFalse(Solver(None, data).is_vfyc)
        data['properties']['vfyc'] = True
        self.assertTrue(Solver(None, data).is_vfyc)

        # test .has_flux_biases
        self.assertFalse(Solver(None, data).has_flux_biases)
        data['properties']['parameters']['flux_biases'] = '...'
        self.assertTrue(Solver(None, data).has_flux_biases)

        # test .has_anneal_schedule
        self.assertFalse(Solver(None, data).has_anneal_schedule)
        data['properties']['parameters']['anneal_schedule'] = '...'
        self.assertTrue(Solver(None, data).has_anneal_schedule)

        # test `.online` property
        self.assertTrue(solver_object('solver').online)
        data = json.loads(structured_solver_data('test'))
        data['status'] = 'offline'
        self.assertFalse(Solver(None, data).online)
        del data['status']
        self.assertTrue(Solver(None, data).online)
    def test_cancel_without_id(self):
        """Make sure the cancel method submits to the right endpoint.

        When cancel is called before the submission has returned the problem id.
        """
        submission_id = 'test-id'
        reply_body = '[%s]' % continue_reply(submission_id, 'solver')

        release_reply = threading.Event()

        with Client('endpoint', 'token') as client:
            client.session = mock.Mock()
            client.session.get = lambda a: choose_reply(
                a,
                {'endpoint/problems/?id={}'.format(submission_id): reply_body})

            def post(a, _):
                release_reply.wait()
                return choose_reply(a, {'endpoint/problems/': reply_body})

            client.session.post = post
            client.session.delete = DeleteEvent.handle

            solver = Solver(client, solver_data('abc123'))
            # Build a problem
            linear = {index: 1 for index in solver.nodes}
            quad = {key: -1 for key in solver.undirected_edges}
            future = solver.sample_ising(linear, quad)
            future.cancel()

            try:
                release_reply.set()
                future.samples
                self.fail()
            except DeleteEvent as event:
                if event.url == 'endpoint/problems/':
                    self.assertEqual(event.body,
                                     '["{}"]'.format(submission_id))
                else:
                    self.assertEqual(
                        event.url,
                        'endpoint/problems/{}/'.format(submission_id))
Esempio n. 30
0
    def test_submit_cancel_reply(self):
        """Handle a response for a canceled job."""

        # each thread can have its instance of a session because
        # the mocked responses are stateless
        def create_mock_session(client):
            session = mock.Mock()
            session.post = lambda a, _: choose_reply(
                a, {'problems/': '[%s]' % cancel_reply('123', 'abc123')})
            return session

        with mock.patch.object(Client, 'create_session', create_mock_session):
            with Client('endpoint', 'token') as client:
                solver = Solver(client, solver_data('abc123'))

                linear, quadratic = test_problem(solver)
                results = solver.sample_ising(linear, quadratic, num_reads=100)

                with self.assertRaises(CanceledFutureError):
                    results.samples