Beispiel #1
0
    def test_coordination_configuration_parser(self):
        self.cfg_manager._set_value(
            CoordinationConfigurationParser.COORDINATOR_LABORATORY_SERVERS, {
                'laboratory1:WL_SERVER1@WL_MACHINE1': {
                    'exp1|ud-fpga|FPGA experiments': 'fpga1@fpga boards',
                    'exp1|ud-pld|PLD experiments': 'pld1@pld boards',
                },
            })

        configuration = self.coordination_configuration_parser.parse_configuration(
        )
        self.assertEquals(1, len(configuration))
        lab_config = configuration['laboratory1:WL_SERVER1@WL_MACHINE1']
        self.assertEquals(2, len(lab_config))
        exp_fpga = ExperimentInstanceId("exp1", "ud-fpga", "FPGA experiments")
        exp_pld = ExperimentInstanceId("exp1", "ud-pld", "PLD experiments")

        fpga_resource = lab_config[exp_fpga]
        self.assertEquals(Resource("fpga boards", "fpga1"), fpga_resource)

        pld_resource = lab_config[exp_pld]
        self.assertEquals(Resource("pld boards", "pld1"), pld_resource)
Beispiel #2
0
 def _fake_simple_lab_response(self):
     self.lab_mock.reserve_experiment(
         ExperimentInstanceId('inst', 'ud-dummy', 'Dummy experiments'),
         "{}", mocker.ANY)
     self.mocker.result((SessionId.SessionId('my_lab_session_id'), 'ok', {
         'address': 'servexp:inst@mach'
     }))
     self.lab_mock.resolve_experiment_address('my_lab_session_id')
     self.mocker.result(CoordAddress("exp", "inst", "mach"))
     self.lab_mock.should_experiment_finish(
         SessionId.SessionId('my_lab_session_id'))
     self.mocker.result(0)
     self.mocker.replay()
    def test_list_resources(self):
        session = self.session_maker()
        try:
            exp_id1 = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
            resource_instance1 = Resource("type1", "instance1")
            self.resources_manager.add_experiment_instance_id(
                "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id1,
                resource_instance1)

            exp_id2 = ExperimentInstanceId("exp2", "ud-pld", "PLD Experiments")
            resource_instance2 = Resource("type2", "instance1")
            self.resources_manager.add_experiment_instance_id(
                "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id2,
                resource_instance2)
            session.commit()
        finally:
            session.close()

        resources = self.resources_manager.list_resources()
        self.assertEquals(2, len(resources))
        self.assertTrue('type1' in resources)
        self.assertTrue('type2' in resources)
Beispiel #4
0
    def parse_configuration(self):
        #
        # configuration = {
        #      "laboratory1:WL_SERVER1@WL_MACHINE1" : {
        #                 ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments") : ("pld1", "ud-pld-boards")
        #      }
        # }
        #
        configuration = {}

        laboratory_servers = self._cfg_manager.get_value(
            COORDINATOR_LABORATORY_SERVERS)
        for laboratory_server_coord_address_str in laboratory_servers:
            experiment_instances = laboratory_servers[
                laboratory_server_coord_address_str]

            laboratory_configuration = {}
            configuration[
                laboratory_server_coord_address_str] = laboratory_configuration

            for experiment_instance in experiment_instances:
                resource_instance = experiment_instances[experiment_instance]
                mo_experiment_instance = re.match(
                    self.EXPERIMENT_INSTANCE_REGEX, experiment_instance)
                if mo_experiment_instance is None:
                    raise coreExc.CoordinationConfigurationParsingError(
                        "Error in coordination parsing: %s doesn't match the regular expression %s"
                        %
                        (experiment_instance, self.EXPERIMENT_INSTANCE_REGEX))

                mo_resource_instance = re.match(self.RESOURCE_INSTANCE_REGEX,
                                                resource_instance)
                if mo_resource_instance is None:
                    raise coreExc.CoordinationConfigurationParsingError(
                        "Error in coordination parsing: %s doesn't match the regular expression %s"
                        % (resource_instance, self.RESOURCE_INSTANCE_REGEX))

                (inst_name, exp_name,
                 exp_cat_name) = mo_experiment_instance.groups()

                experiment_instance_id = ExperimentInstanceId(
                    inst_name, exp_name, exp_cat_name)

                (resource_instance,
                 resource_type) = mo_resource_instance.groups()

                resource = Resource(resource_type, resource_instance)

                laboratory_configuration[experiment_instance_id] = resource

        return configuration
