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()
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()
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)
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)
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
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)
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
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))
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