def test_stop_raises_if_notification_pulling_is_broken(self):
        system = System(pipes=[
            [
                BankAccounts,
                TestNewMultiThreadedRunner.BrokenPulling,
            ],
        ])
        # Create runner.
        self.runner = self.runner_class(system)

        # Create some notifications.
        accounts = self.runner.get(BankAccounts)
        accounts.open_account(
            full_name="Alice",
            email_address="*****@*****.**",
        )

        # Start runner.
        self.runner.start()

        # Trigger pulling of notifications.
        accounts = self.runner.get(BankAccounts)
        accounts.open_account(
            full_name="Alice",
            email_address="*****@*****.**",
        )

        # Wait for runner to error.
        self.assertTrue(self.runner.has_errored.wait(timeout=1))

        # Check stop() raises exception.
        with self.assertRaises(NotificationPullingError) as cm:
            self.runner.stop()
        self.assertIn(
            "Just testing error handling when pulling is broken",
            cm.exception.args[0],
        )
        self.runner = None
    def test_stops_if_app_processing_is_broken(self):
        system = System(pipes=[
            [
                BankAccounts,
                TestMultiThreadedRunner.BrokenProcessing,
            ],
        ])

        self.start_runner(system)

        accounts = self.runner.get(BankAccounts)
        accounts.open_account(
            full_name="Alice",
            email_address="*****@*****.**",
        )

        # Check watch_for_errors() raises exception.
        with self.assertRaises(EventProcessingError) as cm:
            self.runner.watch_for_errors(timeout=1)
        self.assertIn(
            "Just testing error handling when processing is broken",
            cm.exception.args[0],
        )
        self.runner = None
Beispiel #3
0
    def test_prompts_received_doesnt_accumulate_names(self):
        system = System(
            pipes=[
                [
                    BankAccounts,
                    EmailNotifications,
                ],
            ]
        )

        runner = self.runner_class(system)
        runner.start()

        with self.assertRaises(RunnerAlreadyStarted):
            runner.start()

        # Check prompts_received list doesn't accumulate.
        runner.is_prompting = True
        self.assertEqual(runner.prompts_received, [])
        runner.receive_prompt("BankAccounts")
        self.assertEqual(runner.prompts_received, ["BankAccounts"])
        runner.receive_prompt("BankAccounts")
        self.assertEqual(runner.prompts_received, ["BankAccounts"])
        runner.is_prompting = False
 def test_calling_start_twice_raises_error(self):
     self.start_runner(System(pipes=[[BankAccounts]]))
     with self.assertRaises(RunnerAlreadyStarted):
         self.runner.start()
 def test_starts_with_single_app(self):
     self.start_runner(System(pipes=[[BankAccounts]]))
     app = self.runner.get(BankAccounts)
     self.assertIsInstance(app, BankAccounts)
    def test_system_with_processing_loop(self):
        class Command(Aggregate):
            def __init__(self, text: str):
                self.text = text
                self.output: Optional[str] = None
                self.error: Optional[str] = None

            @event
            def done(self, output: str, error: str):
                self.output = output
                self.error = error

        class Result(Aggregate):
            def __init__(self, command_id: UUID, output: str, error: str):
                self.command_id = command_id
                self.output = output
                self.error = error

        class Commands(ProcessApplication):
            def create_command(self, text: str) -> UUID:
                command = Command(text=text)
                self.save(command)
                return command.id

            def policy(
                self,
                domain_event: AggregateEvent[Aggregate],
                processing_event: ProcessingEvent,
            ) -> None:
                if isinstance(domain_event, Result.Created):
                    command = self.repository.get(domain_event.command_id)
                    command.done(
                        output=domain_event.output,
                        error=domain_event.error,
                    )
                    processing_event.collect_events(command)

            def get_result(self, command_id: UUID) -> Tuple[str, str]:
                command = self.repository.get(command_id)
                return command.output, command.error

        class Results(ProcessApplication):
            def policy(
                self,
                domain_event: AggregateEvent[Aggregate],
                processing_event: ProcessingEvent,
            ) -> None:
                if isinstance(domain_event, Command.Created):
                    try:
                        output = subprocess.check_output(
                            shlex.split(domain_event.text))
                        error = ""
                    except Exception as e:
                        error = str(e)
                        output = b""
                    result = Result(
                        command_id=domain_event.originator_id,
                        output=output.decode("utf8"),
                        error=error,
                    )
                    processing_event.collect_events(result)

        self.start_runner(System([[Commands, Results, Commands]]))

        commands = self.runner.get(Commands)
        command_id1 = commands.create_command("echo 'Hello World'")
        command_id2 = commands.create_command("notacommand")

        self.wait_for_runner()
        self.wait_for_runner()

        for _ in range(10):
            output, error = commands.get_result(command_id1)
            if output is None:
                sleep(0.1)
            else:
                break
        else:
            self.fail("No results from command")

        self.assertEqual(output, "Hello World\n")
        self.assertEqual(error, "")

        for _ in range(10):
            output, error = commands.get_result(command_id2)
            if output is None:
                sleep(0.1)
            else:
                break
        else:
            self.fail("No results from command")

        self.assertEqual(output, "")
        self.assertIn("No such file or directory: 'notacommand'", error)
Beispiel #7
0
from eventsourcing.system import System, SingleThreadedRunner
from stocky.command.account.application import AccountApplication, AccountApplicationProducer

# init
system = System(pipes=[[AccountApplication, AccountApplicationProducer]])
runner = SingleThreadedRunner(system)
runner.start()

accounts = runner.get(AccountApplication)
producer = AccountApplicationProducer()

accounts.lead(producer)
producer.follow(accounts.__class__.__name__, accounts.log)