Beispiel #5
0
    def _parse_assigned_experiments(self):
        assigned_experiments = self._cfg_manager.get_value(
            WEBLAB_LABORATORY_SERVER_ASSIGNED_EXPERIMENTS)

        parsed_experiments = []

        for experiment_instance_id, data in assigned_experiments.items():
            mo = re.match(self.EXPERIMENT_INSTANCE_ID_REGEX,
                          experiment_instance_id)
            if mo == None:
                raise LaboratoryErrors.InvalidLaboratoryConfigurationError(
                    "Invalid configuration entry. Expected format: %s; found: %s"
                    % (LaboratoryServer.EXPERIMENT_INSTANCE_ID_REGEX,
                       experiment_instance_id))
            else:
                # ExperimentInstanceId
                groups = mo.groups()
                (exp_inst_name, exp_name, exp_cat_name) = groups
                experiment_instance_id = ExperimentInstanceId(
                    exp_inst_name, exp_name, exp_cat_name)

                # CoordAddress
                try:
                    coord_address = CoordAddress.CoordAddress.translate_address(
                        data['coord_address'])
                except GeneratorErrors.GeneratorError:
                    raise LaboratoryErrors.InvalidLaboratoryConfigurationError(
                        "Invalid coordination address: %s" %
                        data['coord_address'])

                # CheckingHandlers
                checkers = data.get('checkers', ())
                checking_handlers = []
                for checker in checkers:
                    klazz = checker[0]
                    if klazz in IsUpAndRunningHandler.HANDLERS:
                        argss, kargss = (), {}
                        if len(checker) >= 3:
                            kargss = checker[2]
                        if len(checker) >= 2:
                            argss = checker[1]
                        checking_handlers.append(
                            eval('IsUpAndRunningHandler.' + klazz)(*argss,
                                                                   **kargss))
                    else:
                        raise LaboratoryErrors.InvalidLaboratoryConfigurationError(
                            "Invalid IsUpAndRunningHandler: %s" % klazz)
                parsed_experiments.append(
                    (experiment_instance_id, coord_address, checking_handlers))
        return parsed_experiments
Beispiel #6
0
    def test_get_resource_instance_by_experiment_instance_id_failing(self):
        session = self.session_maker()
        try:
            exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
            self.resources_manager.add_experiment_instance_id(
                "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
                Resource("type", "instance"))
            session.commit()
        finally:
            session.close()

        exp_invalid_type = ExperimentInstanceId("exp1", "ud-pld.invalid",
                                                "PLD Experiments")

        self.assertRaises(
            CoordExc.ExperimentNotFoundError, self.resources_manager.
            get_resource_instance_by_experiment_instance_id, exp_invalid_type)

        exp_invalid_inst = ExperimentInstanceId("exp.invalid", "ud-pld",
                                                "PLD Experiments")
        self.assertRaises(
            CoordExc.ExperimentNotFoundError, self.resources_manager.
            get_resource_instance_by_experiment_instance_id, exp_invalid_inst)
    def setUp(self):
        self.cfg_manager = ConfigurationManager.ConfigurationManager()
        self.cfg_manager.append_module(configuration_module)

        self.fake_client = FakeClient()
        self.fake_locator = FakeLocator((self.fake_client, ))
        self.locator = EasyLocator.EasyLocator(
            CoordAddress.CoordAddress('mach', 'inst', 'serv'),
            self.fake_locator)

        self.experiment_instance_id = ExperimentInstanceId(
            "exp_inst", "exp_name", "exp_cat")
        self.experiment_instance_id_old = ExperimentInstanceId(
            "exp_inst", "exp_name", "exp_cat2")
        self.experiment_coord_address = CoordAddress.CoordAddress.translate_address(
            'myserver:myinstance@mymachine')

        self.cfg_manager._set_value(
            'laboratory_assigned_experiments', {
                'exp_inst:exp_name@exp_cat': {
                    'coord_address':
                    'myserver:myinstance@mymachine',
                    'checkers': (
                        ('WebcamIsUpAndRunningHandler', ("https://...", )),
                        ('HostIsUpAndRunningHandler', ("hostname", 80), {}),
                    )
                },
                'exp_inst:exp_name@exp_cat2': {
                    'coord_address':
                    'myserver:myinstance@mymachine',
                    'checkers': (
                        ('WebcamIsUpAndRunningHandler', ("https://...", )),
                        ('HostIsUpAndRunningHandler', ("hostname", 80), {}),
                    ),
                },
            })
        self._create_lab()
