def test_execute_skipping(tmp_path: Path, caplog: LogCaptureFixture) -> None: batch_file = tmp_path / "batch.jsonl" results_dir = tmp_path / "out" # Execute request for the first time. batch = Batch() batch.append(Search("trump", max_tweets=50)) batch.dump(batch_file) assert batch.execute(results_dir) _assert_results_dir_structure(results_dir, list(batch)) batch_entry = batch[0] meta_file = results_dir / batch_entry.meta_file_name data_file = results_dir / batch_entry.data_file_name meta_stat1 = meta_file.stat() data_stat1 = data_file.stat() # Execute same request again (should be skipped). batch = Batch( ) # Recreate from dumped batch file so that batch entry IDs match. batch.load(batch_file) caplog.clear() assert batch.execute(results_dir) assert 1 == len( [record for record in caplog.records if "Skipping" in record.msg]) _assert_results_dir_structure(results_dir, list(batch)) meta_stat2 = meta_file.stat() data_stat2 = data_file.stat() # Verify that files were not modified. assert meta_stat1.st_mtime_ns == meta_stat2.st_mtime_ns assert data_stat1.st_mtime_ns == data_stat2.st_mtime_ns
async def test_unauthenticated(tmp_path: Path, client: AsyncClient, caplog: LogCaptureFixture) -> None: clients = [OIDCClient(client_id="some-id", client_secret="some-secret")] await configure(tmp_path, "github", oidc_clients=clients) return_url = f"https://{TEST_HOSTNAME}:4444/foo?a=bar&b=baz" login_params = { "response_type": "code", "scope": "openid", "client_id": "some-id", "state": "random-state", "redirect_uri": return_url, } caplog.clear() r = await client.get("/auth/openid/login", params=login_params) assert r.status_code == 307 url = urlparse(r.headers["Location"]) assert not url.scheme assert not url.netloc assert url.path == "/login" params = urlencode(login_params) expected_url = f"https://{TEST_HOSTNAME}/auth/openid/login?{params}" assert query_from_url(r.headers["Location"]) == {"rd": [str(expected_url)]} assert parse_log(caplog) == [{ "event": "Redirecting user for authentication", "httpRequest": { "requestMethod": "GET", "requestUrl": ANY, "remoteIp": "127.0.0.1", }, "return_url": return_url, "severity": "info", }]
def test_execute_stray_data_file(tmp_path: Path, caplog: LogCaptureFixture) -> None: batch = Batch() batch.append(Search("trump", max_tweets=50)) batch_entry = batch[0] data = "Just some stray data." data_file = tmp_path / batch_entry.data_file_name write_file(data_file, data) data_stat1 = data_file.stat() assert not batch.execute(tmp_path) # Assert exception is saved. assert batch_entry == read_json(tmp_path / batch_entry.meta_file_name, BatchEntry) assert batch_entry.exception is not None assert batch_entry.exception.type == "ValueError" batch_entry.exception = None # Assert that previous data file is not modified. data_stat2 = data_file.stat() assert data_stat1.st_mtime == data_stat2.st_mtime assert data == read_file(data_file) # Delete data file and verify that it works now. data_file.unlink() caplog.clear() assert batch.execute(tmp_path) assert 1 == len( [record for record in caplog.records if "Retrying" in record.msg]) _assert_results_dir_structure(tmp_path, list(batch))
def test_update_service_tokens_error( tmp_path: Path, config: Config, mock_kubernetes: MockKubernetesApi, caplog: LogCaptureFixture, ) -> None: asyncio.run(initialize_database(config, reset=True)) caplog.clear() def error_callback(method: str, *args: Any) -> None: if method == "list_cluster_custom_object": raise ApiException(status=500, reason="Some error") mock_kubernetes.error_callback = error_callback runner = CliRunner() result = runner.invoke(main, ["update-service-tokens"]) assert result.exit_code == 1 assert parse_log(caplog) == [ { "event": "Unable to list GafaelfawrServiceToken objects", "error": "Kubernetes API error: (500)\nReason: Some error\n", "severity": "error", }, { "error": "Kubernetes API error: (500)\nReason: Some error\n", "event": "Failed to update service token secrets", "severity": "error", }, ]
async def test_invalid_token( client: AsyncClient, caplog: LogCaptureFixture ) -> None: caplog.clear() r = await client.get( "/auth", params={"scope": "exec:admin"}, headers={"Authorization": "Bearer blah"}, ) assert r.status_code == 401 assert parse_log(caplog) == [ { "auth_uri": "NONE", "error": "Token does not start with gt-", "event": "Invalid token", "httpRequest": { "requestMethod": "GET", "requestUrl": ( f"https://{TEST_HOSTNAME}/auth?scope=exec%3Aadmin" ), "remoteIp": "127.0.0.1", }, "required_scope": "exec:admin", "satisfy": "all", "severity": "warning", "token_source": "bearer", } ]
def test_no_signatures_check_signatures( runner, known_good_image_local: TypingKnownGoodImage, caplog: LogCaptureFixture): """Test docker-verify can operate on images without existing signatures.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image_local["image_name"] destination = deepcopy(source) destination.digest = None destination.tag += "_copy" with insecure_registry(): result = runner.invoke( cli, args=[ "--check-signatures", "registry", str(source), str(destination), ], ) assert isinstance(result.exception, SystemExit) assert "does not contain any signatures" in caplog.text assert "is consistent." not in caplog.text
def test_no_signatures_check_signatures( caplog: LogCaptureFixture, docker_registry_secure: DockerRegistrySecure, known_good_image: TypingKnownGoodImage, runner, ): """Test docker-verify can operate on images without existing signatures.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image["image_name"] destination = source.clone() destination.digest = None destination.tag += __name__ with ca_trust_store(docker_registry_secure.cacerts), registry_credentials( docker_registry_secure): result = runner.invoke( cli, args=[ "--check-signatures", "registry", str(source), str(destination) ], ) assert isinstance(result.exception, SystemExit) assert "does not contain any signatures" in caplog.text assert "is consistent." not in caplog.text
def test_unauthorized_source( clirunner, caplog: LogCaptureFixture, docker_registry_secure: DockerRegistrySecure, gpgsigner: GPGSigner, known_good_image: TypingKnownGoodImage, ): """Test docker-sign can handle incorrect credentials.""" caplog.clear() caplog.set_level(logging.DEBUG) # Using local registry credentials when connecting to dockehub ... with registry_credentials(docker_registry_secure): result = clirunner.invoke( cli, args=[ "registry", "--keyid", gpgsigner.keyid, f"{Indices.DOCKERHUB}/dummy:dummy", str(known_good_image["image_name"]), ], env={"DSV_GPG_DATASTORE": str(gpgsigner.homedir)}, input="\n", ) assert result.exception assert "401" in caplog.text assert "Unauthorized" in caplog.text
def test_unauthorized_destination( caplog: LogCaptureFixture, clirunner, docker_registry_secure: DockerRegistrySecure, gpgsigner: GPGSigner, known_good_image: TypingKnownGoodImage, ): """Test docker-sign can handle incorrect credentials.""" caplog.clear() caplog.set_level(logging.DEBUG) # Using local registry credentials when connecting to dockerhub ... with hybrid_trust_store(docker_registry_secure) as path, ca_trust_store( path), registry_credentials(docker_registry_secure): result = clirunner.invoke( cli, args=[ "registry", "--keyid", gpgsigner.keyid, str(known_good_image["image_name"]), f"{Indices.DOCKERHUB}/dummy:dummy", ], env={"DSV_GPG_DATASTORE": str(gpgsigner.homedir)}, input=f"{gpgsigner.passphrase}\n", ) assert result.exception assert "Integrity check passed." in caplog.text assert "401" in caplog.text assert "Unauthorized" in caplog.text
def test_bad_keyid( caplog: LogCaptureFixture, clirunner, docker_registry_secure: DockerRegistrySecure, gpgsigner: GPGSigner, known_good_image: TypingKnownGoodImage, ): """Test docker-sign can handle invalid keyids.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image["image_name"] destination = source.clone() destination.digest = None destination.tag += __name__ with ca_trust_store(docker_registry_secure.cacerts), registry_credentials( docker_registry_secure): result = clirunner.invoke( cli, args=[ "registry", "--keyid", "invalidkeyid", str(source), str(destination), ], env={"DSV_GPG_DATASTORE": str(gpgsigner.homedir)}, input="invalidpassword\n", ) assert result.exception assert "Integrity check passed." in caplog.text assert "Failed to create signature!" in caplog.text
async def test_not_configured(setup: SetupTest, caplog: LogCaptureFixture) -> None: setup.configure("oidc") token_data = await setup.create_session_token() caplog.clear() r = await setup.client.get( "/auth/tokens/influxdb/new", headers={"Authorization": f"bearer {token_data.token}"}, ) assert r.status_code == 404 assert r.json()["detail"]["type"] == "not_supported" log = json.loads(caplog.record_tuples[0][2]) assert log == { "error": "No InfluxDB issuer configuration", "event": "Not configured", "level": "warning", "logger": "gafaelfawr", "method": "GET", "path": "/auth/tokens/influxdb/new", "remote": "127.0.0.1", "request_id": ANY, "scope": "user:token", "token": token_data.token.key, "token_source": "bearer", "user": token_data.username, "user_agent": ANY, }
async def test_logout( client: AsyncClient, config: Config, factory: ComponentFactory, caplog: LogCaptureFixture, ) -> None: token_data = await create_session_token(factory, scopes=["read:all"]) await set_session_cookie(client, token_data.token) # Confirm that we're logged in. r = await client.get("/auth", params={"scope": "read:all"}) assert r.status_code == 200 # Go to /logout without specifying a redirect URL. caplog.clear() r = await client.get("/logout") # Check the redirect and logging. assert r.status_code == 307 assert r.headers["Location"] == config.after_logout_url assert parse_log(caplog) == [{ "event": "Successful logout", "httpRequest": { "requestMethod": "GET", "requestUrl": f"https://{TEST_HOSTNAME}/logout", "remoteIp": "127.0.0.1", }, "severity": "info", }] # Confirm that we're no longer logged in. r = await client.get("/auth", params={"scope": "read:all"}) assert r.status_code == 401
def test_update_service_tokens_error(tmp_path: Path, mock_kubernetes: MockCoreV1Api, caplog: LogCaptureFixture) -> None: initialize(tmp_path) def error_callback(method: str, *args: Any) -> None: if method == "list_secret_for_all_namespaces": raise ApiException(status=500, reason="Some error") MockCoreV1Api.error_callback = error_callback caplog.clear() runner = CliRunner() result = runner.invoke(main, ["update-service-tokens"]) assert result.exit_code == 1 assert [json.loads(r[2]) for r in caplog.record_tuples] == [ { "event": "Unable to list service token secrets", "error": "Kubernetes API error: (500)\nReason: Some error\n", "level": "error", "logger": "gafaelfawr", }, { "error": "Kubernetes API error: (500)\nReason: Some error\n", "event": "Failed to update service token secrets", "level": "error", "logger": "gafaelfawr", }, ]
async def test_logger(caplog: LogCaptureFixture) -> None: configure_logging(name="myapp", profile="production", log_level="info") app = FastAPI() @app.get("/") async def handler( logger: BoundLogger = Depends(logger_dependency), ) -> Dict[str, str]: logger.info("something", param="value") return {} caplog.clear() async with AsyncClient(app=app, base_url="http://example.com") as client: r = await client.get("/", headers={"User-Agent": "some-user-agent/1.0"}) assert r.status_code == 200 assert len(caplog.record_tuples) == 1 assert json.loads(caplog.record_tuples[0][2]) == { "event": "something", "httpRequest": { "requestMethod": "GET", "requestUrl": "http://example.com/", "remoteIp": "127.0.0.1", "userAgent": "some-user-agent/1.0", }, "logger": "myapp", "param": "value", "request_id": ANY, "severity": "info", }
def test_unauthorized_source( clirunner, known_good_image_local: TypingKnownGoodImage, caplog: LogCaptureFixture, ): """Test docker-sign can handle incorrect credentials.""" caplog.clear() caplog.set_level(logging.DEBUG) with insecure_registry(): result = clirunner.invoke( cli, args=[ "registry", "--keyid", "invalidkeyid", f"{Indices.DOCKERHUB}/dummy:dummy", str(known_good_image_local["image_name"]), ], input="\n", ) assert result.exception assert "401" in caplog.text assert "Unauthorized" in caplog.text
def test_bad_keyid(clirunner, known_good_image_local: TypingKnownGoodImage, caplog: LogCaptureFixture): """Test docker-sign can handle invalid keyids.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image_local["image_name"] destination = deepcopy(source) destination.digest = None destination.tag += "_foobar" with insecure_registry(): result = clirunner.invoke( cli, args=[ "registry", "--keyid", "invalidkeyid", str(source), str(destination), ], input="\n", ) assert result.exception assert "Integrity check passed." in caplog.text assert "Failed to create signature!" in caplog.text
def test_no_signatures_resign( clirunner, known_good_image_local: TypingKnownGoodImage, gpgsigner: GPGSigner, caplog: LogCaptureFixture, ): """Test docker-sign can resign images without existing signatures.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image_local["image_name"] destination = deepcopy(source) destination.digest = None destination.tag += "_resigned" with insecure_registry(), temporary_gpg_homedir(gpgsigner.homedir): result = clirunner.invoke( cli, args=[ "--signature-type", "resign", "registry", "--keyid", gpgsigner.keyid, str(source), str(destination), ], input=f"{gpgsigner.passphrase}\n", ) assert not result.exception assert "Integrity check passed." in caplog.text assert "Created new image" in caplog.text assert str(destination) in caplog.text
def test_unauthorized_destination( clirunner, known_good_image_local: TypingKnownGoodImage, gpgsigner: GPGSigner, caplog: LogCaptureFixture, ): """Test docker-sign can handle incorrect credentials.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image_local["image_name"] destination = deepcopy(source) destination.digest = None destination.tag += "_foobar" with insecure_registry(), temporary_gpg_homedir(gpgsigner.homedir): result = clirunner.invoke( cli, args=[ "registry", "--keyid", gpgsigner.keyid, str(known_good_image_local["image_name"]), f"{Indices.DOCKERHUB}/dummy:dummy", ], input=f"{gpgsigner.passphrase}\n", ) assert result.exception assert "Integrity check passed." in caplog.text assert "401" in caplog.text assert "Unauthorized" in caplog.text
async def test_logout(setup: SetupTest, caplog: LogCaptureFixture) -> None: token_data = await setup.create_session_token(scopes=["read:all"]) await setup.login(token_data.token) # Confirm that we're logged in. r = await setup.client.get("/auth", params={"scope": "read:all"}) assert r.status_code == 200 # Go to /logout without specifying a redirect URL. caplog.clear() r = await setup.client.get("/logout", allow_redirects=False) # Check the redirect and logging. assert r.status_code == 307 assert r.headers["Location"] == setup.config.after_logout_url data = json.loads(caplog.record_tuples[0][2]) assert data == { "event": "Successful logout", "level": "info", "logger": "gafaelfawr", "method": "GET", "path": "/logout", "remote": "127.0.0.1", "request_id": ANY, "user_agent": ANY, } # Confirm that we're no longer logged in. r = await setup.client.get("/auth", params={"scope": "read:all"}) assert r.status_code == 401
def test__migrate_deprecated_fields(caplog: LogCaptureFixture) -> None: base_dir = pathlib.Path("/foo") setting_path = pathlib.Path("/foo/pyproject.toml") caplog.clear() config = Config(lint=None) _migrate_deprecated_fields(setting_path, config) assert config.lint is None assert caplog.records == [] config = Config( lint=LintConfig( mypy_target_dirs=[base_dir / "a", base_dir / "b", base_dir / "c"] ), ) _migrate_deprecated_fields(setting_path, config) assert config.lint is not None assert config.lint.mypy_target_dirs is None assert config.lint.mypy_targets is not None and len(config.lint.mypy_targets) == 1 assert config.lint.mypy_targets[0].paths == [ base_dir / "a", base_dir / "b", base_dir / "c", ] assert len(caplog.records) == 1 record = caplog.records[0] assert record.levelno == logging.WARNING assert "tool.pysen.mypy_target_dirs is deprecated" in record.message assert str(setting_path) in record.message
def test_close_task_doesnt_close_already_closed_tasks( self, action: Callable[[FakeRepository, TaskSelector], None], state: str, repo: FakeRepository, tasks: List[Task], freezer: FrozenDateTimeFactory, # noqa: W0613 caplog: LogCaptureFixture, ) -> None: """ Given: An existent closed task. When: using the do_tasks or rm_tasks. Then: Only the open task is closed. """ closed_task = tasks[0] services._close_task(repo, closed_task, TaskState.DONE) caplog.clear() selector = TaskSelector(task_ids=[closed_task.id_, tasks[1].id_]) action(repo, selector) # act task = repo.get(tasks[1].id_, [Task]) assert task.state == state assert ( "pydo.services", logging.INFO, f"Closing task {closed_task.id_}: {closed_task.description} " f"with state {state}", ) not in caplog.record_tuples
async def test_not_configured( tmp_path: Path, client: AsyncClient, factory: ComponentFactory, caplog: LogCaptureFixture, ) -> None: config = await configure(tmp_path, "oidc") factory.reconfigure(config) token_data = await create_session_token(factory) caplog.clear() r = await client.get( "/auth/tokens/influxdb/new", headers={"Authorization": f"bearer {token_data.token}"}, ) assert r.status_code == 404 assert r.json()["detail"]["type"] == "not_supported" assert parse_log(caplog) == [{ "error": "No InfluxDB issuer configuration", "event": "Not configured", "httpRequest": { "requestMethod": "GET", "requestUrl": (f"https://{TEST_HOSTNAME}/auth/tokens/influxdb/new"), "remoteIp": "127.0.0.1", }, "scope": "user:token", "severity": "warning", "token": token_data.token.key, "token_source": "bearer", "user": token_data.username, }]
def test_no_signatures_sign_implicit( caplog: LogCaptureFixture, clirunner, docker_registry_secure: DockerRegistrySecure, gpgsigner: GPGSigner, known_good_image: TypingKnownGoodImage, ): """Test docker-sign can sign (implicit) images without existing signatures.""" caplog.clear() caplog.set_level(logging.DEBUG) source = known_good_image["image_name"] destination = source.clone() destination.digest = None destination.tag += __name__ with ca_trust_store(docker_registry_secure.cacerts), registry_credentials( docker_registry_secure): result = clirunner.invoke( cli, args=[ "registry", "--keyid", gpgsigner.keyid, str(source), str(destination), ], env={"DSV_GPG_DATASTORE": str(gpgsigner.homedir)}, input=f"{gpgsigner.passphrase}\n", ) assert not result.exception assert "Integrity check passed." in caplog.text assert "Created new image" in caplog.text assert str(destination) in caplog.text
async def test_create(setup: SetupTest, mock_kubernetes: MockCoreV1Api, caplog: LogCaptureFixture) -> None: assert setup.config.kubernetes kubernetes_service = setup.factory.create_kubernetes_service() await kubernetes_service.update_service_secrets() await assert_kubernetes_secrets_match_config(setup, mock_kubernetes) expected_tuples = [( { "event": "Created new service token", "key": ANY, "level": "info", "logger": "gafaelfawr", "token_scope": ",".join(s.scopes), "token_username": s.service, }, { "event": (f"Created {s.secret_namespace}/{s.secret_name} secret"), "level": "info", "logger": "gafaelfawr", "scopes": s.scopes, "service": s.service, }, ) for s in setup.config.kubernetes.service_secrets] expected = [r for t in expected_tuples for r in t] assert [json.loads(r[2]) for r in caplog.record_tuples] == expected # Running creation again should not change anything. caplog.clear() objects = mock_kubernetes.get_all_objects_for_test() await kubernetes_service.update_service_secrets() assert mock_kubernetes.get_all_objects_for_test() == objects assert caplog.record_tuples == []
def test_verify_logging_message_for_intent_not_used_in_story( caplog: LogCaptureFixture, validator_under_test: Validator): caplog.clear() with pytest.warns(UserWarning) as record: validator_under_test.verify_intents_in_stories(False) assert "The intent 'goodbye' is not used in any story or rule." in ( m.message.args[0] for m in record)
def test_verify_logging_message_for_unused_utterance( caplog: LogCaptureFixture, validator_under_test: Validator): caplog.clear() with pytest.warns(UserWarning) as record: validator_under_test.verify_utterances_in_stories(False) assert "The utterance 'utter_chatter' is not used in any story or rule." in ( m.message.args[0] for m in record)
def test_verify_logging_message_for_intent_not_used_in_nlu( caplog: LogCaptureFixture, validator_under_test: Validator): caplog.clear() with pytest.warns(UserWarning) as record: validator_under_test.verify_intents(False) assert ("The intent 'goodbye' is listed in the domain file, " "but is not found in the NLU training data." in (m.message.args[0] for m in record))
def assert_and_clear_caplog(caplog: LogCaptureFixture, asserted_msg: str, asserted_context: dict): """Assert first (zero) record in caplog, than clear it""" assert caplog.records[0].message == asserted_msg assert caplog.records[0].msg == asserted_msg assert caplog.records[0].context == asserted_context caplog.clear()
def test_unauthorized(runner, caplog: LogCaptureFixture): """Test docker-verify can handle incorrect credentials.""" caplog.clear() caplog.set_level(logging.DEBUG) image = f"{Indices.DOCKERHUB}/dummy:dummy" result = runner.invoke(cli, args=["registry", image]) assert isinstance(result.exception, SystemExit) assert "401" in caplog.text assert "Unauthorized" in caplog.text assert image in caplog.text
def test_not_found(runner, caplog: LogCaptureFixture): """Test docker-verify can handle incorrect image names.""" caplog.clear() caplog.set_level(logging.DEBUG) image = f"{Indices.DOCKERHUB}/library/python:dummy" result = runner.invoke(cli, args=["registry", image]) assert isinstance(result.exception, SystemExit) assert "404" in caplog.text assert "Not Found" in caplog.text assert image in caplog.text