class TestIBMQFactoryAccounts(IBMQTestCase): """Tests for account handling.""" @classmethod def setUpClass(cls): """Initial class setup.""" super().setUpClass() cls.token = 'API_TOKEN' def setUp(self): """Initial test setup.""" super().setUp() # Reference for saving accounts. self.factory = IBMQFactory() def test_save_account(self): """Test saving an account.""" with custom_qiskitrc(): self.factory.save_account(self.token, url=AUTH_URL) stored_cred = self.factory.stored_account() self.assertEqual(stored_cred['token'], self.token) self.assertEqual(stored_cred['url'], AUTH_URL) def test_save_account_specified_provider(self): """Test saving an account with a specified provider.""" default_hgp_to_save = 'default_hub/default_group/default_project' with custom_qiskitrc() as custom_qiskitrc_cm: hgp = HubGroupProject.from_stored_format(default_hgp_to_save) self.factory.save_account(token=self.token, url=AUTH_URL, hub=hgp.hub, group=hgp.group, project=hgp.project) # Ensure the `default_provider` name was written to the config file. config_parser = ConfigParser() config_parser.read(custom_qiskitrc_cm.tmp_file.name) for name in config_parser.sections(): single_credentials = dict(config_parser.items(name)) self.assertIn('default_provider', single_credentials) self.assertEqual(single_credentials['default_provider'], default_hgp_to_save) def test_save_account_specified_provider_invalid(self): """Test saving an account without specifying all the hub/group/project fields.""" invalid_hgps_to_save = [ HubGroupProject('', 'default_group', ''), HubGroupProject('default_hub', None, 'default_project') ] for invalid_hgp in invalid_hgps_to_save: with self.subTest(invalid_hgp=invalid_hgp), custom_qiskitrc(): with self.assertRaises( IBMQAccountValueError) as context_manager: self.factory.save_account(token=self.token, url=AUTH_URL, hub=invalid_hgp.hub, group=invalid_hgp.group, project=invalid_hgp.project) self.assertIn( 'The hub, group, and project parameters must all be specified', str(context_manager.exception)) def test_delete_account(self): """Test deleting an account.""" with custom_qiskitrc(): self.factory.save_account(self.token, url=AUTH_URL) self.factory.delete_account() stored_cred = self.factory.stored_account() self.assertEqual(len(stored_cred), 0) @requires_qe_access def test_load_account(self, qe_token, qe_url): """Test loading an account.""" if qe_url != QX_AUTH_URL: # .save_account() expects an auth production URL. self.skipTest('Test requires production auth URL') with no_file('Qconfig.py'), custom_qiskitrc(), no_envs( CREDENTIAL_ENV_VARS): self.factory.save_account(qe_token, url=qe_url) self.factory.load_account() self.assertEqual(self.factory._credentials.token, qe_token) self.assertEqual(self.factory._credentials.url, qe_url) @requires_qe_access def test_load_account_saved_provider(self, qe_token, qe_url): """Test loading an account that contains a saved provider.""" if qe_url != QX_AUTH_URL: # .save_account() expects an auth production URL. self.skipTest('Test requires production auth URL') # Get a non default provider. non_default_provider = get_provider(self.factory, qe_token, qe_url, default=False) with no_file('Qconfig.py'), custom_qiskitrc(), no_envs( CREDENTIAL_ENV_VARS): self.factory.save_account( token=qe_token, url=qe_url, hub=non_default_provider.credentials.hub, group=non_default_provider.credentials.group, project=non_default_provider.credentials.project) saved_provider = self.factory.load_account() if saved_provider != non_default_provider: # Prevent tokens from being logged. saved_provider.credentials.token = None non_default_provider.credentials.token = None self.fail( "loaded default provider ({}) != expected ({})".format( saved_provider.credentials.__dict__, non_default_provider.credentials.__dict__)) self.assertEqual(self.factory._credentials.token, qe_token) self.assertEqual(self.factory._credentials.url, qe_url) @requires_qe_access def test_load_account_saved_provider_invalid_hgp(self, qe_token, qe_url): """Test loading an account that contains a saved provider that does not exist.""" if qe_url != QX_AUTH_URL: # .save_account() expects an auth production URL. self.skipTest('Test requires production auth URL') # Hub, group, project in correct format but does not exists. invalid_hgp_to_store = 'invalid_hub/invalid_group/invalid_project' with no_file('Qconfig.py'), custom_qiskitrc(), no_envs( CREDENTIAL_ENV_VARS): hgp = HubGroupProject.from_stored_format(invalid_hgp_to_store) self.factory.save_account(token=qe_token, url=qe_url, hub=hgp.hub, group=hgp.group, project=hgp.project) with self.assertRaises(IBMQAccountError) as context_manager: self.factory.load_account() self.assertIn( '(hub/group/project) stored on disk could not be found', str(context_manager.exception)) def test_load_account_saved_provider_invalid_format(self): """Test loading an account that contains a saved provider in an invalid format.""" # Format {'test_case_input': 'error message from raised exception'} invalid_hgps = { 'hub_group_project': 'Use the "<hub_name>/<group_name>/<project_name>" format', 'default_hub//default_project': 'Every field must be specified', 'default_hub/default_group/': 'Every field must be specified' } for invalid_hgp, error_message in invalid_hgps.items(): with self.subTest(invalid_hgp=invalid_hgp): with no_file('Qconfig.py'), custom_qiskitrc() as temp_qiskitrc, \ no_envs(CREDENTIAL_ENV_VARS): # Save the account. self.factory.save_account(token=self.token, url=AUTH_URL) # Add an invalid provider field to the account stored. with open(temp_qiskitrc.tmp_file.name, 'a') as _file: _file.write( 'default_provider = {}'.format(invalid_hgp)) # Ensure an error is raised if the stored provider is in an invalid format. with self.assertRaises( IBMQAccountError) as context_manager: self.factory.load_account() self.assertIn(error_message, str(context_manager.exception)) @requires_qe_access def test_disable_account(self, qe_token, qe_url): """Test disabling an account """ self.factory.enable_account(qe_token, qe_url) self.factory.disable_account() self.assertIsNone(self.factory._credentials) @requires_qe_access def test_active_account(self, qe_token, qe_url): """Test active_account for an account """ self.assertIsNone(self.factory.active_account()) self.factory.enable_account(qe_token, qe_url) active_account = self.factory.active_account() self.assertIsNotNone(active_account) self.assertEqual(active_account['token'], qe_token) self.assertEqual(active_account['url'], qe_url) def test_save_token_invalid(self): """Test saving an account with invalid tokens. See #391.""" invalid_tokens = [None, '', 0] for invalid_token in invalid_tokens: with self.subTest(invalid_token=invalid_token): with self.assertRaises( IBMQAccountCredentialsInvalidToken) as context_manager: self.factory.save_account(token=invalid_token) self.assertIn('Invalid IBM Quantum Experience token', str(context_manager.exception))
class TestIBMQFactoryAccounts(IBMQTestCase): """Tests for the IBMQ account handling.""" @classmethod def setUpClass(cls): cls.v2_token = 'API2_TOKEN' cls.v1_token = 'API1_TOKEN' def setUp(self): super().setUp() # Reference for saving accounts. self.factory = IBMQFactory() self.provider = IBMQProvider() def test_save_account_v2(self): """Test saving an API 2 account.""" with custom_qiskitrc(): self.factory.save_account(self.v2_token, url=AUTH_URL) stored_cred = self.factory.stored_account() self.assertEqual(stored_cred['token'], self.v2_token) self.assertEqual(stored_cred['url'], AUTH_URL) def test_stored_account_v1(self): """Test listing a stored API 1 account.""" with custom_qiskitrc(): self.provider.save_account(self.v1_token, url=API1_URL) with self.assertRaises(IBMQAccountError): self.factory.stored_account() def test_delete_account_v2(self): """Test deleting an API 2 account.""" with custom_qiskitrc(): self.factory.save_account(self.v2_token, url=AUTH_URL) self.factory.delete_account() stored_cred = self.factory.stored_account() self.assertEqual(len(stored_cred), 0) def test_delete_account_v1(self): """Test deleting an API 1 account.""" with custom_qiskitrc(): self.provider.save_account(self.v1_token, url=API1_URL) with self.assertRaises(IBMQAccountError): self.factory.delete_account() @requires_qe_access @requires_new_api_auth def test_load_account_v2(self, qe_token, qe_url): """Test loading an API 2 account.""" if qe_url != QX_AUTH_URL: # .save_account() expects an auth 2 production URL. self.skipTest('Test requires production auth URL') with no_file('Qconfig.py'), custom_qiskitrc(), no_envs( CREDENTIAL_ENV_VARS): self.factory.save_account(qe_token, url=qe_url) self.factory.load_account() self.assertEqual(self.factory._credentials.token, qe_token) self.assertEqual(self.factory._credentials.url, qe_url) self.assertEqual(self.factory._v1_provider._accounts, {}) def test_load_account_v1(self): """Test loading an API 1 account.""" with no_file('Qconfig.py'), custom_qiskitrc(), no_envs( CREDENTIAL_ENV_VARS): self.provider.save_account(self.v1_token, url=API1_URL) with self.assertRaises(IBMQAccountError): self.factory.load_account() @requires_qe_access @requires_new_api_auth def test_disable_account_v2(self, qe_token, qe_url): """Test disabling an API 2 account """ self.factory.enable_account(qe_token, qe_url) self.factory.disable_account() self.assertIsNone(self.factory._credentials) @requires_qe_access @requires_classic_api def test_disable_account_v1(self, qe_token, qe_url): """Test disabling an API 1 account """ self.factory.enable_account(qe_token, qe_url) with self.assertRaises(IBMQAccountError): self.factory.disable_account() @requires_qe_access @requires_new_api_auth def test_active_account_v2(self, qe_token, qe_url): """Test active_account for an API 2 account """ self.assertIsNone(self.factory.active_account()) self.factory.enable_account(qe_token, qe_url) active_account = self.factory.active_account() self.assertIsNotNone(active_account) self.assertEqual(active_account['token'], qe_token) self.assertEqual(active_account['url'], qe_url) @requires_qe_access @requires_classic_api def test_active_account_v1(self, qe_token, qe_url): """Test active_account for an API 1 account """ self.factory.enable_account(qe_token, qe_url) with self.assertRaises(IBMQAccountError): self.factory.active_account()
class TestIBMQFactoryAccounts(IBMQTestCase): """Tests for account handling.""" @classmethod def setUpClass(cls): """Initial class setup.""" super().setUpClass() cls.token = 'API_TOKEN' def setUp(self): """Initial test setup.""" super().setUp() # Reference for saving accounts. self.factory = IBMQFactory() def test_save_account(self): """Test saving an account.""" with custom_qiskitrc(): self.factory.save_account(self.token, url=AUTH_URL) stored_cred = self.factory.stored_account() self.assertEqual(stored_cred['token'], self.token) self.assertEqual(stored_cred['url'], AUTH_URL) def test_delete_account(self): """Test deleting an account.""" with custom_qiskitrc(): self.factory.save_account(self.token, url=AUTH_URL) self.factory.delete_account() stored_cred = self.factory.stored_account() self.assertEqual(len(stored_cred), 0) @requires_qe_access def test_load_account(self, qe_token, qe_url): """Test loading an account.""" if qe_url != QX_AUTH_URL: # .save_account() expects an auth production URL. self.skipTest('Test requires production auth URL') with no_file('Qconfig.py'), custom_qiskitrc(), no_envs( CREDENTIAL_ENV_VARS): self.factory.save_account(qe_token, url=qe_url) self.factory.load_account() self.assertEqual(self.factory._credentials.token, qe_token) self.assertEqual(self.factory._credentials.url, qe_url) @requires_qe_access def test_disable_account(self, qe_token, qe_url): """Test disabling an account """ self.factory.enable_account(qe_token, qe_url) self.factory.disable_account() self.assertIsNone(self.factory._credentials) @requires_qe_access def test_active_account(self, qe_token, qe_url): """Test active_account for an account """ self.assertIsNone(self.factory.active_account()) self.factory.enable_account(qe_token, qe_url) active_account = self.factory.active_account() self.assertIsNotNone(active_account) self.assertEqual(active_account['token'], qe_token) self.assertEqual(active_account['url'], qe_url) def test_save_none_token(self): """Test saving an account with token=None. See #391""" with self.assertRaises( IBMQAccountCredentialsInvalidToken) as context_manager: self.factory.save_account(None) self.assertIn('Invalid IBM Quantum Experience token', str(context_manager.exception)) def test_save_empty_token(self): """Test saving an account with token=''. See #391""" with self.assertRaises( IBMQAccountCredentialsInvalidToken) as context_manager: self.factory.save_account('') self.assertIn('Invalid IBM Quantum Experience token', str(context_manager.exception)) def test_save_zero_token(self): """Test saving an account with token=0. See #391""" with self.assertRaises( IBMQAccountCredentialsInvalidToken) as context_manager: self.factory.save_account(0) self.assertIn('Invalid IBM Quantum Experience token', str(context_manager.exception))
# obtain a copy of this license in the LICENSE.txt file in the root directory # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. # pylint: disable=unused-argument """Account functionality""" from qiskit.exceptions import QiskitError from qiskit.providers.ibmq.ibmqfactory import IBMQFactory from ._config import set_default_provider, get_default_provider def refresh(self): """Refresh the Account object """ self.disable_account() self.load_account() # Trigger a refresh of the Systems provider from kaleidoscope.qiskit.services import Systems # pylint: disable=cyclic-import Systems._refresh() IBMQFactory.refresh = refresh IBMQFactory.set_default_provider = set_default_provider IBMQFactory.get_default_provider = get_default_provider Account = IBMQFactory() try: Account.load_account() except QiskitError: pass