Beispiel #8
0
    def test_get_resource_instance_by_experiment_instance_id(self):
        session = self.session_maker()
        try:
            exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
            self.resources_manager.add_experiment_instance_id(
                "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
                Resource("type", "instance"))
            session.commit()
        finally:
            session.close()

        resource = self.resources_manager.get_resource_instance_by_experiment_instance_id(
            exp_id)
        expected_resource = Resource("type", "instance")
        self.assertEquals(expected_resource, resource)
Beispiel #9
0
    def test_remove_resource_instance_id(self):
        exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
            Resource("type", "instance"))

        experiment_instances = self.resources_manager.list_experiment_instances_by_type(
            exp_id.to_experiment_id())
        self.assertEquals(1, len(experiment_instances))

        self.resources_manager.remove_resource_instance_id(exp_id)

        experiment_instances = self.resources_manager.list_experiment_instances_by_type(
            exp_id.to_experiment_id())
        self.assertEquals(0, len(experiment_instances))
Beispiel #10
0
    def test_confirm_experiment(self):
        lab_session_id = SessionId.SessionId("samplesession_id")

        mock_laboratory = self.mocker.mock()
        mock_laboratory.reserve_experiment(
            ExperimentInstanceId('inst1', 'exp1', 'cat1'),
            '"sample initial data"', mocker.ANY)
        self.mocker.result((lab_session_id, None, {
            'address': 'server:inst@mach'
        }))

        self.mock_locator[coord_addr(self.lab_address)]
        self.mocker.result(mock_laboratory)
        self.mocker.count(min=1, max=None)

        self.mocker.replay()
        status, reservation1_id = self.coordinator.reserve_experiment(
            ExperimentId('exp1', 'cat1'), 30, 5, True, 'sample initial data',
            DEFAULT_REQUEST_INFO, {})
        now = datetime.datetime.fromtimestamp(int(
            time.time()))  # Remove milliseconds as MySQL do
        self.coordinator.confirmer._confirm_handler.join()
        self.assertEquals(None, self.confirmer._confirm_handler.raised_exc)

        status = self.coordinator.get_reservation_status(reservation1_id)
        expected_status = WSS.LocalReservedStatus(
            reservation1_id, CoordAddress.translate(self.lab_address),
            lab_session_id, {'address': 'server:inst@mach'}, 30, '{}', now,
            now, True, 30, 'http://www.weblab.deusto.es/weblab/client/adfas')

        self.assertTrue(
            hasattr(status, 'timestamp_before'),
            "Unexpected status. Expected\n %s\n, but the obtained does not have timestamp_before:\n %s\n"
            % (expected_status, status))
        self.assertTrue(
            status.timestamp_before >= now and
            status.timestamp_before <= now + datetime.timedelta(seconds=10),
            "Unexpected status due to timestamp_before: %s; expected something like %s"
            % (status, expected_status))
        self.assertTrue(
            status.timestamp_after >= now
            and status.timestamp_after <= now + datetime.timedelta(seconds=10),
            "Unexpected status due to timestamp_after: %s; expected something like %s"
            % (status, expected_status))

        status.timestamp_before = now
        status.timestamp_after = now
        self.assertEquals(expected_status, status)
Beispiel #11
0
    def test_add_experiment_instance_id_redundant(self):
        session = self.session_maker()
        try:
            resource_types = session.query(CoordinatorModel.ResourceType).all()
            self.assertEquals(
                0, len(resource_types),
                "No resource expected in the beginning of the test")
        finally:
            session.close()

        exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
            Resource("type", "instance"))

        # No problem in adding twice the same
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
            Resource("type", "instance"))

        session = self.session_maker()
        try:
            # Everything is all right
            self._check_resource_added(session)
            self._check_experiment_instance_id_added(session)

            # However, we can't add another time the same experiment instance with a different laboratory id:
            self.assertRaises(
                CoordExc.InvalidExperimentConfigError,
                self.resources_manager.add_experiment_instance_id,
                "laboratory2:WL_SERVER1@WL_MACHINE1", exp_id,
                Resource("type", "instance"))

            # Or the same experiment instance with a different resource instance:
            self.assertRaises(
                CoordExc.InvalidExperimentConfigError,
                self.resources_manager.add_experiment_instance_id,
                "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
                Resource("type", "instance2"))

            session.commit()
        finally:
            session.close()
