def test_parse_malformed_app_handles(self): bad_app_handles = { "my_session/my_application_id": "missing scheduler backend", "local://my_session/": "missing app_id", "local://my_application_id": "missing session", } for handle, msg in bad_app_handles.items(): with self.subTest(f"malformed app handle: {msg}", handle=handle): with self.assertRaises(MalformedAppHandleException): parse_app_handle(handle)
def log_lines( self, app_handle: AppHandle, role_name: str, k: int = 0, regex: Optional[str] = None, since: Optional[datetime] = None, until: Optional[datetime] = None, should_tail: bool = False, ) -> Iterable: scheduler_backend, _, app_id = parse_app_handle(app_handle) tsm_event = self._generate_tsm_event( "log_lines", scheduler_backend, app_id, ) try: log_iter = self._log_lines(app_handle, role_name, k, regex, since, until, should_tail) record(tsm_event) return log_iter except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise
def test_parse(self): (scheduler_backend, session_name, app_id) = parse_app_handle( "local://my_session/my_app_id_1234" ) self.assertEqual("local", scheduler_backend) self.assertEqual("my_session", session_name) self.assertEqual("my_app_id_1234", app_id)
def wait(self, app_handle: AppHandle) -> Optional[AppStatus]: scheduler_backend, _, app_id = parse_app_handle(app_handle) tsm_event = self._generate_tsm_event("wait", scheduler_backend, app_id) try: record(tsm_event) return self._wait(app_handle) except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise
def status(self, app_handle: AppHandle) -> Optional[AppStatus]: # allow status checks of apps from other sessions scheduler_backend, _, app_id = parse_app_handle(app_handle) tsm_event = self._generate_tsm_event("status", scheduler_backend, app_id) try: app_status = self._status(app_handle) record(tsm_event) return app_status except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise
def stop(self, app_handle: AppHandle) -> None: scheduler_backend, _, app_id = parse_app_handle(app_handle) tsm_event = self._generate_tsm_event( "stop", scheduler_backend, app_id, ) try: self._stop(app_handle) record(tsm_event) except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise
def test_schedule_success(self, record_tsm_mock): app_info = AppDryRunInfo("test", lambda x: "test") app_info._scheduler = "default" cfg = RunConfig({"image_fetcher": "dir"}) app_info._cfg = cfg session = DummySession("test_session") app_handle = session.schedule(app_info) actual_tsm_event = record_tsm_mock.call_args[0][0] # first arg _, _, app_id = parse_app_handle(app_handle) self.assert_tsm_event( session._generate_tsm_event( "schedule", "default", app_id, runcfg=json.dumps(cfg.cfgs) ), actual_tsm_event, )
def describe(self, app_handle: AppHandle) -> Optional[Application]: scheduler_backend, _, app_id = parse_app_handle(app_handle) tsm_event = self._generate_tsm_event( "describe", scheduler_backend, app_id, ) try: res = self._describe(app_handle) record(tsm_event) return res except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise
def _scheduler_app_id(self, app_handle: AppHandle, check_session: bool = True) -> Tuple[Scheduler, str]: """ Returns the scheduler and app_id from the app_handle. Set ``check_session`` to validate that the session name in the app handle is the same as this session. Raises: ValueError - if ``check_session=True`` and the session in the app handle does not match this session's name KeyError - if no such scheduler backend exists """ scheduler_backend, session_name, app_id = parse_app_handle(app_handle) if check_session and self._name != session_name: raise SessionMismatchException(app_handle, self._name) scheduler = self._scheduler(scheduler_backend) return scheduler, app_id
def status(self, app_handle: AppHandle, external: bool = True) -> Optional[AppStatus]: # TODO(wilsonhong): ``external`` is a short term soluation. For long term we should # fill this value automatically instead of exposing this to user. # allow status checks of apps from other sessions scheduler_backend, _, app_id = parse_app_handle(app_handle) tsm_event = self._generate_tsm_event( "status", scheduler_backend, app_id, source=SourceType.EXTERNAL if external else SourceType.INTERNAL, ) try: app_status = self._status(app_handle) record(tsm_event) return app_status except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise
def schedule(self, dryrun_info: AppDryRunInfo) -> AppHandle: scheduler_backend = dryrun_info._scheduler runcfg = json.dumps( dryrun_info._cfg.cfgs) if dryrun_info._cfg else None tsm_event = self._generate_tsm_event( "schedule", scheduler_backend, runcfg=runcfg, ) try: app_handle = self._schedule(dryrun_info) _, _, app_id = parse_app_handle(app_handle) tsm_event.app_id = app_id # TODO(avivanou): t81936552 each action corresponds to a method call # as a result instead of repeatedly log events in each method, we # can log them implicitly via footsteps lib record(tsm_event) return app_handle except Exception: tsm_event.raw_exception = traceback.format_exc() record(tsm_event) raise