def test_checking_not_failing(self):
     OriginalChecker = RCT.ResourcesCheckerThread.Checker
     RCT.ResourcesCheckerThread.Checker = FakeChecker
     original_sleep = RCT.sleep
     RCT.sleep = lambda *args : None
     try:
         RCT.reset()
         try:
             RCT.set_coordinator(original_coordinator, 10)
             time.sleep(0.01)
             self.assertTrue(counter > 2)
             self.assertTrue(right_coordinator)
             self.assertTrue(checked)
         finally:
             RCT.clean()
     finally:
         RCT.ResourcesCheckerThread.Checker = OriginalChecker
         RCT.sleep = original_sleep
 def test_checking_failing(self):
     OriginalChecker = RCT.ResourcesCheckerThread.Checker
     RCT.ResourcesCheckerThread.Checker = FakeFailingChecker
     original_sleep = RCT.sleep
     RCT.sleep = lambda *args : None
     try:
         RCT.reset()
         try:
             RCT.set_coordinator(original_coordinator, 10)
             initial_time = time.time()
             while not RCT.checker_thread.isAlive() and time.time() - initial_time <= 1:
                 time.sleep(0.02)
             # Now it's alive or more than 1 seconds have passed
             time.sleep(0.2)
             self.assertTrue(counter > 2) # It's still running
             self.assertTrue(right_coordinator)
             self.assertTrue(checked)
         finally:
             RCT.clean()
     finally:
         RCT.ResourcesCheckerThread.Checker = OriginalChecker
         RCT.sleep = original_sleep
