class MonitoringTests(TestCase):

    MAD_FILE = "test.mad"

    def setUp(self):
        self.file_system = InMemoryFileSystem()

    def test_loading(self):
        Arguments._identifier = lambda s: "1"

        self.file_system.define(
            self.MAD_FILE, "service DB {"
            "  operation Select {"
            "      think 5"
            "   }"
            "}"
            "client Browser {"
            "  every 10 {"
            "      query DB/Select"
            "   }"
            "}")

        controller = Controller(StringIO(), self.file_system)

        controller.execute("test.mad", "25")

        data = self.file_system.opened_files["test_1/DB.log"].getvalue().split(
            "\n")
        self.assertEqual(4, len(data),
                         data)  # header line, + Monitoring at 10, 20 + newline
Ejemplo n.º 2
0
class MonitoringTests(TestCase):

    MAD_FILE = "test.mad"

    def setUp(self):
        self.file_system = InMemoryFileSystem()

    def test_loading(self):
        Arguments._identifier = lambda s: "1"

        self.file_system.define(
            self.MAD_FILE,
            "service DB {"
            "  operation Select {"
            "      think 5"
            "   }"
            "}"
            "client Browser {"
            "  every 10 {"
            "      query DB/Select"
            "   }"
            "}")

        controller = Controller(StringIO(), self.file_system)

        controller.execute("test.mad", "25")

        data = self.file_system.opened_files["test_1/DB.log"].getvalue().split("\n")
        self.assertEqual(4, len(data), data) # header line, + Monitoring at 10, 20 + newline