Beispiel #12
0
    def test_reject_experiment_laboratory_raises_exception(self):
        mock_laboratory = self.mocker.mock()
        mock_laboratory.reserve_experiment(
            ExperimentInstanceId('inst1', 'exp1', 'cat1'),
            '"sample initial data"', mocker.ANY)
        self.mocker.throw(Exception("Any unhandled exception"))

        self.mock_locator[coord_addr(self.lab_address)]
        self.mocker.result(mock_laboratory)

        self.mocker.replay()
        status, reservation1_id = self.coordinator.reserve_experiment(
            ExperimentId('exp1', 'cat1'), 30, 5, True, 'sample initial data',
            DEFAULT_REQUEST_INFO, {})
        self.coordinator.confirmer._confirm_handler.join()
        self.assertEquals(None, self.confirmer._confirm_handler.raised_exc)

        status = self.coordinator.get_reservation_status(reservation1_id)
        expected_status = WSS.WaitingInstancesQueueStatus(reservation1_id, 0)
        self.assertEquals(expected_status, status)
Beispiel #13
0
    def setUp(self):

        self.coord_address = CoordAddress.CoordAddress.translate_address( "server0:instance0@machine0")

        self.mock_locator  = MockLocator()
        self.locator       = EasyLocator.EasyLocator( self.coord_address, self.mock_locator )

        self.cfg_manager = ConfigurationManager.ConfigurationManager()
        self.cfg_manager.append_module(configuration_module)
        self.cfg_manager._set_value(COORDINATOR_LABORATORY_SERVERS, {
            u'lab1:inst@machine' : {
                'inst1|exp1|cat1' : 'res_inst@res_type'
            },
        })

        self.coordinator = coordinator_create(SQLALCHEMY, self.locator, self.cfg_manager)
        self.coordinator._clean()
        self.confirmer   = self.coordinator.confirmer

        self.lab_address = u"lab1:inst@machine"
        self.coordinator.add_experiment_instance_id(self.lab_address, ExperimentInstanceId('inst1', 'exp1','cat1'), Resource("res_type", "res_inst"))
Beispiel #14
0
    def test_remove_resource_instance_id(self):
        session = self.session_maker()
        try:
            exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
            self.resources_manager.add_experiment_instance_id(
                "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
                Resource("type", "instance"))

            experiment_instances = session.query(
                CoordinatorModel.ExperimentInstance).all()
            self.assertEquals(1, len(experiment_instances))

            self.resources_manager.remove_resource_instance_id(session, exp_id)

            experiment_instances = session.query(
                CoordinatorModel.ExperimentInstance).all()
            self.assertEquals(0, len(experiment_instances))

            session.commit()
        finally:
            session.close()
Beispiel #15
0
    def test_remove_resource_instance(self):
        exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
        resource_instance = Resource("type", "instance")
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id, resource_instance)

        # Checking that the resources are there
        experiment_instances = self.resources_manager.list_experiment_instances_by_type(
            exp_id.to_experiment_id())
        self.assertEquals(1, len(experiment_instances))
        resource_instances = self.resources_manager.list_resource_instances()
        self.assertEquals(1, len(resource_instances))

        # Removing resource instance
        self.resources_manager.remove_resource_instance(resource_instance)

        # Checking that the resources are not there, neither the experiment instances
        resource_instances = self.resources_manager.list_resource_instances()
        self.assertEquals(0, len(resource_instances))
        experiment_instances = self.resources_manager.list_experiment_instances_by_type(
            exp_id.to_experiment_id())
        self.assertEquals(0, len(experiment_instances))
Beispiel #16
0
    def test_add_experiment_instance_id(self):
        session = self.session_maker()
        try:
            resource_types = session.query(CoordinatorModel.ResourceType).all()
            self.assertEquals(
                0, len(resource_types),
                "No resource expected in the beginning of the test")

            exp_id = ExperimentInstanceId("exp1", "ud-pld", "PLD Experiments")
            session.commit()
        finally:
            session.close()
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_id,
            Resource("type", "instance"))

        session = self.session_maker()
        try:
            self._check_resource_added(session)
            self._check_experiment_instance_id_added(session)
            session.commit()
        finally:
            session.close()
    def list_laboratories_addresses(self):
        client = self._redis_maker()

        laboratory_addresses = {
            # laboratory_coord_address : {
            #         experiment_instance_id : resource_instance
            # }
        }

        for experiment_type in client.smembers(WEBLAB_EXPERIMENT_TYPES):
            experiment_id = ExperimentId.parse(experiment_type)
            experiment_instance_names = client.smembers(WEBLAB_EXPERIMENT_INSTANCES % experiment_type)
            for experiment_instance_name in experiment_instance_names:
                experiment_instance_id = ExperimentInstanceId(experiment_instance_name, experiment_id.exp_name, experiment_id.cat_name)
                weblab_experiment_instance = WEBLAB_EXPERIMENT_INSTANCE % (experiment_type, experiment_instance_name)
                laboratory_address = client.hget(weblab_experiment_instance, LAB_COORD)
                resource_str       = client.hget(weblab_experiment_instance, RESOURCE_INST)
                resource           = Resource.parse(resource_str)
                current            = laboratory_addresses.get(laboratory_address, {})
                current[experiment_instance_id] = resource
                laboratory_addresses[laboratory_address] = current

        return laboratory_addresses
