def setUp(self): self._cfg_manager = ConfigurationManager.ConfigurationManager() self._cfg_manager.append_module(configuration_module) self.RESERVATION_ID = "my_reservation_id" self.RESERVATION_SESS_ID = SessionId.SessionId(self.RESERVATION_ID) self.LAB_SESS_ID = "my_lab_sess_id" self.ANY_COORD_ADDR = CoordAddress.translate('translator:myprocess@mymachine') self.LAB_COORD_ADDR = CoordAddress.translate('laboratory:myprocess@mymachine')
def setUp(self): self._cfg_manager = ConfigurationManager.ConfigurationManager() self._cfg_manager.append_module(configuration_module) self.RESERVATION_ID = "my_reservation_id" self.RESERVATION_SESS_ID = SessionId.SessionId(self.RESERVATION_ID) self.LAB_SESS_ID = "my_lab_sess_id" self.ANY_COORD_ADDR = CoordAddress.translate( 'translator:myprocess@mymachine') self.LAB_COORD_ADDR = CoordAddress.translate( 'laboratory:myprocess@mymachine')
def setUp(self): self.coord_address = CoordAddress.translate( "server0:instance0@machine0") self.cfg_manager = ConfigurationManager.ConfigurationManager() self.cfg_manager.append_module(configuration_module) self.cfg_manager._set_value( CoordinationConfigurationParser.COORDINATOR_LABORATORY_SERVERS, { 'server:laboratoryserver@labmachine': { 'inst|ud-dummy|Dummy experiments': 'dummy1@dummy boards' } }) self.cfg_manager._set_value("core_number", 0) self.mocker = mocker.Mocker() self.lab_mock = self.mocker.mock() self.locator = FakeLocator(self.lab_mock) # Clean the database coordinator = coordinator_create(SQLALCHEMY, self.locator, self.cfg_manager) coordinator._clean() coordinator.stop() # External server generation self.ups = WrappedUPS(self.coord_address, self.locator, self.cfg_manager) self.ups._db_manager._delete_all_uses()
def enqueue_confirmation(self, lab_coordaddress_str, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, resource_type_name): # We can stablish a politic such as using # thread pools or a queue of threads or something # like that... here lab_coordaddress = CoordAddress.translate(lab_coordaddress_str) self._confirm_handler = self._confirm_experiment(lab_coordaddress, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, resource_type_name) self._confirm_handler.join(self._enqueuing_timeout)
def test_reserve_experiment(self): db_sess_id = ValidDatabaseSessionId('student2', "student") sess_id, _ = self.ups._reserve_session(db_sess_id) exp_id = ExperimentId('this does not experiment', 'this neither') with wlcontext(self.ups, session_id=sess_id): self.assertRaises(coreExc.UnknownExperimentIdError, core_api.reserve_experiment, exp_id, "{}", "{}") exp_id = ExperimentId('ud-dummy', 'Dummy experiments') lab_sess_id = SessionId.SessionId("lab_session_id") self.lab_mock.reserve_experiment(exp_id, "{}") self.mocker.result(lab_sess_id) self.mocker.count(0, 1) self.lab_mock.resolve_experiment_address(lab_sess_id) self.mocker.result(CoordAddress.translate('foo:bar@machine')) self.mocker.count(0, 1) self.mocker.replay() reservation = core_api.reserve_experiment(exp_id, "{}", "{}") self.assertTrue(isinstance(reservation, Reservation.Reservation)) core_api.logout()
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.translate( "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"))
def test_reserve_experiment(self): db_sess_id = ValidDatabaseSessionId('student2', "student") sess_id, _ = self.ups._reserve_session(db_sess_id) exp_id = ExperimentId('this does not experiment','this neither') with wlcontext(self.ups, session_id = sess_id): self.assertRaises( coreExc.UnknownExperimentIdError, core_api.reserve_experiment, exp_id, "{}", "{}" ) exp_id = ExperimentId('ud-dummy','Dummy experiments') lab_sess_id = SessionId.SessionId("lab_session_id") self.lab_mock.reserve_experiment(exp_id, "{}") self.mocker.result(lab_sess_id) self.mocker.count(0, 1) self.lab_mock.resolve_experiment_address(lab_sess_id) self.mocker.result(CoordAddress.translate('foo:bar@machine')) self.mocker.count(0, 1) self.mocker.replay() reservation = core_api.reserve_experiment(exp_id, "{}", "{}") self.assertTrue( isinstance(reservation,Reservation.Reservation)) core_api.logout()
def setUp(self): cfg_manager = ConfigurationManager.ConfigurationManager() cfg_manager.append_module(configuration_module) self.fake_client = FakeClient() self.fake_locator = FakeLocator(self.fake_client) locator = self.fake_locator self.experiment_instance_id = ExperimentInstanceId( "exp_inst", "exp_name", "exp_cat") self.experiment_coord_address = CoordAddress.translate( 'myserver:myinstance@mymachine') cfg_manager._set_value( 'laboratory_assigned_experiments', { 'exp_inst:exp_name@exp_cat': { 'coord_address': 'myserver1:myinstance@mymachine', 'checkers': ( ('WebcamIsUpAndRunningHandler', ("https://...", )), ('HostIsUpAndRunningHandler', ("hostname", 80), {}), ) } }) self.lab = LaboratoryServer.LaboratoryServer(None, locator, cfg_manager)
def setUp(self): self._cfg_manager = ConfigurationManager.ConfigurationManager() self._cfg_manager.append_module(configuration_module) self.ANY_COORD_ADDR = CoordAddress.translate('myserver:myprocess@mymachine') self._clean_up_files_stored_dir()
def setUp(self): self.coord_address = CoordAddress.translate( "server0:instance0@machine0" ) self.cfg_manager = ConfigurationManager.ConfigurationManager() self.cfg_manager.append_module(configuration_module) self.cfg_manager._set_value(CoordinationConfigurationParser.COORDINATOR_LABORATORY_SERVERS, { 'server:laboratoryserver@labmachine' : { 'inst|ud-dummy|Dummy experiments' : 'dummy1@dummy boards' } } ) self.cfg_manager._set_value("core_number", 0) self.mocker = mocker.Mocker() self.lab_mock = self.mocker.mock() self.locator = FakeLocator(self.lab_mock) # Clean the database coordinator = coordinator_create(SQLALCHEMY, self.locator, self.cfg_manager) coordinator._clean() coordinator.stop() # External server generation self.ups = WrappedUPS( self.coord_address, self.locator, self.cfg_manager ) self.ups._db_manager._delete_all_uses()
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 )
def test_list_experiment_instance_ids(self): clients_coord_addresses = CoordAddress.translate("myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler',) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, { 'checkers' : checking_handlers } ) result = self._assigned_micro_servers.list_experiment_instance_ids() self.assertEquals([self.exp_inst_id], result)
def setUp(self): coord_address = CoordAddress.translate( "server0:instance0@machine0") self.cfg_manager = ConfigurationManager.ConfigurationManager() self.cfg_manager.append_module(configuration_module) self.core_server = UserProcessingServer(coord_address, None, self.cfg_manager)
def test_get_is_up_and_running_handlers(self): clients_coord_addresses = CoordAddress.translate("myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler',) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, { 'checkers' : checking_handlers } ) retrieved_is_up_and_running_handlers = self._assigned_micro_servers.get_is_up_and_running_handlers(self.exp_inst_id) self.assertEquals(checking_handlers, retrieved_is_up_and_running_handlers)
def setUp(self): self._cfg_manager = ConfigurationManager.ConfigurationManager() self._cfg_manager.append_module(configuration_module) self.ANY_COORD_ADDR = CoordAddress.translate( 'myserver:myprocess@mymachine') self._clean_up_files_stored_dir()
def test_get_lab_session_id(self): clients_coord_addresses = CoordAddress.translate("myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler',) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, { 'checkers' : checking_handlers } ) self._assigned_micro_servers.reserve_experiment(self.exp_inst_id, "foo") lab_session_id = self._assigned_micro_servers.get_lab_session_id(self.exp_inst_id) self.assertEquals("foo", lab_session_id)
def test_get_coord_address(self): clients_coord_addresses = CoordAddress.translate("myserver:myinstance@mymachine") checking_handlers = ("WebcamIsUpAndRunningHandler",) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, {"checkers": checking_handlers} ) coord_address = self._assigned_micro_servers.get_coord_address(self.exp_inst_id) self.assertEquals(clients_coord_addresses, coord_address)
def enqueue_confirmation(self, lab_coordaddress_str, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, resource_type_name): # We can stablish a politic such as using # thread pools or a queue of threads or something # like that... here lab_coordaddress = CoordAddress.translate(lab_coordaddress_str) self._confirm_handler = self._confirm_experiment( lab_coordaddress, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, resource_type_name) self._confirm_handler.join(self._enqueuing_timeout)
def test_list_experiment_instance_ids(self): clients_coord_addresses = CoordAddress.translate( "myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler', ) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, {'checkers': checking_handlers}) result = self._assigned_micro_servers.list_experiment_instance_ids() self.assertEquals([self.exp_inst_id], result)
def enqueue_free_experiment(self, lab_coordaddress_str, reservation_id, lab_session_id, experiment_instance_id): # We can stablish a policy such as using # thread pools or a queue of threads or something # like that... here if lab_session_id is None: # If the user didn't manage to obtain a session_id, don't call the free_experiment method experiment_response = None initial_time = end_time = datetime.datetime.now() self.coordinator.confirm_resource_disposal(lab_coordaddress_str, reservation_id, lab_session_id, experiment_instance_id, experiment_response, initial_time, end_time) else: # Otherwise... lab_coordaddress = CoordAddress.translate(lab_coordaddress_str) self._free_handler = self._free_experiment(lab_coordaddress, reservation_id, lab_session_id, experiment_instance_id) self._free_handler.join(self._enqueuing_timeout)
def test_get_coord_address(self): clients_coord_addresses = CoordAddress.translate( "myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler', ) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, {'checkers': checking_handlers}) coord_address = self._assigned_micro_servers.get_coord_address( self.exp_inst_id) self.assertEquals(clients_coord_addresses, coord_address)
def test_add_server(self): clients_coord_addresses = CoordAddress.translate( "myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler', ) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, {'checkers': checking_handlers}) self.assertRaises(LaboratoryErrors.ExperimentAlreadyFoundError, self._assigned_micro_servers.add_server, self.exp_inst_id, clients_coord_addresses, {'checkers': checking_handlers})
def test_add_server(self): clients_coord_addresses = CoordAddress.translate("myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler',) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, { 'checkers' : checking_handlers } ) self.assertRaises( LaboratoryErrors.ExperimentAlreadyFoundError, self._assigned_micro_servers.add_server, self.exp_inst_id, clients_coord_addresses, { 'checkers' : checking_handlers } )
def test_get_lab_session_id(self): clients_coord_addresses = CoordAddress.translate( "myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler', ) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, {'checkers': checking_handlers}) self._assigned_micro_servers.reserve_experiment( self.exp_inst_id, "foo") lab_session_id = self._assigned_micro_servers.get_lab_session_id( self.exp_inst_id) self.assertEquals("foo", lab_session_id)
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)
def check_laboratory(self, address_str, experiments): """ Checks in that laboratory address which experiments are broken and which ones are working. :param address_str: laboratory address, e.g. "laboratory:general_laboratory@server1" :param experiments: dictionary of experiments: resources, e.g. { "exp1|ud-fpga|FPGA experiments" : "fpga1@fpga boards"} """ broken_resources = { # resource_id : error_message } try: address = CoordAddress.translate(address_str) server = self.locator.get( address, timeout=1800) # Extended timeout for this method failing_experiments = server.check_experiments_resources() # # failing_experiments is a dictionary such as: # { # experiment_instance_id : error_message # } # for failing_experiment in failing_experiments: if not failing_experiment in experiments: log.log( ResourcesChecker, log.level.Error, "Laboratory server %s reported that experiment %s was failing; however this laboratory does NOT manage this experiment. Attack?" % (address_str, failing_experiment)) continue # # The error for a resource will be concatenated # broken_resource = experiments[failing_experiment] error_message = failing_experiments[failing_experiment] if broken_resource in broken_resources: broken_resources[broken_resource] = broken_resources[ broken_resource] + ';' + error_message else: broken_resources[broken_resource] = error_message except: traceback.print_exc() log.log(ResourcesChecker, log.level.Critical, "Error checking resources of laboratory %s " % address_str) log.log_exc(ResourcesChecker, log.level.Critical) return broken_resources
def _reserve_experiment(self): db_sess_id = ValidDatabaseSessionId('student1', "student") sess_id, _ = self.ups._reserve_session(db_sess_id) with wlcontext(self.ups, session_id = sess_id): exp_id = ExperimentId('ud-dummy','Dummy experiments') lab_sess_id = SessionId.SessionId("lab_session_id") self.lab_mock.reserve_experiment(exp_id, "{}") self.mocker.result(lab_sess_id) self.mocker.count(0, 1) self.lab_mock.resolve_experiment_address(lab_sess_id) self.mocker.result(CoordAddress.translate('foo:bar@machine')) self.mocker.count(0, 1) self.mocker.replay() reservation = core_api.reserve_experiment(exp_id, "{}", "{}") return reservation.reservation_id
def _reserve_experiment(self): db_sess_id = ValidDatabaseSessionId('student1', "student") sess_id, _ = self.ups._reserve_session(db_sess_id) with wlcontext(self.ups, session_id=sess_id): exp_id = ExperimentId('ud-dummy', 'Dummy experiments') lab_sess_id = SessionId.SessionId("lab_session_id") self.lab_mock.reserve_experiment(exp_id, "{}") self.mocker.result(lab_sess_id) self.mocker.count(0, 1) self.lab_mock.resolve_experiment_address(lab_sess_id) self.mocker.result(CoordAddress.translate('foo:bar@machine')) self.mocker.count(0, 1) self.mocker.replay() reservation = core_api.reserve_experiment(exp_id, "{}", "{}") return reservation.reservation_id
def to_business_light(self): usage = ExperimentUsage() usage.experiment_use_id = self.id usage.start_date = _splitted_utc_datetime_to_timestamp(self.start_date, self.start_date_micro) usage.end_date = _splitted_utc_datetime_to_timestamp(self.end_date, self.end_date_micro) usage.from_ip = self.origin usage.reservation_id = self.reservation_id usage.experiment_id = ExperimentId(self.experiment.name, self.experiment.category.name) usage.coord_address = CoordAddress.translate(self.coord_address) request_info = {} for prop in self.properties: name = prop.property_name.name value = prop.value request_info[name] = value usage.request_info = request_info return usage
def test_reserve_experiment(self): clients_coord_addresses = CoordAddress.translate("myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler',) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, { 'checkers' : checking_handlers } ) def check_reserve(): result = self._assigned_micro_servers.reserve_experiment( self.exp_inst_id, "my session id" ) self.assertEquals( clients_coord_addresses, result ) check_reserve() self._assigned_micro_servers.free_experiment(self.exp_inst_id) check_reserve() self._assigned_micro_servers.free_experiment(self.exp_inst_id) self.assertRaises( LaboratoryErrors.AlreadyFreedExperimentError, self._assigned_micro_servers.free_experiment, self.exp_inst_id )
def check_laboratory(self, address_str, experiments): """ Checks in that laboratory address which experiments are broken and which ones are working. :param address_str: laboratory address, e.g. "laboratory:general_laboratory@server1" :param experiments: dictionary of experiments: resources, e.g. { "exp1|ud-fpga|FPGA experiments" : "fpga1@fpga boards"} """ broken_resources = { # resource_id : error_message } try: address = CoordAddress.translate(address_str) server = self.locator[address] failing_experiments = server.check_experiments_resources() # # failing_experiments is a dictionary such as: # { # experiment_instance_id : error_message # } # for failing_experiment in failing_experiments: if not failing_experiment in experiments: log.log( ResourcesChecker, log.level.Error, "Laboratory server %s reported that experiment %s was failing; however this laboratory does NOT manage this experiment. Attack?" % (address_str, failing_experiment)) continue # # The error for a resource will be concatenated # broken_resource = experiments[failing_experiment] error_message = failing_experiments[failing_experiment] if broken_resource in broken_resources: broken_resources[broken_resource] = broken_resources[broken_resource] + ';' + error_message else: broken_resources[broken_resource] = error_message except: traceback.print_exc() log.log( ResourcesChecker, log.level.Critical, "Error checking resources of laboratory %s " % address_str) log.log_exc(ResourcesChecker, log.level.Critical) return broken_resources
def setUp(self): self.coord_address = CoordAddress.translate( "server0:instance0@machine0") self.mock_locator = self.mocker.mock() 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.mock_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"))
def setUp(self): cfg_manager= ConfigurationManager.ConfigurationManager() cfg_manager.append_module(configuration_module) self.fake_client = FakeClient() self.fake_locator = FakeLocator(self.fake_client) locator = self.fake_locator self.experiment_instance_id = ExperimentInstanceId("exp_inst","exp_name","exp_cat") self.experiment_coord_address = CoordAddress.translate('myserver:myinstance@mymachine') cfg_manager._set_value('laboratory_assigned_experiments', { 'exp_inst:exp_name@exp_cat': { 'coord_address': 'myserver1:myinstance@mymachine', 'checkers': ( ('WebcamIsUpAndRunningHandler', ("https://...",)), ('HostIsUpAndRunningHandler', ("hostname", 80), {}), )} }) self.lab = LaboratoryServer.LaboratoryServer( None, locator, cfg_manager )
def test_reserve_experiment(self): clients_coord_addresses = CoordAddress.translate( "myserver:myinstance@mymachine") checking_handlers = ('WebcamIsUpAndRunningHandler', ) self._assigned_micro_servers.add_server( self.exp_inst_id, clients_coord_addresses, {'checkers': checking_handlers}) def check_reserve(): result = self._assigned_micro_servers.reserve_experiment( self.exp_inst_id, "my session id") self.assertEquals(clients_coord_addresses, result) check_reserve() self._assigned_micro_servers.free_experiment(self.exp_inst_id) check_reserve() self._assigned_micro_servers.free_experiment(self.exp_inst_id) self.assertRaises(LaboratoryErrors.AlreadyFreedExperimentError, self._assigned_micro_servers.free_experiment, self.exp_inst_id)
def _confirm_experiment(self, lab_coordaddress, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, resource_type_name): try: initial_time = datetime.datetime.now() try: labserver = self.locator[lab_coordaddress] reservation_result = labserver.reserve_experiment(experiment_instance_id, client_initial_data, server_initial_data) lab_session_id, server_initialization_response, exp_info = reservation_result except Exception as e: if DEBUG: traceback.print_exc() log.log( ReservationConfirmer, log.level.Error, "Exception confirming experiment: %s" % e ) log.log_exc( ReservationConfirmer, log.level.Warning ) self.coordinator.mark_experiment_as_broken(experiment_instance_id, [str(e)]) else: end_time = datetime.datetime.now() experiment_coordaddress = CoordAddress.translate(exp_info['address']) self.coordinator.confirm_experiment(experiment_coordaddress, experiment_instance_id.to_experiment_id(), reservation_id, lab_coordaddress.address, lab_session_id, server_initialization_response, initial_time, end_time, resource_type_name, exp_info) except: if DEBUG: traceback.print_exc() log.log(ReservationConfirmer, log.level.Critical, "Unexpected exception confirming experiment") log.log_exc(ReservationConfirmer, log.level.Critical)
def test_get_reservation_info(self): db_sess_id = ValidDatabaseSessionId('student2', "student") sess_id, _ = self.ups._reserve_session(db_sess_id) exp_id = ExperimentId('ud-dummy','Dummy experiments') lab_sess_id = SessionId.SessionId("lab_session_id") self.lab_mock.reserve_experiment(exp_id, "{}") self.mocker.result(lab_sess_id) self.mocker.count(0, 1) self.lab_mock.resolve_experiment_address(lab_sess_id) self.mocker.result(CoordAddress.translate('foo:bar@machine')) self.mocker.count(0, 1) self.mocker.replay() with wlcontext(self.ups, session_id = sess_id): reservation = core_api.reserve_experiment( exp_id, "{}", "{}") with wlcontext(self.ups, reservation_id = reservation.reservation_id): reservation_info = core_api.get_reservation_info() self.assertEquals('ud-dummy', reservation_info.exp_name) self.assertEquals('Dummy experiments', reservation_info.cat_name) with wlcontext(self.ups, session_id = sess_id): core_api.logout()
def _confirm_experiment(self, lab_coordaddress, reservation_id, experiment_instance_id, client_initial_data, server_initial_data, resource_type_name): try: initial_time = datetime.datetime.now() try: labserver = self.locator[lab_coordaddress] reservation_result = labserver.reserve_experiment( experiment_instance_id, client_initial_data, server_initial_data) lab_session_id, server_initialization_response, exp_info = reservation_result except Exception as e: if DEBUG: traceback.print_exc() log.log(ReservationConfirmer, log.level.Error, "Exception confirming experiment: %s" % e) log.log_exc(ReservationConfirmer, log.level.Warning) self.coordinator.mark_experiment_as_broken( experiment_instance_id, [str(e)]) else: end_time = datetime.datetime.now() experiment_coordaddress = CoordAddress.translate( exp_info['address']) self.coordinator.confirm_experiment( experiment_coordaddress, experiment_instance_id.to_experiment_id(), reservation_id, lab_coordaddress.address, lab_session_id, server_initialization_response, initial_time, end_time, resource_type_name, exp_info) except: if DEBUG: traceback.print_exc() log.log(ReservationConfirmer, log.level.Critical, "Unexpected exception confirming experiment") log.log_exc(ReservationConfirmer, log.level.Critical)
def setUp(self): self.coord_address = CoordAddress.translate( "server0:instance0@machine0") self.mock_locator = self.mocker.mock() 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.mock_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"))
def test_get_reservation_info(self): db_sess_id = ValidDatabaseSessionId('student2', "student") sess_id, _ = self.ups._reserve_session(db_sess_id) exp_id = ExperimentId('ud-dummy', 'Dummy experiments') lab_sess_id = SessionId.SessionId("lab_session_id") self.lab_mock.reserve_experiment(exp_id, "{}") self.mocker.result(lab_sess_id) self.mocker.count(0, 1) self.lab_mock.resolve_experiment_address(lab_sess_id) self.mocker.result(CoordAddress.translate('foo:bar@machine')) self.mocker.count(0, 1) self.mocker.replay() with wlcontext(self.ups, session_id=sess_id): reservation = core_api.reserve_experiment(exp_id, "{}", "{}") with wlcontext(self.ups, reservation_id=reservation.reservation_id): reservation_info = core_api.get_reservation_info() self.assertEquals('ud-dummy', reservation_info.exp_name) self.assertEquals('Dummy experiments', reservation_info.cat_name) with wlcontext(self.ups, session_id=sess_id): core_api.logout()
def get_reservation_status(self, reservation_id): self._remove_expired_reservations() expired = self.reservations_manager.update(reservation_id) if expired: self._delete_reservation(reservation_id) raise ExpiredSessionError("Expired reservation") self._synchronizer.request_and_wait() reservation_id_with_route = '%s;%s.%s' % ( reservation_id, reservation_id, self.core_server_route) client = self.redis_maker() weblab_reservation_pqueue = WEBLAB_RESOURCE_RESERVATION_PQUEUE % ( self.resource_type_name, reservation_id) reservation_data_str = client.get(weblab_reservation_pqueue) if reservation_data_str is None: log.log( PriorityQueueScheduler, log.level.Error, "get_reservation_status called with a reservation_id that is not registered (not found on weblab_reservation_pqueue). Returning a WaitingInstanceStatus" ) return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, 50) reservation_data = json.loads(reservation_data_str) if ACTIVE_STATUS in reservation_data: # Reserved or Waiting reservation status = reservation_data[ACTIVE_STATUS] # It may be just waiting for the experiment server to respond if status == STATUS_WAITING_CONFIRMATION: return WSS.WaitingConfirmationQueueStatus( reservation_id_with_route, self.core_server_url) # Or the experiment server already responded and therefore we have all this data str_lab_coord_address = reservation_data[LAB_COORD] obtained_time = reservation_data[TIME] initialization_in_accounting = reservation_data[ INITIALIZATION_IN_ACCOUNTING] lab_session_id = reservation_data[LAB_SESSION_ID] initial_configuration = reservation_data[INITIAL_CONFIGURATION] timestamp_before_tstamp = reservation_data[TIMESTAMP_BEFORE] timestamp_after_tstamp = reservation_data[TIMESTAMP_AFTER] if EXP_INFO in reservation_data and reservation_data[EXP_INFO]: exp_info = json.loads(reservation_data[EXP_INFO]) else: exp_info = {} timestamp_before = datetime.datetime.fromtimestamp( timestamp_before_tstamp) timestamp_after = datetime.datetime.fromtimestamp( timestamp_after_tstamp) lab_coord_address = CoordAddress.translate(str_lab_coord_address) if initialization_in_accounting: before = timestamp_before_tstamp else: before = timestamp_after_tstamp if before is not None: remaining = (before + obtained_time) - self.time_provider.get_time() else: remaining = obtained_time return WSS.LocalReservedStatus( reservation_id_with_route, lab_coord_address, SessionId.SessionId(lab_session_id), exp_info, obtained_time, initial_configuration, timestamp_before, timestamp_after, initialization_in_accounting, remaining, self.core_server_url) # else it's waiting weblab_resource_pqueue_map = WEBLAB_RESOURCE_PQUEUE_MAP % self.resource_type_name weblab_resource_pqueue_sorted = WEBLAB_RESOURCE_PQUEUE_SORTED % self.resource_type_name filled_reservation_id = client.hget(weblab_resource_pqueue_map, reservation_id) if filled_reservation_id is None: log.log( PriorityQueueScheduler, log.level.Error, "get_reservation_status called with a reservation_id that is not registered (not found on the reservations map). Returning a WaitingInstanceStatus" ) return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, 50) position = client.zrank(weblab_resource_pqueue_sorted, filled_reservation_id) if position is None: # It's not in the queue now time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) if self.resources_manager.are_resource_instances_working( self.resource_type_name): return WSS.WaitingQueueStatus(reservation_id_with_route, position) else: return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, position)
def get_reservation_status(self, reservation_id): self._remove_expired_reservations() try: session = self.session_maker() try: self.reservations_manager.update(session, reservation_id) session.commit() finally: session.close() except StaleDataError: time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) self._synchronizer.request_and_wait() reservation_id_with_route = '%s;%s.%s' % (reservation_id, reservation_id, self.core_server_route) return_current_status = False session = self.session_maker() try: # # If the current user is actually in a reservation assigned to a # certain laboratory, it may be in a Reserved state or in a # WaitingConfirmation state (meaning that it is still waiting for # a response from the Laboratory). # concrete_current_reservation = session.query(ConcreteCurrentReservation).filter(ConcreteCurrentReservation.current_reservation_id == reservation_id).first() if concrete_current_reservation is not None: resource_instance = concrete_current_reservation.slot_reservation.current_resource_slot.resource_instance requested_experiment_instance = None for experiment_instance in resource_instance.experiment_instances: if experiment_instance.experiment_type == concrete_current_reservation.current_reservation.reservation.experiment_type: requested_experiment_instance = experiment_instance break if requested_experiment_instance is None: raise Exception("Invalid state: there is an resource_instance of the resource_type the user was waiting for which doesn't have any experiment_instance of the experiment_type the user was waiting for") str_lab_coord_address = requested_experiment_instance.laboratory_coord_address lab_coord_address = CoordAddress.translate(str_lab_coord_address) obtained_time = concrete_current_reservation.time lab_session_id = concrete_current_reservation.lab_session_id if concrete_current_reservation.exp_info: exp_info = json.loads(concrete_current_reservation.exp_info) else: exp_info = {} initial_configuration = concrete_current_reservation.initial_configuration initialization_in_accounting = concrete_current_reservation.initialization_in_accounting if concrete_current_reservation.timestamp_before is None: timestamp_before = None else: timestamp_before = datetime.datetime.fromtimestamp(concrete_current_reservation.timestamp_before) if concrete_current_reservation.timestamp_after is None: timestamp_after = None else: timestamp_after = datetime.datetime.fromtimestamp(concrete_current_reservation.timestamp_after) if lab_session_id is None: return WSS.WaitingConfirmationQueueStatus(reservation_id_with_route, self.core_server_url) else: if initialization_in_accounting: before = concrete_current_reservation.timestamp_before else: before = concrete_current_reservation.timestamp_after if before is not None: remaining = (before + obtained_time) - self.time_provider.get_time() else: remaining = obtained_time return WSS.LocalReservedStatus(reservation_id_with_route, lab_coord_address, SessionId.SessionId(lab_session_id), exp_info, obtained_time, initial_configuration, timestamp_before, timestamp_after, initialization_in_accounting, remaining, self.core_server_url) resource_type = session.query(ResourceType).filter_by(name = self.resource_type_name).one() waiting_reservation = session.query(WaitingReservation).filter_by(reservation_id = reservation_id, resource_type_id = resource_type.id).first() if waiting_reservation is None: waiting_reservations = [] else: # # If it has not been assigned to any laboratory, then it might # be waiting in the queue of that resource type (Waiting) or # waiting for instances (WaitingInstances, meaning that there is # no resource of that type implemented) # waiting_reservations = session.query(WaitingReservation)\ .filter(WaitingReservation.resource_type == waiting_reservation.resource_type).order_by(WaitingReservation.priority, WaitingReservation.id).all() if waiting_reservation is None or waiting_reservation not in waiting_reservations: # # The position has changed and it is not in the list anymore! # This has happened using WebLab Bot with 65 users. # return_current_status = True else: position = waiting_reservations.index(waiting_reservation) remaining_working_instances = False for resource_instance in waiting_reservation.resource_type.instances: if resource_instance.slot is not None: remaining_working_instances = True break finally: session.close() if return_current_status: time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) if remaining_working_instances: return WSS.WaitingQueueStatus(reservation_id_with_route, position) else: return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, position)
def coord_addr(coord_addr_str): return CoordAddress.translate(coord_addr_str)
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
def get_reservation_status(self, reservation_id): self._remove_expired_reservations() expired = self.reservations_manager.update(reservation_id) if expired: self._delete_reservation(reservation_id) raise ExpiredSessionError("Expired reservation") self._synchronizer.request_and_wait() reservation_id_with_route = '%s;%s.%s' % (reservation_id, reservation_id, self.core_server_route) client = self.redis_maker() weblab_reservation_pqueue = WEBLAB_RESOURCE_RESERVATION_PQUEUE % (self.resource_type_name, reservation_id) reservation_data_str = client.get(weblab_reservation_pqueue) if reservation_data_str is None: log.log( PriorityQueueScheduler, log.level.Error, "get_reservation_status called with a reservation_id that is not registered (not found on weblab_reservation_pqueue). Returning a WaitingInstanceStatus") return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, 50) reservation_data = json.loads(reservation_data_str) if ACTIVE_STATUS in reservation_data: # Reserved or Waiting reservation status = reservation_data[ACTIVE_STATUS] # It may be just waiting for the experiment server to respond if status == STATUS_WAITING_CONFIRMATION: return WSS.WaitingConfirmationQueueStatus(reservation_id_with_route, self.core_server_url) # Or the experiment server already responded and therefore we have all this data str_lab_coord_address = reservation_data[LAB_COORD] obtained_time = reservation_data[TIME] initialization_in_accounting = reservation_data[INITIALIZATION_IN_ACCOUNTING] lab_session_id = reservation_data[LAB_SESSION_ID] initial_configuration = reservation_data[INITIAL_CONFIGURATION] timestamp_before_tstamp = reservation_data[TIMESTAMP_BEFORE] timestamp_after_tstamp = reservation_data[TIMESTAMP_AFTER] if EXP_INFO in reservation_data and reservation_data[EXP_INFO]: exp_info = json.loads(reservation_data[EXP_INFO]) else: exp_info = {} timestamp_before = datetime.datetime.fromtimestamp(timestamp_before_tstamp) timestamp_after = datetime.datetime.fromtimestamp(timestamp_after_tstamp) lab_coord_address = CoordAddress.translate(str_lab_coord_address) if initialization_in_accounting: before = timestamp_before_tstamp else: before = timestamp_after_tstamp if before is not None: remaining = (before + obtained_time) - self.time_provider.get_time() else: remaining = obtained_time return WSS.LocalReservedStatus(reservation_id_with_route, lab_coord_address, SessionId.SessionId(lab_session_id), exp_info, obtained_time, initial_configuration, timestamp_before, timestamp_after, initialization_in_accounting, remaining, self.core_server_url) # else it's waiting weblab_resource_pqueue_map = WEBLAB_RESOURCE_PQUEUE_MAP % self.resource_type_name weblab_resource_pqueue_sorted = WEBLAB_RESOURCE_PQUEUE_SORTED % self.resource_type_name filled_reservation_id = client.hget(weblab_resource_pqueue_map, reservation_id) if filled_reservation_id is None: log.log( PriorityQueueScheduler, log.level.Error, "get_reservation_status called with a reservation_id that is not registered (not found on the reservations map). Returning a WaitingInstanceStatus") return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, 50) position = client.zrank(weblab_resource_pqueue_sorted, filled_reservation_id) if position is None: # It's not in the queue now time.sleep(TIME_ANTI_RACE_CONDITIONS * random.random()) return self.get_reservation_status(reservation_id) if self.resources_manager.are_resource_instances_working(self.resource_type_name): return WSS.WaitingQueueStatus(reservation_id_with_route, position) else: return WSS.WaitingInstancesQueueStatus(reservation_id_with_route, position)
import weblab.data.dto.experiments as Experiment import weblab.data.dto.experiments as ExperimentAllowed import weblab.data.dto.experiments as ExperimentUse import weblab.data.dto.users as User import weblab.data.dto.users as Role from weblab.data import ValidDatabaseSessionId from weblab.core.coordinator.resource import Resource import weblab.core.exc as coreExc import test.unit.configuration as configuration_module import voodoo.configuration as ConfigurationManager laboratory_coordaddr = CoordAddress.translate( "server:laboratoryserver@labmachine" ) @case_uses_module(Confirmer) class UserProcessorTestCase(unittest.TestCase): def setUp(self): self.mocker = mocker.Mocker() self.lab_mock = self.mocker.mock() self.locator = FakeLocator( lab = self.lab_mock ) self.db = FakeDatabase() self.cfg_manager = ConfigurationManager.ConfigurationManager() self.cfg_manager.append_module(configuration_module) self.cfg_manager._set_value(COORDINATOR_LABORATORY_SERVERS, { 'server:laboratoryserver@labmachine' : {
import weblab.data.dto.experiments as Category import weblab.data.dto.experiments as Experiment import weblab.data.dto.experiments as ExperimentAllowed import weblab.data.dto.experiments as ExperimentUse import weblab.data.dto.users as User import weblab.data.dto.users as Role from weblab.data import ValidDatabaseSessionId from weblab.core.coordinator.resource import Resource import weblab.core.exc as coreExc import test.unit.configuration as configuration_module import voodoo.configuration as ConfigurationManager laboratory_coordaddr = CoordAddress.translate( "server:laboratoryserver@labmachine") @case_uses_module(Confirmer) class UserProcessorTestCase(unittest.TestCase): def setUp(self): self.mocker = mocker.Mocker() self.lab_mock = self.mocker.mock() self.locator = FakeLocator(lab=self.lab_mock) self.db = FakeDatabase() self.cfg_manager = ConfigurationManager.ConfigurationManager() self.cfg_manager.append_module(configuration_module) self.cfg_manager._set_value( COORDINATOR_LABORATORY_SERVERS, {
def enqueue_should_finish(self, lab_coordaddress_str, lab_session_id, reservation_id): lab_coordaddress = CoordAddress.translate(lab_coordaddress_str) self._should_finish(lab_coordaddress, lab_session_id, reservation_id)
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