Ejemplo n.º 3
0
class TestXXX(TestCase):
    # TODO to be move in the acceptance tests

    def setUp(self):
        self.file_system = InMemoryFileSystem()

    @skip("Debugging Sensapp example")
    def test_sensapp(self):
        with open(
                "C:/Users/franckc/home/projects/diversify/dev/mad/samples/sensapp/sensapp.mad"
        ) as source:
            self.file_system.define("test.mad", source.read())

        controller = Controller(StringIO(), self.file_system)
        simulation = controller.execute("test.mad", "200")

    def test_client_server_with_autoscaling(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   settings {"
            "      autoscaling {"
            "          period: 10"
            "          limits: [3, 6]"
            "      }"
            "   }"
            "   operation Select {"
            "      think 9"
            "   }"
            "}"
            "client Browser {"
            "  every 2 {"
            "      query DB/Select"
            "  }"
            "}")

        controller = Controller(StringIO(), self.file_system)
        simulation = controller.execute("test.mad", "115")

        server = simulation.environment.look_up("DB")
        worker_pool = server.environment.look_up(Symbols.WORKER_POOL)
        self.assertEqual(5, worker_pool.capacity)
Ejemplo n.º 4
0
class TestXXX(TestCase):
    # TODO to be move in the acceptance tests

    def setUp(self):
        self.file_system = InMemoryFileSystem()

    @skip("Debugging Sensapp example")
    def test_sensapp(self):
        with open("C:/Users/franckc/home/projects/diversify/dev/mad/samples/sensapp/sensapp.mad") as source:
            self.file_system.define("test.mad", source.read())

        controller = Controller(StringIO(), self.file_system)
        simulation = controller.execute("test.mad", "200")

    def test_client_server_with_autoscaling(self):
        self.file_system.define(
            "test.mad",
            "service DB {"
            "   settings {"
            "      autoscaling {"
            "          period: 10"
            "          limits: [3, 6]"
            "      }"
            "   }"
            "   operation Select {"
            "      think 9"
            "   }"
            "}"
            "client Browser {"
            "  every 2 {"
            "      query DB/Select"
            "  }"
            "}")

        controller = Controller(StringIO(), self.file_system)
        simulation = controller.execute("test.mad", "115")

        server = simulation.environment.look_up("DB")
        worker_pool = server.environment.look_up(Symbols.WORKER_POOL)
        self.assertEqual(5, worker_pool.capacity)
Ejemplo n.º 5
0
 def setUp(self):
     self.file_system = InMemoryFileSystem()
Ejemplo n.º 6
0
class CorrectExpressionTests(ParserTests):

    MAD_FILE = "test.mad"

    def setUp(self):
        self.file_system = InMemoryFileSystem()

    def test_parsing_all_expressions(self):
        for (text, expected_result, rule) in self._all_expressions():
            self.file_system.define(self.MAD_FILE, text)
            actual_result = self._do_parse(rule)
            self.assertEqual(expected_result, actual_result,
                             "Fail to parse '%s'" % text)

    def _all_expressions(self):
        return [
            ("query DB/Select", Query("DB", "Select"), "query"),
            ("query DB/Select {timeout: 50}", Query("DB", "Select",
                                                    timeout=50), "query"),
            ("query DB/Select {priority: 12}",
             Query("DB", "Select", priority=12), "query"),
            ("query DB/Select {priority: 12, timeout: 50}",
             Query("DB", "Select", priority=12, timeout=50), "query"),
            ("invoke DB/Select", Trigger("DB", "Select"), "invoke"),
            ("invoke DB/Select {priority: 12}", Trigger("DB", "Select",
                                                        12), "invoke"),
            ("think 5", Think(5), "think"), ("fail", Fail(), "fail"),
            ("fail 0.5", Fail(probability=0.5), "fail"),
            ("think 5 "
             "invoke DB/Select "
             "query DB/Insert "
             "ignore {"
             "  fail "
             "}",
             Sequence(Think(5), Trigger("DB", "Select"), Query("DB", "Insert"),
                      IgnoreError(Fail())), "action_list"),
            ("retry { think 5 }", Retry(Think(5)), "retry"),
            ("retry (limit: 5) { think 5 }", Retry(Think(5),
                                                   limit=5), "retry"),
            ("retry (delay: constant(10)) { think 5 }",
             Retry(Think(5), delay=Delay(10, "constant")), "retry"),
            ("retry (limit: 23, delay: exponential(135)) { think 5 }",
             Retry(Think(5), limit=23, delay=Delay(135,
                                                   "exponential")), "retry"),
            ("ignore { think 5 }", IgnoreError(Think(5)), "ignore"),
            ("operation Select { think 5 }",
             DefineOperation("Select", Think(5)), "define_operation"),
            ("service DB { operation Select { think 4 } }",
             DefineService("DB", DefineOperation("Select",
                                                 Think(4))), "define_service"),
            ("client Browser { every 5 { query DB/Select } }",
             DefineClientStub("Browser", 5, Query("DB",
                                                  "Select")), "define_client"),
            ("service DB { "
             "  operation Select { "
             "      think 4 "
             "  }"
             "}"
             "client Browser { "
             "  every 5 { "
             "      query DB/Select"
             "  }"
             "}",
             Sequence(DefineService("DB", DefineOperation("Select", Think(4))),
                      DefineClientStub("Browser", 5,
                                       Query("DB", "Select"))), "unit"),
            ("settings { queue: LIFO }", Settings(queue=LIFO()), "settings"),
            ("autoscaling {"
             "  period: 134"
             "  limits: [27, 52]"
             "}", {
                 "autoscaling": Autoscaling(period=134, limits=(27, 52))
             }, "autoscaling"),
            ("throttling: none", {
                "throttling": NoThrottlingSettings()
            }, "throttling"),
            ("throttling: tail-drop(50)", {
                "throttling": TailDropSettings(capacity=50)
            }, "throttling"),
            ("settings {"
             "  queue: FIFO"
             "  autoscaling {"
             "      limits: [1, 5]"
             "  }"
             "  throttling: tail-drop(50)"
             "}",
             Settings(queue=FIFO(),
                      autoscaling=Autoscaling(limits=(1, 5)),
                      throttling=TailDropSettings(50)), "settings"),
            ("service DB { "
             "  settings {"
             "      queue: LIFO"
             "  }"
             "  operation Select { "
             "      think 4 "
             "  }"
             "}"
             "client Browser { "
             "  every 5 { "
             "      query DB/Select"
             "  }"
             "}",
             Sequence(
                 DefineService(
                     "DB",
                     Sequence(Settings(queue=LIFO()),
                              DefineOperation("Select", Think(4)))),
                 DefineClientStub("Browser", 5, Query("DB",
                                                      "Select"))), "unit")
        ]
Ejemplo n.º 7
0
 def setUp(self):
     Arguments._identifier = MagicMock(return_value=self.IDENTIFIER)
     self.display = StringIO()
     self.file_system = InMemoryFileSystem()
Ejemplo n.º 8
0
class MadAcceptanceTests(TestCase):

    IDENTIFIER = "1"
    MODEL_NAME = "test"
    LOCATION = MODEL_NAME + ".mad"

    def setUp(self):
        Arguments._identifier = MagicMock(return_value=self.IDENTIFIER)
        self.display = StringIO()
        self.file_system = InMemoryFileSystem()

    def _execute(self, command_line = None):
        if not command_line:
            command_line = [self.LOCATION, 1000]
        mad = Controller(self.display, self.file_system)
        self.simulation = mad.execute(*command_line)

    def _verify_successful_task_count(self, entity_name, expected_count):
        entity = self.simulation.environment.look_up(entity_name)
        monitor = entity.look_up(Symbols.MONITOR)
        #self.assertEqual(expected_count, entity.monitor.success_count)
        self.assertEqual(expected_count, monitor.tasks.successful)

    def _verify_complete_task_count(self, entity_name, expected_count):
        entity = self.simulation.environment.look_up(entity_name)
        monitor = entity.look_up(Symbols.MONITOR)
        #self.assertEqual(expected_count, monitor.statistics.total_request_count)
        self.assertEqual(expected_count, monitor.tasks.complete)

    def _verify_opening(self):
        self._verify_version()
        self._verify_copyright()
        self._verify_disclaimer()

    def _verify_invalid_parameter_count(self, count):
        self._verify_output(Messages.INVALID_PARAMETER_COUNT, count=count)

    def _verify_invalid_simulation_length(self, wrong_length):
        self._verify_output(Messages.INVALID_SIMULATION_LENGTH, length=wrong_length)

    def _verify_invalid_simulation_file(self, wrong_file):
        self._verify_output(Messages.INVALID_SIMULATION_FILE, file=str(wrong_file))

    def _verify_usage(self):
        self._verify_output(Messages.USAGE)

    def _verify_model_loaded(self):
        self._verify_output(Messages.MODEL_LOADED, location=self.LOCATION)

    def _verify_disclaimer(self):
        self._verify_output(Messages.DISCLAIMER)

    def _verify_version(self):
        from mad import __version__ as MAD_VERSION
        self._verify_output(Messages.VERSION, version=MAD_VERSION)

    def _verify_copyright(self):
        from mad import __copyright_years__ as YEARS
        from mad import __copyright_owner__ as OWNER
        self._verify_output(Messages.COPYRIGHT, years=YEARS, owner=OWNER)

    def _verify_valid_model(self):
        self._verify_output_excludes(Messages.INVALID_MODEL)
        self._verify_output_excludes(Messages.SEVERITY_ERROR)

    def _verify_no_warnings(self):
        self._verify_output_excludes(Messages.SEVERITY_WARNING)

    def _verify_syntax_error(self, line, hint):
        self._verify_output(Messages.INVALID_SYNTAX, line=line, hint=hint)

    def _verify_invalid_model(self):
        self._verify_output(Messages.INVALID_MODEL)

    def _verify_unknown_operation(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_UNKNOWN_OPERATION,
                            severity=Messages.SEVERITY_ERROR,
                            service=service_name,
                            operation=operation_name)

    def _verify_duplicate_service(self, service_name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=service_name)

    def _verify_duplicate_client(self, client_name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=client_name)

    def _verify_duplicate_entity_name(self, name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=name)

    def _verify_duplicate_operation(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_DUPLICATE_OPERATION,
                            severity=Messages.SEVERITY_ERROR,
                            operation=operation_name,
                            service=service_name)

    def _verify_operation_never_invoked(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_NEVER_INVOKED_OPERATION,
                            severity=Messages.SEVERITY_WARNING,
                            operation=operation_name,
                            service=service_name)

    def _verify_unknown_service(self, service_name):
        self._verify_output(Messages.ERROR_UNKNOWN_SERVICE,
                            severity=Messages.SEVERITY_ERROR,
                            service=service_name)

    def _verify_output(self, message, **values):
        from re import search, escape
        text = escape(message.format(**values))
        output = self.display.getvalue()
        match = search(text, output)
        self.assertIsNotNone(match, "\nCould not found text '%s' in output:\n%s" % (str(text), output))

    def _verify_output_excludes(self, message, **values):
        from re import search, escape
        text = escape(message.format(**values))
        output = self.display.getvalue()
        match = search(text, output)
        self.assertIsNone(match, "\nFound unexpected text '%s' in output:\n%s" % (str(text), output))

    def _verify_reports_for(self, entities):
        for each_entity in entities:
            self._verify_report(each_entity)

    def _verify_report(self, entity):
        directory = Arguments.OUTPUT_DIRECTORY.format(name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        report = Arguments.REPORT.format(entity=entity, directory=directory)
        self.assertTrue(self.file_system.has_file(report),
                        "Missing report for '%s' (file '%s').\n Existing files are %s" % (entity, report, str(list(self.file_system.opened_files.keys()))))

    def _verify_log(self):
        directory = Arguments.OUTPUT_DIRECTORY.format(name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        report = Arguments.PATH_TO_LOG_FILE.format(directory=directory, log_file=Arguments.LOG_FILE)
        self.assertTrue(self.file_system.has_file(report),
                        "Missing log file '%s'.\n Existing files are %s" % (report, str(list(self.file_system.opened_files.keys()))))

    def _verify_model_copy(self):
        directory = Arguments.OUTPUT_DIRECTORY.format(name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        model_copy = Arguments.PATH_TO_MODEL_COPY.format(directory=directory, file=self.MODEL_NAME+".mad")
        self.assertTrue(self.file_system.has_file(model_copy),
                        "Missing copy of the model '%s'.\n Existing files are %s" % (model_copy, str(list(self.file_system.opened_files.keys()))))
Ejemplo n.º 9
0
 def setUp(self):
     self.file_system = InMemoryFileSystem()
Ejemplo n.º 10
0
 def setUp(self):
     Arguments._identifier = MagicMock(return_value=self.IDENTIFIER)
     self.display = StringIO()
     self.file_system = InMemoryFileSystem()
Ejemplo n.º 11
0
class MadAcceptanceTests(TestCase):

    IDENTIFIER = "1"
    MODEL_NAME = "test"
    LOCATION = MODEL_NAME + ".mad"

    def setUp(self):
        Arguments._identifier = MagicMock(return_value=self.IDENTIFIER)
        self.display = StringIO()
        self.file_system = InMemoryFileSystem()

    def _execute(self, command_line = None):
        if not command_line:
            command_line = [self.LOCATION, 1000]
        mad = Controller(self.display, self.file_system)
        self.simulation = mad.execute(*command_line)

    def _verify_successful_task_count(self, entity_name, expected_count):
        entity = self.simulation.environment.look_up(entity_name)
        monitor = entity.look_up(Symbols.MONITOR)
        #self.assertEqual(expected_count, entity.monitor.success_count)
        self.assertEqual(expected_count, monitor.tasks.successful)

    def _verify_complete_task_count(self, entity_name, expected_count):
        entity = self.simulation.environment.look_up(entity_name)
        monitor = entity.look_up(Symbols.MONITOR)
        #self.assertEqual(expected_count, monitor.statistics.total_request_count)
        self.assertEqual(expected_count, monitor.tasks.complete)

    def _verify_opening(self):
        self._verify_version()
        self._verify_copyright()
        self._verify_disclaimer()

    def _verify_invalid_parameter_count(self, count):
        self._verify_output(Messages.INVALID_PARAMETER_COUNT, count=count)

    def _verify_invalid_simulation_length(self, wrong_length):
        self._verify_output(Messages.INVALID_SIMULATION_LENGTH, length=wrong_length)

    def _verify_invalid_simulation_file(self, wrong_file):
        self._verify_output(Messages.INVALID_SIMULATION_FILE, file=str(wrong_file))

    def _verify_usage(self):
        self._verify_output(Messages.USAGE)

    def _verify_model_loaded(self):
        self._verify_output(Messages.MODEL_LOADED, location=self.LOCATION)

    def _verify_disclaimer(self):
        self._verify_output(Messages.DISCLAIMER)

    def _verify_version(self):
        from mad import __version__ as MAD_VERSION
        self._verify_output(Messages.VERSION, version=MAD_VERSION)

    def _verify_copyright(self):
        from mad import __copyright_years__ as YEARS
        from mad import __copyright_owner__ as OWNER
        self._verify_output(Messages.COPYRIGHT, years=YEARS, owner=OWNER)

    def _verify_valid_model(self):
        self._verify_output_excludes(Messages.INVALID_MODEL)
        self._verify_output_excludes(Messages.SEVERITY_ERROR)

    def _verify_no_warnings(self):
        self._verify_output_excludes(Messages.SEVERITY_WARNING)

    def _verify_syntax_error(self, line, hint):
        self._verify_output(Messages.INVALID_SYNTAX, line=line, hint=hint)

    def _verify_invalid_model(self):
        self._verify_output(Messages.INVALID_MODEL)

    def _verify_unknown_operation(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_UNKNOWN_OPERATION,
                            severity=Messages.SEVERITY_ERROR,
                            service=service_name,
                            operation=operation_name)

    def _verify_duplicate_service(self, service_name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=service_name)

    def _verify_duplicate_client(self, client_name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=client_name)

    def _verify_duplicate_entity_name(self, name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=name)

    def _verify_duplicate_operation(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_DUPLICATE_OPERATION,
                            severity=Messages.SEVERITY_ERROR,
                            operation=operation_name,
                            service=service_name)

    def _verify_operation_never_invoked(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_NEVER_INVOKED_OPERATION,
                            severity=Messages.SEVERITY_WARNING,
                            operation=operation_name,
                            service=service_name)

    def _verify_unknown_service(self, service_name):
        self._verify_output(Messages.ERROR_UNKNOWN_SERVICE,
                            severity=Messages.SEVERITY_ERROR,
                            service=service_name)

    def _verify_output(self, message, **values):
        from re import search, escape
        text = escape(message.format(**values))
        output = self.display.getvalue()
        match = search(text, output)
        self.assertIsNotNone(match, "\nCould not found text '%s' in output:\n%s" % (str(text), output))

    def _verify_output_excludes(self, message, **values):
        from re import search, escape
        text = escape(message.format(**values))
        output = self.display.getvalue()
        match = search(text, output)
        self.assertIsNone(match, "\nFound unexpected text '%s' in output:\n%s" % (str(text), output))

    def _verify_reports_for(self, entities):
        for each_entity in entities:
            self._verify_report(each_entity)

    def _verify_report(self, entity):
        directory = Arguments.OUTPUT_DIRECTORY.format(name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        report = Arguments.REPORT.format(entity=entity, directory=directory)
        self.assertTrue(self.file_system.has_file(report),
                        "Missing report for '%s' (file '%s').\n Existing files are %s" % (entity, report, str(self.file_system.opened_files.keys())))

    def _verify_log(self):
        directory = Arguments.OUTPUT_DIRECTORY.format(name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        report = Arguments.PATH_TO_LOG_FILE.format(directory=directory, log_file=Arguments.LOG_FILE)
        self.assertTrue(self.file_system.has_file(report),
                        "Missing log file '%s'.\n Existing files are %s" % (report, str(self.file_system.opened_files.keys())))

    def _verify_model_copy(self):
        directory = Arguments.OUTPUT_DIRECTORY.format(name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        model_copy = Arguments.PATH_TO_MODEL_COPY.format(directory=directory, file=self.MODEL_NAME+".mad")
        self.assertTrue(self.file_system.has_file(model_copy),
                        "Missing copy of the model '%s'.\n Existing files are %s" % (model_copy, str(self.file_system.opened_files.keys())))
Ejemplo n.º 12
0
class AcceptanceTests(TestCase):

    IDENTIFIER = "1"
    MODEL_NAME = "test"
    LOCATION = MODEL_NAME + ".mad"

    def setUp(self):
        Arguments._identifier = MagicMock(return_value=self.IDENTIFIER)
        self.display = StringIO()
        self.file_system = InMemoryFileSystem()

    def test_client_server(self):
        self.file_system.define(
            "test.mad", ""
            "service DB {"
            "   operation Insert {"
            "      think 5"
            "      query Mirror/Insert"
            "      fail 0.5"
            "   }"
            "   operation Select {"
            "      think 5"
            "   }"
            "}"
            "service Mirror {"
            "   operation Insert {"
            "      think 5"
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DB/Select"
            "      retry (limit: 5, delay:exponential(5)) {"
            "           invoke DB/Insert"
            "      }"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_valid_model()
        self._verify_no_warnings()
        self._verify_reports_for(["DB"])
        self._verify_log()

    def test_priority_scheme(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "}"
            ""
            "client Browser_A {"
            "   every 1 {"
            "      query DB/Select {priority: 10}"
            "   }"
            "}"
            ""
            "client Browser_B {"
            "   every 10 {"
            "      query DB/Select {priority: 0}"
            "   }"
            "}")

        self._execute([self.LOCATION, 22])

        self._verify_opening()
        self._verify_valid_model()
        self._verify_no_warnings()
        self._verify_successful_invocations("Browser_A", 3)
        self._verify_successful_invocations("Browser_B", 0)
        self._verify_reports_for(["DB"])
        self._verify_log()

    def test_fail(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      fail"
            "   }"
            "}"
            ""
            "client Browser {"
            "   every 2 {"
            "       query DB/Select "
            "   }"
            "}")

        self._execute([self.LOCATION, 100])

        self._verify_opening()
        self._verify_valid_model()
        self._verify_no_warnings()
        self._verify_successful_invocations("Browser", 0)
        self._verify_reports_for(["DB"])
        self._verify_log()

    def test_retry(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      fail"
            "   }"
            "}"
            ""
            "client Browser {"
            "   every 100 {"
            "       retry(delay:constant(2), limit:10) {"
            "           query DB/Select"
            "       }"
            "   }"
            "}")

        self._execute([self.LOCATION, 200])

        self._verify_opening()
        self._verify_valid_model()
        self._verify_no_warnings()
        self._verify_successful_invocations("Browser", 0)
        self._verify_request_count("DB", 10)
        self._verify_reports_for(["DB"])
        self._verify_log()

    def test_ignore_error(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      fail"
            "   }"
            "}"
            ""
            "client Browser {"
            "   every 20 {"
            "       ignore {"
            "           query DB/Select"
            "       }"
            "   }"
            "}")

        self._execute([self.LOCATION, 40])

        self._verify_opening()
        self._verify_valid_model()
        self._verify_no_warnings()
        self._verify_successful_invocations("Browser", 1)
        self._verify_reports_for(["DB"])
        self._verify_log()

    def test_timeouts(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 10"
            "   }"
            "}"
            "client Browser {"
            "   every 20 {"
            "      query DB/Select {timeout: 5}"
            "   }"
            "}")

        self._execute([self.LOCATION, 100])

        self._verify_opening()
        self._verify_valid_model()
        self._verify_no_warnings()
        self._verify_successful_invocations("Browser", 0)
        self._verify_reports_for(["DB"])
        self._verify_log()

    def test_invalid_simulation_length(self):
        self.file_system.define("test.mad",
                                "whatever, as it will not be parsed!")

        wrong_length = "wrong length"
        invalid_command_line = ["test.mad", wrong_length]
        self._execute(invalid_command_line)

        self._verify_opening()
        self._verify_invalid_simulation_length(wrong_length)
        self._verify_usage()

    def test_invalid_simulation_file(self):
        self.file_system.define("test.mad",
                                "whatever, as it will not be parsed!")

        wrong_file = 1
        invalid_command_line = [wrong_file, 1000]
        self._execute(invalid_command_line)

        self._verify_opening()
        self._verify_invalid_simulation_file(wrong_file)
        self._verify_usage()

    def test_invalid_parameter_count(self):
        self.file_system.define("test.mad",
                                "whatever, as it will not be parsed!")

        invalid_command_line = ["test.mad", 1000, "an extra parameter"]
        self._execute(invalid_command_line)

        self._verify_opening()
        self._verify_invalid_parameter_count(len(invalid_command_line))
        self._verify_usage()

    def test_error_empty_service(self):
        self.file_system.define(
            "test.mad", "service DB { \n"
            "   settings { \n"
            "       queue: LIFO \n"
            "   } \n"
            "} \n"
            "client Browser { \n"
            "   every 5 { \n"
            "      query DB/Insert \n"
            "   } \n"
            "} \n")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_syntax_error(line=5, hint="}")

    def test_error_unknown_operation(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DB/Insert"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_unknown_operation("DB", "Insert")
        self._verify_operation_never_invoked("DB", "Select")

    def test_error_duplicate_service(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "}"
            "service DB {"
            "   operation Insert {"
            "      think 17"
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DB/Select"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_duplicate_service("DB")

    def test_error_duplicate_client(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5 "
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DB/Select"
            "   }"
            "}"
            "client Browser { "
            "   every 10 {"
            "       invoke DB/Select"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_duplicate_client("Browser")

    def test_error_duplicate_entity_name(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "}"
            "client DB {"
            "   every 5 {"
            "      query DB/Select"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_duplicate_entity_name("DB")

    def test_error_duplicate_operation(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "   operation Select  {"
            "      think 17"
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DB/Select"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_duplicate_operation("DB", "Select")

    def test_warning_operation_never_invoked(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "   operation Insert {"
            "      think 17"
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DB/Select"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_valid_model()
        self._verify_operation_never_invoked("DB", "Insert")

    def test_error_unknown_service(self):
        self.file_system.define(
            "test.mad", "service DB {"
            "   operation Select {"
            "      think 5"
            "   }"
            "}"
            "client Browser {"
            "   every 5 {"
            "      query DBBBB/Select"
            "   }"
            "}")

        self._execute()

        self._verify_opening()
        self._verify_model_loaded()
        self._verify_invalid_model()
        self._verify_unknown_service("DBBBB")

    def _execute(self, command_line=None):
        if not command_line:
            command_line = [self.LOCATION, 1000]
        mad = Controller(self.display, self.file_system)
        self.simulation = mad.execute(*command_line)

    def _verify_successful_invocations(self, entity_name, expected_count):
        entity = self.simulation.environment.look_up(entity_name)
        self.assertEqual(expected_count, entity.monitor.success_count)

    def _verify_request_count(self, entity_name, expected_count):
        entity = self.simulation.environment.look_up(entity_name)
        monitor = entity.look_up(Symbols.MONITOR)
        self.assertEqual(expected_count,
                         monitor.statistics.total_request_count)

    def _verify_opening(self):
        self._verify_version()
        self._verify_copyright()
        self._verify_disclaimer()

    def _verify_invalid_parameter_count(self, count):
        self._verify_output(Messages.INVALID_PARAMETER_COUNT, count=count)

    def _verify_invalid_simulation_length(self, wrong_length):
        self._verify_output(Messages.INVALID_SIMULATION_LENGTH,
                            length=wrong_length)

    def _verify_invalid_simulation_file(self, wrong_file):
        self._verify_output(Messages.INVALID_SIMULATION_FILE,
                            file=str(wrong_file))

    def _verify_usage(self):
        self._verify_output(Messages.USAGE)

    def _verify_model_loaded(self):
        self._verify_output(Messages.MODEL_LOADED, location=self.LOCATION)

    def _verify_disclaimer(self):
        self._verify_output(Messages.DISCLAIMER)

    def _verify_version(self):
        from mad import __version__ as MAD_VERSION
        self._verify_output(Messages.VERSION, version=MAD_VERSION)

    def _verify_copyright(self):
        from mad import __copyright_years__ as YEARS
        from mad import __copyright_owner__ as OWNER
        self._verify_output(Messages.COPYRIGHT, years=YEARS, owner=OWNER)

    def _verify_valid_model(self):
        self._verify_output_excludes(Messages.INVALID_MODEL)
        self._verify_output_excludes(Messages.SEVERITY_ERROR)

    def _verify_no_warnings(self):
        self._verify_output_excludes(Messages.SEVERITY_WARNING)

    def _verify_syntax_error(self, line, hint):
        self._verify_output(Messages.INVALID_SYNTAX, line=line, hint=hint)

    def _verify_invalid_model(self):
        self._verify_output(Messages.INVALID_MODEL)

    def _verify_unknown_operation(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_UNKNOWN_OPERATION,
                            severity=Messages.SEVERITY_ERROR,
                            service=service_name,
                            operation=operation_name)

    def _verify_duplicate_service(self, service_name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=service_name)

    def _verify_duplicate_client(self, client_name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=client_name)

    def _verify_duplicate_entity_name(self, name):
        self._verify_output(Messages.ERROR_DUPLICATE_IDENTIFIER,
                            severity=Messages.SEVERITY_ERROR,
                            identifier=name)

    def _verify_duplicate_operation(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_DUPLICATE_OPERATION,
                            severity=Messages.SEVERITY_ERROR,
                            operation=operation_name,
                            service=service_name)

    def _verify_operation_never_invoked(self, service_name, operation_name):
        self._verify_output(Messages.ERROR_NEVER_INVOKED_OPERATION,
                            severity=Messages.SEVERITY_WARNING,
                            operation=operation_name,
                            service=service_name)

    def _verify_unknown_service(self, service_name):
        self._verify_output(Messages.ERROR_UNKNOWN_SERVICE,
                            severity=Messages.SEVERITY_ERROR,
                            service=service_name)

    def _verify_output(self, message, **values):
        from re import search, escape
        text = escape(message.format(**values))
        output = self.display.getvalue()
        match = search(text, output)
        self.assertIsNotNone(
            match,
            "\nCould not found text '%s' in output:\n%s" % (str(text), output))

    def _verify_output_excludes(self, message, **values):
        from re import search, escape
        text = escape(message.format(**values))
        output = self.display.getvalue()
        match = search(text, output)
        self.assertIsNone(
            match, "\nFound unexpected text '%s' in output:\n%s" %
            (str(text), output))

    def _verify_reports_for(self, entities):
        for each_entity in entities:
            self._verify_report(each_entity)

    def _verify_report(self, entity):
        directory = Arguments.OUTPUT_DIRECTORY.format(
            name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        report = Arguments.REPORT.format(entity=entity, directory=directory)
        self.assertTrue(
            self.file_system.has_file(report),
            "Missing report for '%s' (file '%s').\n Existing files are %s" %
            (entity, report, str(self.file_system.opened_files.keys())))

    def _verify_log(self):
        directory = Arguments.OUTPUT_DIRECTORY.format(
            name=self.MODEL_NAME, identifier=self.IDENTIFIER)
        report = Arguments.PATH_TO_LOG_FILE.format(directory=directory,
                                                   log_file=Arguments.LOG_FILE)
        self.assertTrue(
            self.file_system.has_file(report),
            "Missing log file '%s'.\n Existing files are %s" %
            (report, str(self.file_system.opened_files.keys())))