Beispiel #18
0
 def to_experiment_instance_id(self):
     exp_id = self.experiment_type.to_experiment_id()
     return ExperimentInstanceId(self.experiment_instance_id,
                                 exp_id.exp_name, exp_id.cat_name)
Beispiel #19
0
    def test_free_experiment_raises_exception(self):
        self.mock_locator.real_mock = self.mocker.mock()
        self.mock_locator.real_mock.get_server_from_coordaddress(
                self.coord_address,
                coord_addr(self.lab_address),
                ServerType.Laboratory,
                'all'
        )
        self.mocker.throw( Exception('foo') )

        self.mocker.replay()
        self.confirmer.enqueue_free_experiment(self.lab_address, '5', 'lab_session_id', ExperimentInstanceId('inst1','exp1','cat1'))
        self.confirmer._free_handler.join()

        self.assertEquals( None, self.confirmer._free_handler.raised_exc )
Beispiel #20
0
 def setUp(self):
     self.experiment_id = ExperimentId('exp', 'cat')
     self.experiment_instance_id = ExperimentInstanceId(
         'inst', 'exp', 'cat')
Beispiel #21
0
    def test_scheduler_reservation_associations(self):
        exp_inst_id1 = ExperimentInstanceId("exp1", "ud-pld",
                                            "PLD experiments")
        exp_inst_id1b = ExperimentInstanceId("exp2", "ud-pld",
                                             "PLD experiments")
        exp_inst_id2 = ExperimentInstanceId("exp1", "ud-fpga",
                                            "FPGA experiments")

        exp_id1 = exp_inst_id1.to_experiment_id()
        exp_id2 = exp_inst_id2.to_experiment_id()

        session = self.session_maker()
        try:
            self.resources_manager.add_resource(
                session, Resource("pld_local", "instance"))
            self.resources_manager.add_resource(
                session, Resource("pld_remote", "instance"))
            self.resources_manager.add_resource(
                session, Resource("fpga_remote", "instance"))
            session.commit()
        finally:
            session.close()

        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_inst_id1,
            Resource("pld_local", "instance"))
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_inst_id1b,
            Resource("pld_remote", "instance"))
        self.resources_manager.add_experiment_instance_id(
            "laboratory1:WL_SERVER1@WL_MACHINE1", exp_inst_id2,
            Resource("fpga_remote", "instance"))

        reservation1 = 'reservation1'
        reservation2 = 'reservation2'

        self.resources_manager.associate_scheduler_to_reservation(
            reservation1, exp_id1, 'pld_local')
        self.resources_manager.associate_scheduler_to_reservation(
            reservation1, exp_id1, 'pld_remote')
        self.resources_manager.associate_scheduler_to_reservation(
            reservation2, exp_id2, 'fpga_remote')

        resource_type_names = self.resources_manager.retrieve_schedulers_per_reservation(
            reservation1, exp_id1)
        self.assertEquals(set(('pld_local', 'pld_remote')),
                          set(resource_type_names))
        resource_type_names = self.resources_manager.retrieve_schedulers_per_reservation(
            reservation2, exp_id2)
        self.assertEquals(['fpga_remote'], list(resource_type_names))

        self.resources_manager.dissociate_scheduler_from_reservation(
            reservation1, exp_id1, 'pld_remote')
        resource_type_names = self.resources_manager.retrieve_schedulers_per_reservation(
            reservation1, exp_id1)
        self.assertEquals(['pld_local'], list(resource_type_names))

        self.resources_manager.clean_associations_for_reservation(
            reservation1, exp_id1)

        resource_type_names = self.resources_manager.retrieve_schedulers_per_reservation(
            reservation1, exp_id1)
        self.assertEquals(0, len(resource_type_names))
Beispiel #22
0
 def setUp(self):
     self._assigned_micro_servers = AssignedExperiments.AssignedExperiments(
     )
     self.exp_inst_id = ExperimentInstanceId("exp_inst", "exp_name",
                                             "exp_cat")
 def list_experiment_instances_by_type(self, experiment_id):
     client = self._redis_maker()
     weblab_experiment_instances = WEBLAB_EXPERIMENT_INSTANCES % experiment_id.to_weblab_str()
     return [ 
         ExperimentInstanceId(inst, experiment_id.exp_name, experiment_id.cat_name)
         for inst in client.smembers(weblab_experiment_instances) ]
