def test_invalid_certificate_config(self): self.maxDiff = None # Given url = "http://acme.com" config = Configuration() config.update(store_url=url) config.update(auth=("nono", "le petit robot")) config.write(self.config) responses.add_callback(responses.GET, re.compile(url + "/*"), self._dummy_ssl_error_callback) error_message = "To connect to 'acme.com' insecurely, add the `-k` " \ "flag to enpkg command" # When with use_given_config_context(self.config): with mock_print() as m: with self.assertRaises(SystemExit): main(["--config"]) # Then last_line = m.value.splitlines()[-1] self.assertMultiLineEqual(last_line, error_message)
def test_install_pypi_before_non_pypi(self): # Given config = Configuration() config.update(auth=("nono", "le petit robot")) session = Session.from_configuration(config) session.authenticate(config.auth) repository = repository_factory(session, config.indices) enpkg = Enpkg(repository, session, [self.prefix]) enpkg.execute = mock.Mock() # When with mock_print() as mocked_print: with mock_raw_input("yes"): install_req(enpkg, config, "swig 2.0.2", FakeOptions()) # Then self._assert_ask_for_pypi(mocked_print) # When with mock_print() as mocked_print: with mock_raw_input("yes"): install_req(enpkg, config, "swig 2.0.2-1", FakeOptions()) # Then self._assert_ask_for_pypi(mocked_print)
def test_set_repository_cache(self): homedir = os.path.normpath(os.path.expanduser("~")) config = Configuration() config.update(repository_cache="~/.env/LOCAL-REPO") self.assertEqual(config.repository_cache, os.path.join(homedir, ".env", "LOCAL-REPO"))
def test_set_prefix(self): homedir = os.path.normpath(os.path.expanduser("~")) config = Configuration() config.update(prefix=os.path.normpath("~/.env")) self.assertEqual(config.prefix, os.path.join(homedir, ".env"))
def test_no_installed(self): config = Configuration() config.update(use_webservice=False) with mkdtemp() as d: # XXX: isn't there a better way to ensure ws at the end of a line # are not eaten away ? r_output = textwrap.dedent("""\ Name Versions Product Note ================================================================================ another_dummy 2.0.0-1 commercial {0} dummy 0.9.8-1 commercial {0} 1.0.0-1 commercial {0} """.format("")) entries = [ dummy_repository_package_factory("dummy", "1.0.0", 1), dummy_repository_package_factory("dummy", "0.9.8", 1), dummy_repository_package_factory("another_dummy", "2.0.0", 1) ] enpkg = create_prefix_with_eggs(config, d, remote_entries=entries) with mock_print() as m: search(enpkg._remote_repository, enpkg._top_installed_repository, config, UserInfo(True)) self.assertMultiLineEqual(m.value, r_output)
def test_401_index_handling(self): self.maxDiff = None # Given repo = "http://acme.com/repo/ets/" config = Configuration() config.update(use_webservice=False, indexed_repositories=[repo]) config.update(auth=("nono", "le petit robot")) config.write(self.config) url = repo + "index.json" responses.add(responses.HEAD, url, status=401) error_message = textwrap.dedent("""\ Could not authenticate as 'nono' (server answered: 'Invalid credentials') Ensure your username and password are correct. You can change your authentication details with 'enpkg --userpass'. """) # When with use_given_config_context(self.config): with mock_print() as m: with self.assertRaises(SystemExit): main(["dummy_requirement"]) # Then self.assertMultiLineEqual(m.value, error_message)
def test_pattern(self): config = Configuration() config.update(use_webservice=False) with mkdtemp() as d: r_output = textwrap.dedent("""\ Name Versions Product Note ================================================================================ dummy 0.9.8-1 commercial {0} * 1.0.1-1 commercial {0} """.format("")) entries = [dummy_repository_package_factory("dummy", "1.0.1", 1), dummy_repository_package_factory("dummy", "0.9.8", 1), dummy_repository_package_factory("another_package", "2.0.0", 1)] installed_entries = [dummy_installed_package_factory("dummy", "1.0.1", 1)] enpkg = create_prefix_with_eggs(config, d, installed_entries, entries) with mock_print() as m: search(enpkg._remote_repository, enpkg._top_installed_repository, config, UserInfo(True), pat=re.compile("dummy")) self.assertMultiLineEqual(m.value, r_output) r_output = textwrap.dedent("""\ Name Versions Product Note ================================================================================ another_package 2.0.0-1 commercial {0} dummy 0.9.8-1 commercial {0} * 1.0.1-1 commercial {0} """.format("")) with mock_print() as m: search(enpkg._remote_repository, enpkg._top_installed_repository, config, UserInfo(True), pat=re.compile(".*")) self.assertMultiLineEqual(m.value, r_output)
def test_no_acct(self): # Given url = "https://acme.com" auth_url = url + "/accounts/user/info/" config = Configuration() config.update(store_url=url) def callback(request): if auth != ("valid_user", "valid_password"): return (403, {}, "") return (200, {}, json.dumps(R_JSON_AUTH_RESP)) responses.add_callback(responses.GET, auth_url, callback) write_default_config(self.f) with Session.from_configuration(config) as session: config = Configuration() config.update(store_url=url) auth = ("invalid_user", "invalid_password") with self.assertRaises(AuthFailedError): usr = config._checked_change_auth(auth, session, self.f) config = Configuration() auth = ("valid_user", "valid_password") usr = config._checked_change_auth(auth, session, self.f) self.assertTrue(usr.is_authenticated) self.assertEqual(config.auth, UserPasswordAuth("valid_user", "valid_password"))
def test_simple_no_webservice(self): output_template = textwrap.dedent("""\ Python version: {pyver} enstaller version: {version} sys.prefix: {sys_prefix} platform: {platform} architecture: {arch} use_webservice: False keyring backend: {keyring_backend} settings: prefix = {{prefix}} repository_cache = {{repository_cache}} noapp = False proxy = None IndexedRepos: 'http://acme.com/' No valid auth information in configuration, cannot authenticate. You are not logged in. To log in, type 'enpkg --userpass'. """).format(pyver=PY_VER, sys_prefix=sys.prefix, version=__version__, platform=platform.platform(), arch=platform.architecture()[0], keyring_backend=_keyring_backend_name()) prefix = sys.prefix repository_cache = os.path.join(prefix, "LOCAL-REPO") r_output = output_template.format(prefix=os.path.normpath(prefix), repository_cache=repository_cache) config = Configuration() config.update(indexed_repositories=["http://acme.com"], use_webservice=False) with mock_print() as m: print_config(config, config.prefix, Session(DummyAuthenticator(), self.prefix)) self.assertMultiLineEqual(m.value, r_output)
def test_not_available(self): responses.add(responses.GET, "https://acme.com/accounts/user/info/", body=json.dumps(R_JSON_AUTH_FREE_RESP)) config = Configuration() config.update(store_url="https://acme.com") r_output = textwrap.dedent("""\ Name Versions Product Note ================================================================================ another_package 2.0.0-1 commercial not subscribed to dummy 0.9.8-1 commercial {0} 1.0.1-1 commercial {0} Note: some of those packages are not available at your current subscription level ('Canopy / EPD Free'). """.format("")) another_entry = dummy_repository_package_factory("another_package", "2.0.0", 1) another_entry.available = False entries = [dummy_repository_package_factory("dummy", "1.0.1", 1), dummy_repository_package_factory("dummy", "0.9.8", 1), another_entry] with Session.from_configuration(config) as session: with mkdtemp() as d: with mock_print() as m: enpkg = create_prefix_with_eggs(config, d, remote_entries=entries) search(enpkg._remote_repository, enpkg._installed_repository, config, session) self.assertMultiLineEqual(m.value, r_output)
def test_ensure_authenticated_config(self): # Given r_message = textwrap.dedent("""\ Could not authenticate as 'nono' Please check your credentials/configuration and try again (original error is: 'Authentication error: Invalid user login.'). You can change your authentication details with 'enpkg --userpass'. """) store_url = "https://acme.com" responses.add(responses.GET, store_url + "/accounts/user/info/", body=json.dumps(R_JSON_NOAUTH_RESP)) config = Configuration() config.update(store_url=store_url, auth=("nono", "le petit robot")) session = Session.from_configuration(config) # When/Then with mock_print() as m: with self.assertRaises(SystemExit) as e: ensure_authenticated_config(config, "", session) self.assertEqual(exception_code(e), -1) self.assertMultiLineEqual(m.value, r_message)
def test_recursive_install_unavailable_dependency(self): config = Configuration() session = Session(DummyAuthenticator(), self.prefix) auth = ("nono", "le gros robot") session.authenticate(auth) config.update(auth=auth) r_output = textwrap.dedent(""" Cannot install 'scipy', as this package (or some of its requirements) are not available at your subscription level 'Canopy / EPD Free' (You are logged in as 'nono'). """) self.maxDiff = None numpy = dummy_repository_package_factory("numpy", "1.7.1", 1) numpy.available = False scipy = dummy_repository_package_factory("scipy", "0.12.0", 1) scipy.packages = ["numpy 1.7.1"] remote_entries = [numpy, scipy] with mock.patch("enstaller.main.Enpkg.execute"): enpkg = create_prefix_with_eggs(config, self.prefix, [], remote_entries) with mock_print() as m: with self.assertRaises(SystemExit): install_req(enpkg, config, "scipy", FakeOptions()) self.assertMultiLineEqual(m.value, r_output)
def test_invalid_certificate_dont_webservice(self): self.maxDiff = None # Given url = "http://acme.com" config = Configuration() config.update(use_webservice=False, indexed_repositories=["http://acme.com/repo/"]) config.update(auth=("nono", "le petit robot")) config.write(self.config) def callback(request): msg = "Dummy SSL error" raise requests.exceptions.SSLError(msg, request=request) responses.add_callback(responses.HEAD, re.compile(url + "/*"), callback) error_message = textwrap.dedent("""\ SSL error: Dummy SSL error To connect to 'acme.com' insecurely, add the `-k` flag to enpkg command """) # When with use_given_config_context(self.config): with mock_print() as m: with self.assertRaises(SystemExit): main(["dummy_requirement"]) # Then self.assertMultiLineEqual(m.value, error_message)
def test_insecure_flag(self): # Given responses.add(responses.GET, "https://acme.com/accounts/user/info/", body=json.dumps(R_JSON_AUTH_RESP)) config = Configuration() config.update(store_url="https://acme.com") config.update(auth=("nono", "le gros robot")) # When with self.assertRaises(SystemExit) as e: with mock.patch("enstaller.main._ensure_config_or_die", return_value=config): with mock.patch( "enstaller.main.ensure_authenticated_config" ): main_noexc(["-s", "fubar"]) # Then self.assertEqual(e.exception.code, 0) # When with self.assertRaises(SystemExit) as e: with mock.patch("enstaller.main._ensure_config_or_die", return_value=config): with mock.patch( "enstaller.main.ensure_authenticated_config" ): main_noexc(["-ks", "fubar"]) # Then self.assertEqual(e.exception.code, 0)
def test_installed(self): config = Configuration() config.update(use_webservice=False) with mkdtemp() as d: r_output = textwrap.dedent("""\ Name Versions Product Note ================================================================================ dummy 0.9.8-1 commercial {0} * 1.0.1-1 commercial {0} """.format("")) entries = [ dummy_repository_package_factory("dummy", "1.0.1", 1), dummy_repository_package_factory("dummy", "0.9.8", 1) ] installed_entries = [ dummy_installed_package_factory("dummy", "1.0.1", 1) ] enpkg = create_prefix_with_eggs(config, d, installed_entries, entries) with mock_print() as m: search(enpkg._remote_repository, enpkg._installed_repository, config, UserInfo(True)) self.assertMultiLineEqual(m.value, r_output)
def test_non_writable_repository_cache(self): fake_dir = "/some/dummy_dir/hopefully/doesnt/exists" config = Configuration() with mock.patch("os.makedirs", side_effect=OSError("mocked makedirs")): config.update(repository_cache=fake_dir) self.assertNotEqual(config.repository_cache, fake_dir)
def test_with_keyring(self): with make_keyring_available_context() as mocked_keyring: config = Configuration() config.update(auth=(FAKE_USER, FAKE_PASSWORD)) self.assertEqual(config.auth, UserPasswordAuth(FAKE_USER, FAKE_PASSWORD)) self.assertFalse(mocked_keyring.set_password.called)
def test_reset_auth_with_keyring(self): with make_keyring_available_context(): config = Configuration() config.update(auth=(FAKE_USER, FAKE_PASSWORD)) config.reset_auth() self.assertIsNone(config.auth)
def test_simple_with_proxy(self): proxystr = "http://acme.com:3128" config = Configuration() config.update(proxy=proxystr) config.write(self.f) config = Configuration.from_file(self.f) self.assertEqual(str(config.proxy), proxystr) self.assertEqual(config.proxy_dict, {"http": proxystr})
def test_proxy_setup(self): # Given proxy_string = "http://acme.com" # When config = Configuration() config.update(proxy=proxy_string) # Then self.assertEqual(str(config.proxy), "http://acme.com:3128")
def test_no_config_file(self): with tempfile.NamedTemporaryFile(delete=False, mode="wt") as fp: fp.write("") config = Configuration() self.assertIsNone(config.auth) config.update(auth=(FAKE_USER, FAKE_PASSWORD)) config.write(fp.name) new_config = Configuration.from_file(fp.name) self.assertEqual(new_config.auth, FAKE_AUTH)
def test_indices_property_no_pypi(self): # Given r_indices = tuple([ ("https://api.enthought.com/eggs/{0}/index.json?pypi=false". format(custom_plat), "https://api.enthought.com/eggs/{0}/index.json".format(custom_plat)), ]) config = Configuration() config.update(use_pypi=False) # When/Then self.assertEqual(config.indices, r_indices)
def authenticated_config(f): config = Configuration() config.update(auth=("dummy", "dummy")) m = mock.Mock() m.return_value = config m.from_file.return_value = config wrapper = mock.patch("enstaller.main.Configuration", m) mock_authenticated_config = mock.patch( "enstaller.main.ensure_authenticated_config", mock.Mock()) return mock_authenticated_config(wrapper(f))
def test_indices_property_no_webservice(self): # Given r_indices = tuple(( ("https://acme.com/{0}/index.json".format(custom_plat), "https://acme.com/{0}/index.json".format(custom_plat)), )) config = Configuration() config.update(use_webservice=False, indexed_repositories=["https://acme.com/{PLATFORM}/"]) # When/Then self.assertEqual(config.indices, r_indices)
def test_max_retries(self): # Given config = Configuration() # When/Then with Session.from_configuration(config) as session: for prefix in ("http://", "https://"): self.assertEqual(session._raw.adapters[prefix].max_retries, 0) # When/Then config.update(max_retries=3) with Session.from_configuration(config) as session: for prefix in ("http://", "https://"): self.assertEqual(session._raw.adapters[prefix].max_retries, 3)
def test_authenticated_from_configuration_wo_auth(self): # Given url = "http://acme.com" responses.add(responses.GET, url) responses.add(responses.GET, url + "/accounts/user/info/", body=json.dumps(R_JSON_AUTH_RESP)) config = Configuration() config.update(store_url=url) # When/Then with self.assertRaises(EnstallerException): with Session.authenticated_from_configuration(config): pass
class AuthManagerBase(unittest.TestCase): klass = None def setUp(self): self.prefix = tempfile.mkdtemp() self.config = Configuration() self.config.update(use_webservice=False, indexed_repositories=["http://acme.com"]) self.session = Session(self.klass.from_configuration(self.config), self.prefix) def tearDown(self): shutil.rmtree(self.prefix) self.session.close()
def test_authenticated_from_configuration(self): # Given url = "http://acme.com" responses.add(responses.GET, url) responses.add(responses.GET, url + "/accounts/user/info/", body=json.dumps(R_JSON_AUTH_RESP)) config = Configuration() config.update(store_url=url, auth=("yoyo", "yeye")) # When with Session.authenticated_from_configuration(config) as session: resp = session._raw_get(url) # Then self.assertTrue(resp.status_code, 200)
def test_change_store_url(self): config = Configuration() config.update(auth=(FAKE_USER, FAKE_PASSWORD)) config.write(self.f) config = Configuration.from_file(self.f) config.update(store_url="https://acme.com") self.assertEqual(config.auth._encoded_auth, FAKE_CREDS) self.assertEqual(config.autoupdate, True) self.assertEqual(config.proxy, None) self.assertEqual(config.use_webservice, True) self.assertEqual(config.webservice_entry_point, "https://acme.com/eggs/{0}/".format(custom_plat)) self.assertEqual(config.api_url, "https://acme.com/accounts/user/info/")
def test_api_token(self): # Given config = Configuration() # When config.update(auth=APITokenAuth("dummy token")) # Then self.assertEqual(config.auth, APITokenAuth("dummy token")) # Given data = StringIO("api_token = 'yoyo'") # When config = Configuration.from_file(data) # Then self.assertEqual(config.auth, APITokenAuth("yoyo"))
def test_simple_legacy_canopy(self): # Given url = "https://api.enthought.com" config = Configuration() config.update(store_url=url, auth=FAKE_AUTH) responses.add(responses.GET, url + "/accounts/user/info/", status=200, body=json.dumps(R_JSON_AUTH_RESP)) session = Session.from_configuration(config) session.authenticate(config.auth) # When user_info = UserInfo.from_session(session) # Then self.assertEqual(user_info.first_name, R_JSON_AUTH_RESP["first_name"])
def test_simple_old_legacy(self): # Given url = "https://acme.com" config = Configuration() config.update(use_webservice=False, auth=FAKE_AUTH) config.update(indexed_repositories=[url]) responses.add(responses.HEAD, config.indices[0][0], status=200) session = Session.from_configuration(config) session.authenticate(config.auth) # When user_info = UserInfo.from_session(session) # Then self.assertTrue(user_info.is_authenticated)
def test_max_retries_with_etag(self): # Given config = Configuration() # When/Then with Session.from_configuration(config) as session: with session.etag(): for prefix in ("http://", "https://"): max_retries = session._raw.adapters[prefix].max_retries self.assertEqual(max_retries.total, 0) # When/Then config.update(max_retries=3) with Session.from_configuration(config) as session: with session.etag(): for prefix in ("http://", "https://"): max_retries = session._raw.adapters[prefix].max_retries self.assertEqual(max_retries.total, 3)
def test_store_kind(self): """ Ensure config auth information is properly set-up when using EPD_auth """ # Given config = Configuration() # When config.update(store_url="http://acme.com") # Then self.assertEqual(config.store_kind, "legacy") self.assertEqual(config.store_url, "http://acme.com") # Given config = Configuration() # When config.update(store_url="brood+http://acme.com") # Then self.assertEqual(config.store_kind, "brood") self.assertEqual(config.store_url, "http://acme.com") # Given s = StringIO("store_url = 'http://acme.com'") # When config = Configuration.from_file(s) # Then self.assertEqual(config.store_kind, "legacy") self.assertEqual(config.store_url, "http://acme.com") # Given s = StringIO("store_url = 'brood+http://acme.com'") # When config = Configuration.from_file(s) # Then self.assertEqual(config.store_kind, "brood") self.assertEqual(config.store_url, "http://acme.com")
def test_simple_set_auth(self): # Given config = Configuration() # When/Then self.assertIsNone(config.auth) # Given config = Configuration() # When/Then with self.assertRaises(InvalidConfiguration): config.update(auth=("", "")) # Given config = Configuration() config.update(auth=("yoyoma", "")) # When/Then self.assertIsNotNone(config.auth)
def test_simple_brood_auth(self): # Given url = "https://acme.com" token_url = url + "/api/v0/json/auth/tokens/auth" config = Configuration() config.update(store_url="brood+" + url, auth=FAKE_AUTH) responses.add(responses.POST, token_url, status=200, body=json.dumps({"token": "dummy token"})) session = Session.from_configuration(config) session.authenticate(config.auth) # When user_info = UserInfo.from_session(session) # Then self.assertTrue(user_info.is_authenticated)
def test_from_configuration(self): # Given config = Configuration() # When/Then with Session.from_configuration(config) as session: self.assertTrue(session._raw.verify) self.assertIsInstance(session._authenticator, LegacyCanopyAuthManager) # When/Then config = Configuration() config.update(verify_ssl=False) with Session.from_configuration(config) as session: self.assertFalse(session._raw.verify) # Given config = Configuration() config.update(verify_ssl=False, use_webservice=False) # When/Then with Session.from_configuration(config) as session: self.assertFalse(session._raw.verify) self.assertIsInstance(session._authenticator, OldRepoAuthManager) # Given config = Configuration() config.update(store_url="brood+http://acme.com") # When/Then with Session.from_configuration(config) as session: self.assertIsInstance(session._authenticator, BroodAuthenticator)
def test_install_not_available(self): # Given config = Configuration() config.update(auth=FAKE_AUTH) nose = dummy_repository_package_factory("nose", "1.3.0", 1) nose.available = False repository = Repository() repository.add_package(nose) enpkg = Enpkg(repository, mocked_session_factory(config.repository_cache), [self.prefix]) enpkg.execute = mock.Mock() # When/Then with mock.patch("enstaller.config.subscription_message") as \ subscription_message: with self.assertRaises(SystemExit) as e: install_req(enpkg, config, "nose", FakeOptions()) subscription_message.assert_called() self.assertEqual(e.exception.code, 1)