def sample_workflow(self):
        wf = Workflow()

        wf.mco_model = self.mco_factory.create_model()
        wf.mco_model.parameters = [self.mco_parameter_factory.create_model()]
        wf.mco_model.kpis = [KPISpecification()]
        wf.execution_layers = [
            ExecutionLayer(data_sources=[
                self.data_source_factory.create_model(),
                self.data_source_factory.create_model(),
            ]),
            ExecutionLayer(
                data_sources=[self.data_source_factory.create_model()]),
        ]
        return wf
Beispiel #2
0
    def setUp(self):
        self.registry = ProbeFactoryRegistry()
        self.plugin = self.registry.plugin

        factory = self.registry.data_source_factories[0]
        self.layer = ExecutionLayer(
            data_sources=[factory.create_model(),
                          factory.create_model()])
Beispiel #3
0
    def test_data_sources(self):
        wf = self.workflow
        mco_factory = self.plugin.mco_factories[0]
        wf.mco_model = mco_factory.create_model()
        parameter_factory = mco_factory.parameter_factories[0]
        wf.mco_model.parameters.append(parameter_factory.create_model())
        wf.mco_model.parameters[0].name = "name"
        wf.mco_model.parameters[0].type = "type"
        wf.mco_model.kpis.append(KPISpecification(name='name'))

        layer = ExecutionLayer()
        wf.execution_layers.append(layer)
        ds_factory = self.plugin.data_source_factories[0]
        ds_model = ds_factory.create_model()
        layer.data_sources.append(ds_model)

        errors = verify_workflow(wf)
        self.assertEqual(errors[0].subject, ds_model)
        self.assertIn(
            "The number of input slots (1 values) returned by "
            "'Dummy data source' does not match the number "
            "of user-defined names specified (0 values). This "
            "is either a plugin error or a file error.", errors[0].local_error)

        ds_model.input_slot_info.append(InputSlotInfo(name="name"))

        errors = verify_workflow(wf)
        self.assertEqual(errors[0].subject, ds_model)
        self.assertIn(
            "The number of output slots (1 values) returned by "
            "'Dummy data source' does not match the number "
            "of user-defined names specified (0 values). This "
            "is either a plugin error or a file error.", errors[0].local_error)

        ds_model.output_slot_info.append(OutputSlotInfo(name="name"))

        errors = verify_workflow(wf)
        self.assertEqual(len(errors), 0)

        ds_model.input_slot_info[0].name = ''
        errors = verify_workflow(wf)
        self.assertEqual(len(errors), 1)
        self.assertIn("Input slot is not named", errors[0].local_error)

        ds_model.output_slot_info[0].name = ''
        errors = verify_workflow(wf)
        self.assertEqual(len(errors), 3)
        self.assertIn("All output variables have undefined names",
                      errors[1].local_error)
        self.assertIn("An output variable has an undefined name",
                      errors[2].local_error)
Beispiel #4
0
    def test_empty_execution_layer(self):
        wf = self.workflow
        mco_factory = self.plugin.mco_factories[0]
        wf.mco_model = mco_factory.create_model()
        parameter_factory = mco_factory.parameter_factories[0]
        wf.mco_model.parameters.append(parameter_factory.create_model())
        wf.mco_model.parameters[0].name = "name"
        wf.mco_model.parameters[0].type = "type"
        wf.mco_model.kpis.append(KPISpecification(name='name'))

        layer = ExecutionLayer()
        wf.execution_layers.append(layer)
        errors = verify_workflow(wf)

        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0].subject, wf.execution_layers[0])