Beispiel #24
0
    def test_list_experiments(self):
        self.coordinator.add_experiment_instance_id("server:laboratoryserver@labmachine", ExperimentInstanceId('inst','ud-dummy2','Dummy experiments'), Resource("res_type", "res_inst"))

        expected = "ud-dummy@Dummy experiments\n"
        expected +=  "ud-dummy2@Dummy experiments\n"

        result   = methods.list_experiments.call()
        self.assertEquals(expected, result)
Beispiel #25
0
    def setUp(self):

        self.maxDiff = 2000

        def _find_server(server_type, name):
            return self.ups

        self._find_server_backup = methods._find_server
        methods._find_server     = _find_server

        self.locator = FakeLocator()
        self.cfg_manager = ConfigurationManager.ConfigurationManager()
        self.cfg_manager.append_module(configuration_module)
        self.cfg_manager._set_value(COORDINATOR_LABORATORY_SERVERS, {
            'server:laboratoryserver@labmachine' : {
                'inst|ud-dummy|Dummy experiments' : 'res_inst@res_type'
            }
        })

        # With this one we clean everything before creating the UPS
        self.coordinator = coordinator_create(SQLALCHEMY, self.locator, self.cfg_manager, ConfirmerClass = ConfirmerMock)
        self.coordinator._clean()

        self.coord_address = CoordAddress.CoordAddress.translate_address( "server0:instance0@machine0" )

        self.ups = UserProcessingServer.UserProcessingServer(
                self.coord_address,
                self.locator,
                self.cfg_manager
            )

        self.ups._coordinator.stop()
        self.ups._coordinator = self.coordinator
        self.coordinator.add_experiment_instance_id("server:laboratoryserver@labmachine", ExperimentInstanceId('inst','ud-dummy','Dummy experiments'), Resource("res_type", "res_inst"))
Beispiel #26
0
    def _parse_assigned_experiments(self):
        """
        Parses the configuration that was provided to the server and loads every Experiment
        that is declared in it. This task is executed at the beginning.
        :return: List of tuples, each tuple containing information for an Experiment
        """

        assigned_experiments = self._cfg_manager.get_value(
            WEBLAB_LABORATORY_SERVER_ASSIGNED_EXPERIMENTS)

        parsed_experiments = []

        for experiment_instance_id, data in assigned_experiments.items():
            mo = re.match(self.EXPERIMENT_INSTANCE_ID_REGEX,
                          experiment_instance_id)
            if mo == None:
                raise LaboratoryErrors.InvalidLaboratoryConfigurationError(
                    "Invalid configuration entry. Expected format: %s; found: %s"
                    % (LaboratoryServer.EXPERIMENT_INSTANCE_ID_REGEX,
                       experiment_instance_id))
            else:
                number = data.get('number', 1)

                for n in range(1, number + 1):
                    # ExperimentInstanceId
                    groups = mo.groups()
                    (exp_inst_name, exp_name, exp_cat_name) = groups

                    if number > 1:
                        exp_inst_name += '__%s' % n

                    experiment_instance_id = ExperimentInstanceId(
                        exp_inst_name, exp_name, exp_cat_name)

                    # CoordAddress
                    try:
                        coord_address = CoordAddress.translate(
                            data['coord_address'])
                    except GeneratorError:
                        raise LaboratoryErrors.InvalidLaboratoryConfigurationError(
                            "Invalid coordination address: %s" %
                            data['coord_address'])

                    # CheckingHandlers
                    checkers = data.get('checkers', ())
                    checking_handlers = {}
                    for checker in checkers:
                        klazz = checker[0]
                        if klazz in IsUpAndRunningHandler.HANDLERS:
                            argss, kargss = (), {}
                            if len(checker) >= 3:
                                kargss = checker[2]
                            if len(checker) >= 2:
                                argss = checker[1]
                            checking_handlers[repr(checker)] = eval(
                                'IsUpAndRunningHandler.' + klazz)(*argss,
                                                                  **kargss)
                        else:
                            raise LaboratoryErrors.InvalidLaboratoryConfigurationError(
                                "Invalid IsUpAndRunningHandler: %s" % klazz)

                    # API
                    api = data.get('api', None)

                    # Polling: if it manages its own polling, the client does not need to manage it
                    manages_polling = data.get('manages_polling', False)

                    parsed_experiments.append(
                        (experiment_instance_id, coord_address, {
                            'checkers': checking_handlers,
                            'api': api,
                            'manages_polling': manages_polling,
                            'number': number
                        }))
        return parsed_experiments