예제 #3
0
class AbstractCoordinator(object):
    CoordinatorTimeProvider = TimeProvider

    def __init__(self, data_manager, locator, cfg_manager, ConfirmerClass):
        if ConfirmerClass is None:
            ConfirmerClass = Confirmer.ReservationConfirmer

        self.cfg_manager = cfg_manager
        self._data_manager = data_manager

        self.core_server_url = self.cfg_manager.get_value(CORE_SERVER_URL)

        self.notifier = AdminNotifier.AdminNotifier(self.cfg_manager)
        self.notifications_enabled = self.cfg_manager.get_value(
            RESOURCES_CHECKER_NOTIFICATIONS_ENABLED,
            DEFAULT_RESOURCES_CHECKER_NOTIFICATIONS_ENABLED)

        self.locator = locator  # Used by ResourcesChecker
        self.confirmer = ConfirmerClass(self, locator)

        self.time_provider = self.CoordinatorTimeProvider()

        self.initial_store = TemporalInformationStore.InitialTemporalInformationStore(
        )
        self.finished_store = TemporalInformationStore.FinishTemporalInformationStore(
        )
        self.completed_store = TemporalInformationStore.CompletedInformationStore(
        )
        self.finished_reservations_store = Queue.Queue()

        self._initialize_managers()

        #
        # The system administrator must define what scheduling system is used by each resource type
        # For instance:
        #
        # scheduling_systems = {
        #                  "pld boards"     : ("PRIORITY_QUEUE", {}),
        #                  "fpga boards"    : ("PRIORITY_QUEUE", {}),
        #                  "vm experiments" : ("BOOKING", { 'slots' : 30 * 1000 }), # Slots of 30 minutes
        #                  "something else" : ("EXTERNAL", { 'address' : 'http://192.168.1.50:8080/SchedulingServer', 'protocol' : 'SOAP' }) # If somebody else has implemented the scheduling schema in other language
        #            }
        #
        self.schedulers = {}
        scheduling_systems = cfg_manager.get_value(CORE_SCHEDULING_SYSTEMS)
        for resource_type_name in scheduling_systems:
            scheduling_system, arguments = scheduling_systems[
                resource_type_name]
            if not scheduling_system in self.SCHEDULING_SYSTEMS:
                raise CoordExc.UnregisteredSchedulingSystemError(
                    "Unregistered scheduling system: %r" % scheduling_system)
            SchedulingSystemClass = self.SCHEDULING_SYSTEMS[scheduling_system]

            data_manager = self._data_manager

            generic_scheduler_arguments = Scheduler.GenericSchedulerArguments(
                cfg_manager=self.cfg_manager,
                resource_type_name=resource_type_name,
                reservations_manager=self.reservations_manager,
                resources_manager=self.resources_manager,
                confirmer=self.confirmer,
                data_manager=data_manager,
                time_provider=self.time_provider,
                core_server_url=self.core_server_url,
                initial_store=self.initial_store,
                finished_store=self.finished_store,
                completed_store=self.completed_store,
                post_reservation_data_manager=self.
                post_reservation_data_manager)

            self.schedulers[resource_type_name] = SchedulingSystemClass(
                generic_scheduler_arguments, **arguments)

        self.aggregators = {
            # experiment_id_str : AGGREGATOR( schedulers )
        }

        coordination_configuration_parser = CoordinationConfigurationParser.CoordinationConfigurationParser(
            cfg_manager)
        resource_types_per_experiment_id = coordination_configuration_parser.parse_resources_for_experiment_ids(
        )

        #
        # This configuration argument has a dictionary such as:
        # {
        #     'experiment_id_str' : {'foo' : 'bar'}
        # }
        #
        # The argument itself is not mandatory.
        #
        aggregators_configuration = self.cfg_manager.get_value(
            CORE_SCHEDULER_AGGREGATORS, {})

        for experiment_id_str in resource_types_per_experiment_id:
            generic_scheduler_arguments = Scheduler.GenericSchedulerArguments(
                cfg_manager=self.cfg_manager,
                resource_type_name=None,
                reservations_manager=self.reservations_manager,
                resources_manager=self.resources_manager,
                confirmer=self.confirmer,
                data_manager=self._data_manager,
                time_provider=self.time_provider,
                core_server_url=self.core_server_url,
                initial_store=self.initial_store,
                finished_store=self.finished_store,
                completed_store=self.completed_store,
                post_reservation_data_manager=self.
                post_reservation_data_manager)

            resource_type_names = resource_types_per_experiment_id[
                experiment_id_str]
            try:
                aggregated_schedulers = OrderedDict()
                for resource_type_name in resource_type_names:
                    aggregated_schedulers[
                        resource_type_name] = self.schedulers[
                            resource_type_name]

            except KeyError, ke:
                raise Exception(
                    "Scheduler not found with resource type name %s. Check %s config property."
                    % (ke, CORE_SCHEDULING_SYSTEMS))

            particular_configuration = aggregators_configuration.get(
                experiment_id_str)

            aggregator = self.AGGREGATOR(generic_scheduler_arguments,
                                         ExperimentId.parse(experiment_id_str),
                                         aggregated_schedulers,
                                         particular_configuration)

            self.aggregators[experiment_id_str] = aggregator

        clean = cfg_manager.get('core_number') == 0
        post_reservation_expiration_time = cfg_manager.get_value(
            POST_RESERVATION_EXPIRATION_TIME,
            DEFAULT_POST_RESERVATION_EXPIRATION_TIME)
        self.expiration_delta = datetime.timedelta(
            seconds=post_reservation_expiration_time)

        if clean:
            resources_checker_frequency = cfg_manager.get_value(
                RESOURCES_CHECKER_FREQUENCY,
                DEFAULT_RESOURCES_CHECKER_FREQUENCY)
            ResourcesCheckerThread.set_coordinator(
                self, resources_checker_frequency)

            self._clean()

            coordination_configuration_parser = CoordinationConfigurationParser.CoordinationConfigurationParser(
                self.cfg_manager)

            configuration = coordination_configuration_parser.parse_configuration(
            )
            for laboratory_server_coord_address_str in configuration:
                experiment_instance_config = configuration[
                    laboratory_server_coord_address_str]
                for experiment_instance_id in experiment_instance_config:
                    resource = experiment_instance_config[
                        experiment_instance_id]
                    self.add_experiment_instance_id(
                        laboratory_server_coord_address_str,
                        experiment_instance_id, resource)

            self._initial_clean(coordination_configuration_parser)