def test_pykafka_config(mocker: mock, config: Config): ssl_config_sentinel = mock.sentinel.ssl_config ssl_config_mock = mocker.patch("esque.config.SslConfig", return_value=ssl_config_sentinel) plain_authenticator_sentinel = mock.sentinel.plain_authenticator plain_authenticator_mock = mocker.patch( "pykafka.sasl_authenticators.PlainAuthenticator", return_value=plain_authenticator_sentinel ) config.context_switch("context_5") expected_config = { "hosts": "kafka:9094,kafka1:9094,kafka2:9094,kafka3:9094", "sasl_authenticator": plain_authenticator_sentinel, "ssl_config": ssl_config_sentinel, } actual_config = config.create_pykafka_config() assert expected_config == actual_config ssl_config_mock.assert_called_with( **{ "cafile": "/my/ca.crt", "certfile": "/my/certificate.crt", "keyfile": "/my/certificate.key", "password": "******", } ) plain_authenticator_mock.assert_called_with(user="******", password="******", security_protocol="SASL_SSL")
def non_interactive_cli_runner(mocker: mock, unittest_config: Config) -> CliRunner: mocker.patch("esque.cli.helpers._isatty", return_value=False) mocker.patch("esque.cli.environment.ESQUE_VERBOSE", new_callable=mock.PropertyMock, return_value="1") return CliRunner()
def load_config(mocker: mock, tmp_path: Path) -> config_loader: """ Loads config of the given version or key into a temporary directory and set this directory as esque config directory. Available keys are `LOAD_INTEGRATION_TEST_CONFIG` and `LOAD_SAMPLE_CONFIG`. It will delete all other configs found in that directory. :param config_version: version or config key to load :type config_version: int :return: Tuple[NamedTemporaryFile, str] where str is the content of the config and the tempfile """ mocker.patch("esque.config._config_dir", return_value=tmp_path) def loader(config_version: int = LOAD_CURRENT_VERSION) -> Tuple[Path, str]: for file in tmp_path.glob("*"): os.remove(str(file.resolve())) original_path = get_path_for_config_version(config_version) data = original_path.read_text() if config_version == 0: config_file = tmp_path / "esque.cfg" else: config_file = tmp_path / "esque_config.yaml" config_file.write_text(data) return config_file, data return loader
def test_do_combat(mocker: mock, player: dict, dynamodb_config: boto3.resource) -> None: """ Test that a good combat request gets properly sent to our lambda function :param mocker: Pytest mock fixture :param player: Input character dictionary :param dynamodb_config: boto3 resource with our tables """ # Arrange mocker.patch( "worlds_worst_serverless.worlds_worst_operator.actions.random.choice", return_value="attack", ) input_player = Player(**player) expected_player_updates = {"hit_points": 400, "ex": 150} expected_target_updates = expected_player_updates expected_message = [ "Truckthunders uses attack!", "Truckthunders uses attack!", "Truckthunders and Truckthunders tie.", "Truckthunders has 400 HP left.", ] # Act updated_player, updated_target, player_updates, target_updates, message = operator.do_combat( player=input_player, table=dynamodb_config) # Assert assert input_player != updated_player assert player_updates == expected_player_updates assert target_updates == expected_target_updates assert message == expected_message
def test_route_bad_id(mocker: mock, mock_event: dict, dynamodb_config: boto3.resource) -> None: """ Test that the operator router returns 401 Unauthorized if the player ID is wrong :param mocker: Pytest mock fixture :param mock_event: Mock AWS lambda event dict :param dynamodb_config: boto3 config with our resource """ # Arrange # Mock all the things we already tested mocker.patch( "worlds_worst_serverless.worlds_worst_operator.actions.random.choice", return_value="block", ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.operator.boto3.resource", return_value=dynamodb_config, ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.operator.os.environ", return_value="Table", ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.actions" ".get_player", return_value={"Error": "Queried player does not exist."}, ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.database_ops.get_player", return_value={"Error": "Queried player does not exist."}, ) mock_event["body"]["playerId"] = "wrong_key" expected_response = { "statusCode": 401, "body": json.dumps({"Error": "Player does not exist in database"}), "message": json.dumps("Time to reroll."), "headers": { "Access-Control-Allow-Origin": "*" }, } # Act response = operator.route_tasks_and_response(mock_event, mock_event) # Assert assert response == expected_response
def test_validation_called(mocker: mock, load_config: config_loader): conf_path, conf_content = load_config() validator_mock = mocker.patch("esque.validation.validate_esque_config") Config() validated_config_dict, = validator_mock.call_args[0] assert validated_config_dict == yaml.safe_load(conf_content)
def test_send_mime_complete_failure(self, mock_smtp: mock, mock_smtp_ssl): mock_smtp.side_effect = SMTPServerDisconnected() msg = MIMEMultipart() with pytest.raises(SMTPServerDisconnected): utils.email.send_mime_email('from', 'to', msg, dryrun=False) mock_smtp.assert_any_call( host=conf.get('smtp', 'SMTP_HOST'), port=conf.getint('smtp', 'SMTP_PORT'), timeout=conf.getint('smtp', 'SMTP_TIMEOUT'), ) assert mock_smtp.call_count == conf.getint('smtp', 'SMTP_RETRY_LIMIT') assert not mock_smtp_ssl.called assert not mock_smtp.return_value.starttls.called assert not mock_smtp.return_value.login.called assert not mock_smtp.return_value.sendmail.called assert not mock_smtp.return_value.quit.called
async def test_mqtt_client_calls_telem(mqtt_client: MQTTClient, mocker: mock): from tests.test_database_models import SAMPLE_GATEWAY_HID telem_func = mocker.patch("feeder.util.mqtt.client.commit_telemetry_data") await mqtt_client.publish(f"krs.tel.gts.{SAMPLE_GATEWAY_HID}", message=b"{}") message = await mqtt_client.deliver_message() packet = message.publish_packet await mqtt_client.handle_message(packet) telem_func.assert_called_once_with(SAMPLE_GATEWAY_HID, {})
def test_migrate_config(mocker: mock, interactive_cli_runner: CliRunner, load_config: config_loader): conf_path, old_conf_text = load_config(0) assert get_config_version(conf_path) == CURRENT_VERSION - 1 mocker.patch("esque.config._config_dir", return_value=conf_path.parent) new_conf_path = conf_path backup = None def migration_wrapper(config_path: Path): nonlocal new_conf_path, backup new_conf_path, backup = migrate(config_path) return new_conf_path, backup mocker.patch.object(migration, "migrate", wraps=migration_wrapper) result = interactive_cli_runner.invoke(config_migrate, catch_exceptions=False) assert result.exit_code == 0 assert get_config_version(new_conf_path) == CURRENT_VERSION assert backup.read_text() == old_conf_text
def test_edit_topic_calls_validator(mocker: mock, topic, interactive_cli_runner, topic_controller): validator_mock = mocker.patch("esque.validation.validate_editable_topic_config", side_effect=EditCanceled()) config_dict = { "config": { "cleanup.policy": "delete", "compression.type": "producer", "delete.retention.ms": "123456789", "segment.jitter.ms": "0", "segment.ms": "123456789", "unclean.leader.election.enable": "true", } } mocker.patch.object(click, "edit", return_value=yaml.dump(config_dict, default_flow_style=False)) interactive_cli_runner.invoke(esque, args=["edit", "topic", topic], input="y\n") (validated_config_dict,) = validator_mock.call_args[0] assert validated_config_dict == config_dict
def interactive_cli_runner(mocker: mock) -> CliRunner: mocker.patch("esque.cli.helpers._isatty", return_value=True) mocker.patch("esque.cli.environment.ESQUE_VERBOSE", new_callable=mock.PropertyMock, return_value="1") return CliRunner()
def test_list(mocker: mock): # no item, no error with tempfile.TemporaryDirectory() as tempdir: mocker.patch("drudgeyer.cli.show.BASEDIR", Path(tempdir)) result = runner.invoke(app, ["list"]) assert result.exit_code == 0, result.stdout # successfully query items with tempfile.TemporaryDirectory() as tempdir: mocker.patch("drudgeyer.cli.add.BASEDIR", Path(tempdir)) mocker.patch("drudgeyer.cli.show.BASEDIR", Path(tempdir)) result = runner.invoke(app, ["add", "echo 1"]) result = runner.invoke(app, ["add", "echo 2"]) assert result.exit_code == 0, result.stdout result = runner.invoke(app, ["list"]) assert result.exit_code == 0, result.stdout assert len(result.stdout.split("\n")) > 2, result.stdout # mock requests with tempfile.TemporaryDirectory() as tempdir: mocker.patch("drudgeyer.cli.add.BASEDIR", Path(tempdir)) mocker.patch("drudgeyer.cli.show.BASEDIR", Path(tempdir)) result = runner.invoke(app, ["add", "echo 1"]) result = runner.invoke(app, ["add", "echo 2"]) assert result.exit_code == 0, result.stdout mocker.patch("requests.post", lambda x, y, headers: None) result = runner.invoke(app, ["list", "--prune"]) assert result.exit_code == 0, result.stdout # successfully show items with tempfile.TemporaryDirectory() as tempdir: mocker.patch("drudgeyer.cli.show.BASEDIR", Path(tempdir)) mocker.patch( "drudgeyer.job_scheduler.queue.FileQueue.list", lambda x: [ BaseQueueModel( id="xxx0", order=0, command="", status=Status.todo), BaseQueueModel( id="xxx1", order=1, command="", status=Status.doing), BaseQueueModel( id="xxx2", order=2, command="", status=Status.done), BaseQueueModel( id="xxx3", order=3, command="", status=Status.failed), ], ) result = runner.invoke(app, ["list"]) assert result.exit_code == 0, result.stdout assert len(result.stdout.split("\n")) > 4, result.stdout
def test_route_tasks_and_response(mocker: mock, mock_event: dict, player: dict, dynamodb_config: boto3.resource) -> None: """ Test that a combat action proceeds correctly and returns the right response :param mocker: Pytest mock fixture :param mock_event: Mock AWS lambda event dict :param player: Input character dictionary :param dynamodb_config: boto3 config with our resource """ # Arrange # Mock all the things we already tested mocker.patch( "worlds_worst_serverless.worlds_worst_operator.actions.random.choice", return_value="block", ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.operator.boto3.resource", return_value=dynamodb_config, ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.operator.os.environ", return_value="Table", ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.actions.get_player", return_value={"player_data": player}, ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.database_ops.get_player", return_value={"player_data": player}, ) mocker.patch( "worlds_worst_serverless.worlds_worst_operator.operator.update_player", return_value={}, ) # Expect player to get hit for 100 damage and get 100 ex expected_player = Player(**player) expected_player.hit_points = 400 expected_player.ex = 100 expected_message = [ "Truckthunders uses attack!", "Truckthunders uses block!", "Truckthunders wins.", "Truckthunders has 500 HP left.", ] expected_action_results = json.dumps({ "Player": asdict(expected_player), "message": expected_message }) expected_response = { "statusCode": 200, "body": expected_action_results, "headers": { "Access-Control-Allow-Origin": "*" }, } # Act response = operator.route_tasks_and_response(mock_event, mock_event) # Assert assert response == expected_response