Beispiel #5
0
    def test_multilayer_execution(self):
        # The multilayer peforms the following execution
        # layer 0: in1 + in2   | in3 + in4
        #             res1          res2
        # layer 1:        res1 + res2
        #                    res3
        # layer 2:        res3 * res1
        #                     res4
        # layer 3:        res4 * res2
        #                     out1
        # Final result should be
        # out1 = ((in1 + in2 + in3 + in4) * (in1 + in2) * (in3 + in4)

        data_values = [
            DataValue(value=10, name="in1"),
            DataValue(value=15, name="in2"),
            DataValue(value=3, name="in3"),
            DataValue(value=7, name="in4"),
        ]

        def adder(model, parameters):

            first = parameters[0].value
            second = parameters[1].value
            return [DataValue(value=(first + second))]

        adder_factory = ProbeDataSourceFactory(
            self.plugin,
            input_slots_size=2,
            output_slots_size=1,
            run_function=adder,
        )

        def multiplier(model, parameters):
            first = parameters[0].value
            second = parameters[1].value
            return [DataValue(value=(first * second))]

        multiplier_factory = ProbeDataSourceFactory(
            self.plugin,
            input_slots_size=2,
            output_slots_size=1,
            run_function=multiplier,
        )

        mco_factory = ProbeMCOFactory(self.plugin)
        mco_model = mco_factory.create_model()
        parameter_factory = mco_factory.parameter_factories[0]

        mco_model.parameters = [
            parameter_factory.create_model({"name": "in1"}),
            parameter_factory.create_model({"name": "in2"}),
            parameter_factory.create_model({"name": "in3"}),
            parameter_factory.create_model({"name": "in4"}),
        ]
        mco_model.kpis = [KPISpecification(name="out1")]

        wf = Workflow(
            mco_model=mco_model,
            execution_layers=[
                ExecutionLayer(),
                ExecutionLayer(),
                ExecutionLayer(),
                ExecutionLayer(),
            ],
        )
        # Layer 0
        model = adder_factory.create_model()
        model.input_slot_info = [
            InputSlotInfo(name="in1"),
            InputSlotInfo(name="in2"),
        ]
        model.output_slot_info = [OutputSlotInfo(name="res1")]
        wf.execution_layers[0].data_sources.append(model)

        model = adder_factory.create_model()
        model.input_slot_info = [
            InputSlotInfo(name="in3"),
            InputSlotInfo(name="in4"),
        ]
        model.output_slot_info = [OutputSlotInfo(name="res2")]
        wf.execution_layers[0].data_sources.append(model)

        # layer 1
        model = adder_factory.create_model()
        model.input_slot_info = [
            InputSlotInfo(name="res1"),
            InputSlotInfo(name="res2"),
        ]
        model.output_slot_info = [OutputSlotInfo(name="res3")]
        wf.execution_layers[1].data_sources.append(model)

        # layer 2
        model = multiplier_factory.create_model()
        model.input_slot_info = [
            InputSlotInfo(name="res3"),
            InputSlotInfo(name="res1"),
        ]
        model.output_slot_info = [OutputSlotInfo(name="res4")]
        wf.execution_layers[2].data_sources.append(model)

        # layer 3
        model = multiplier_factory.create_model()
        model.input_slot_info = [
            InputSlotInfo(name="res4"),
            InputSlotInfo(name="res2"),
        ]
        model.output_slot_info = [OutputSlotInfo(name="out1")]
        wf.execution_layers[3].data_sources.append(model)

        kpi_results = wf.execute(data_values)
        self.assertEqual(1, len(kpi_results))
        self.assertEqual(8750, kpi_results[0].value)
Beispiel #6
0
    def test_kpi_specification_adherence(self):
        # Often the user may only wish to treat a subset of DataSource
        # output slots as KPIs. This test makes sure they get what they
        # ask for!

        # keep input DataValues constant
        data_values = [
            DataValue(value=99, name="in1"),
            DataValue(value=1, name="in2"),
        ]

        # dummy addition DataSource(a, b) that also returns its inputs
        # [a, b, a+b]
        def adder(model, parameters):
            first = parameters[0].value
            second = parameters[1].value
            return [
                DataValue(value=first),
                DataValue(value=second),
                DataValue(value=(first + second)),
            ]

        adder_factory = ProbeDataSourceFactory(
            self.plugin,
            input_slots_size=2,
            output_slots_size=3,
            run_function=adder,
        )

        mco_factory = ProbeMCOFactory(self.plugin)
        parameter_factory = mco_factory.parameter_factories[0]
        mco_model = mco_factory.create_model()

        # DataSourceModel stats constant throughout
        model = adder_factory.create_model()
        model.input_slot_info = [
            InputSlotInfo(name="in1"),
            InputSlotInfo(name="in2"),
        ]
        model.output_slot_info = [
            OutputSlotInfo(name="out1"),
            OutputSlotInfo(name="out2"),
            OutputSlotInfo(name="out3"),
        ]

        # test Parameter and KPI spec that follows DataSource slots
        # exactly
        mco_model.parameters = [
            parameter_factory.create_model({"name": "in1"}),
            parameter_factory.create_model({"name": "in2"}),
        ]
        mco_model.kpis = [
            KPISpecification(name="out1"),
            KPISpecification(name="out2"),
            KPISpecification(name="out3"),
        ]
        # need to make a new workflow for each KPISpecification
        wf = Workflow(mco_model=mco_model, execution_layers=[ExecutionLayer()])
        wf.execution_layers[0].data_sources.append(model)
        kpi_results = wf.execute(data_values)
        self.assertEqual(len(kpi_results), 3)
        self.assertEqual(kpi_results[0].value, 99)
        self.assertEqual(kpi_results[1].value, 1)
        self.assertEqual(kpi_results[2].value, 100)
        self.assertEqual(kpi_results[0].name, "out1")
        self.assertEqual(kpi_results[1].name, "out2")
        self.assertEqual(kpi_results[2].name, "out3")

        # now test all possible combinations of KPISpecification, including
        # those with KPIs repeated, and empty KPI specification
        import itertools

        out_options = [("out1", 99), ("out2", 1), ("out3", 100)]
        for num_outputs in range(len(out_options) + 2, 0, -1):
            for spec in itertools.permutations(out_options, r=num_outputs):
                mco_model.kpis = [
                    KPISpecification(name=opt[0]) for opt in spec
                ]

                wf = Workflow(
                    mco_model=mco_model, execution_layers=[ExecutionLayer()]
                )
                wf.execution_layers[0].data_sources.append(model)
                kpi_results = wf.execute(data_values)
                self.assertEqual(len(kpi_results), num_outputs)

                for i in range(num_outputs):
                    self.assertEqual(kpi_results[i].name, spec[i][0])
                    self.assertEqual(kpi_results[i].value, spec[i][1])