Beispiel #27
0
    def test_free_experiment_success(self):
        mock_laboratory = self.mocker.mock()
        mock_laboratory.free_experiment('lab_session_id')

        self.mock_locator.real_mock = self.mocker.mock()
        self.mock_locator.real_mock.get_server_from_coordaddress(
                self.coord_address,
                coord_addr(self.lab_address),
                ServerType.Laboratory,
                'all'
        )
        self.mocker.result((mock_laboratory,))

        self.mocker.replay()
        self.confirmer.enqueue_free_experiment(self.lab_address, '5', 'lab_session_id', ExperimentInstanceId('inst1','exp1','cat1'))
        self.confirmer._free_handler.join()
Beispiel #28
0
    def _update_queues(self):
        ###########################################################
        # There are reasons why a waiting reservation may not be
        # able to be promoted while the next one is. For instance,
        # if a user is waiting for "pld boards", but only for
        # instances of "pld boards" which have a "ud-binary@Binary
        # experiments" server running. If only a "ud-pld@PLD
        # Experiments" is available, then this user will not be
        # promoted and the another user which is waiting for a
        # "ud-pld@PLD Experiments" can be promoted.
        #
        # Therefore, we have a list of the IDs of the waiting
        # reservations we previously thought that they couldn't be
        # promoted in this iteration. They will have another
        # chance in the next run of _update_queues.
        #
        previously_waiting_reservation_ids = []

        ###########################################################
        # While there are free instances and waiting reservations,
        # take the first waiting reservation and set it to current
        # reservation. Make this repeatedly because we want to
        # commit each change
        #
        while True:
            session = self.session_maker()
            try:
                resource_type = session.query(ResourceType).filter(ResourceType.name == self.resource_type_name).first()

                #
                # Retrieve the first waiting reservation. If there is no one that
                # we haven't tried already, return
                #
                first_waiting_reservations = session.query(WaitingReservation).filter(WaitingReservation.resource_type == resource_type).order_by(WaitingReservation.priority, WaitingReservation.id)[:len(previously_waiting_reservation_ids) + 1]
                first_waiting_reservation = None
                for waiting_reservation in first_waiting_reservations:
                    if waiting_reservation.id not in previously_waiting_reservation_ids:
                        first_waiting_reservation = waiting_reservation
                        break

                if first_waiting_reservation is None:
                    return # There is no waiting reservation for this resource that we haven't already tried

                previously_waiting_reservation_ids.append(first_waiting_reservation.id)

                #
                # For the current resource_type, let's ask for
                # all the resource instances available (i.e. those
                # who have no SchedulingSchemaIndependentSlotReservation
                # associated)
                #
                free_instances = session.query(CurrentResourceSlot)\
                        .select_from(join(CurrentResourceSlot, ResourceInstance))\
                        .filter(not_(CurrentResourceSlot.slot_reservations.any()))\
                        .filter(ResourceInstance.resource_type == resource_type)\
                        .order_by(CurrentResourceSlot.id).all()

                if len(free_instances) == 0:
                    # If there is no free instance, just return
                    return

                #
                # Select the correct free_instance for the current student among
                # all the free_instances
                #
                if self.randomize_instances:
                    randomized_free_instances = [ free_instance for free_instance in free_instances ]
                    random.shuffle(randomized_free_instances)
                else:
                    randomized_free_instances = free_instances

                for free_instance in randomized_free_instances:

                    resource_type = free_instance.resource_instance.resource_type
                    if resource_type is None:
                        continue # If suddenly the free_instance is not a free_instance anymore, try with other free_instance

                    #
                    # IMPORTANT: from here on every "continue" should first revoke the
                    # reservations_manager and resources_manager confirmations
                    #

                    self.reservations_manager.confirm(session, first_waiting_reservation.reservation_id)
                    slot_reservation = self.resources_manager.acquire_resource(session, free_instance)
                    total_time = first_waiting_reservation.time
                    initialization_in_accounting = first_waiting_reservation.initialization_in_accounting
                    start_time = self.time_provider.get_time()
                    concrete_current_reservation = ConcreteCurrentReservation(slot_reservation, first_waiting_reservation.reservation_id,
                                                        total_time, start_time, first_waiting_reservation.priority, first_waiting_reservation.initialization_in_accounting)
                    concrete_current_reservation.set_timestamp_before(self.time_provider.get_time())

                    client_initial_data = first_waiting_reservation.reservation.client_initial_data
                    request_info = json.loads(first_waiting_reservation.reservation.request_info)
                    username     = request_info.get('username')
                    username_unique = request_info.get('username_unique')
                    locale       = request_info.get('locale')

                    reservation_id = first_waiting_reservation.reservation_id
                    if reservation_id is None:
                        break # If suddenly the waiting_reservation is not a waiting_reservation anymore, so reservation is None, go again to the while True.

                    requested_experiment_type = first_waiting_reservation.reservation.experiment_type
                    selected_experiment_instance = None
                    for experiment_instance in free_instance.resource_instance.experiment_instances:
                        if experiment_instance.experiment_type == requested_experiment_type:
                            selected_experiment_instance = experiment_instance

                    if selected_experiment_instance is None:
                        # This resource is not valid for this user, other free_instance should be
                        # selected. Try with other, but first clean the acquired resources
                        self.reservations_manager.downgrade_confirmation(session, first_waiting_reservation.reservation_id)
                        self.resources_manager.release_resource(session, slot_reservation)
                        continue

                    experiment_instance_id = ExperimentInstanceId(selected_experiment_instance.experiment_instance_id, requested_experiment_type.exp_name, requested_experiment_type.cat_name)

                    laboratory_coord_address = selected_experiment_instance.laboratory_coord_address
                    try:
                        session.delete(first_waiting_reservation)
                        session.add(concrete_current_reservation)
                        session.commit()
                    except IntegrityError as ie:
                        if DEBUG:
                            print("IntegrityError when adding concrete_current_reservation: ", sys.exc_info())
                        # Other scheduler confirmed the user or booked the reservation, rollback and try again
                        # But log just in case
                        log.log(
                            PriorityQueueScheduler, log.level.Warning,
                            "IntegrityError looping on update_queues: %s" % ie )
                        log.log_exc(PriorityQueueScheduler, log.level.Info)
                        session.rollback()
                        break
                    except Exception as e:
                        if DEBUG:
                            print("Other error when adding concrete_current_reservation: ", sys.exc_info())

                        log.log(
                            PriorityQueueScheduler, log.level.Warning,
                            "Exception looping on update_queues: %s" % e )
                        log.log_exc(PriorityQueueScheduler, log.level.Info)
                        session.rollback()
                        break
                    else:
                        #
                        # Enqueue the confirmation, since it might take a long time
                        # (for instance, if the laboratory server does not reply because
                        # of any network problem, or it just takes too much in replying),
                        # so this method might take too long. That's why we enqueue these
                        # petitions and run them in other threads.
                        #
                        timezone = time.timezone if (time.localtime().tm_isdst == 0) else time.altzone
                        deserialized_server_initial_data = {
                                'priority.queue.slot.length'                       : '%s' % total_time,
                                'priority.queue.slot.start'                        : '%s' % datetime.datetime.fromtimestamp(start_time),
                                'priority.queue.slot.start.utc'                    : '%s' % datetime.datetime.utcfromtimestamp(start_time),
                                'priority.queue.slot.start.timestamp'              : '%s' % start_time,
                                'priority.queue.slot.start.timezone'               : '%s' % timezone,
                                'priority.queue.slot.initialization_in_accounting' : initialization_in_accounting,
                                'request.experiment_id.experiment_name'            : experiment_instance_id.exp_name,
                                'request.experiment_id.category_name'              : experiment_instance_id.cat_name,
                                'request.username'                                 : username,
                                'request.username.unique'                          : username_unique,
                                'request.full_name'                                : username,
                                'request.locale'                                   : locale,
                                'weblab_reservation_id'                            : first_waiting_reservation.reservation_id,
                            }
                        server_initial_data = json.dumps(deserialized_server_initial_data)
                        # server_initial_data will contain information such as "what was the last experiment used?".
                        # If a single resource was used by a binary experiment, then the next time may not require reprogramming the device
                        self.confirmer.enqueue_confirmation(laboratory_coord_address, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, self.resource_type_name)
                        #
                        # After it, keep in the while True in order to add the next
                        # reservation
                        #
                        break
            except (ConcurrentModificationError, IntegrityError) as ie:
                # Something happened somewhere else, such as the user being confirmed twice, the experiment being reserved twice or so on.
                # Rollback and start again
                if DEBUG:
                    print("Other ConcurrentModificationError or IntegrityError in update_queues: ", sys.exc_info())

                log.log(
                    PriorityQueueScheduler, log.level.Warning,
                    "Exception while updating queues, reverting and trying again: %s" % ie )
                log.log_exc(PriorityQueueScheduler, log.level.Info)
                session.rollback()
            finally:
                session.close()
Beispiel #29
0
 def get_experiment_instance_id(self):
     return ExperimentInstanceId(None, self.name, self.category.name)