def uninstall(package_name, service_name): """Uninstalls the specified service from the cluster, and verifies that its resources and framework were correctly cleaned up after the uninstall has completed. Any agents which are expected to have orphaned resources (e.g. due to being shut down) should be passed to ignore_dead_agent() before triggering the uninstall. """ start = time.time() log.info("Uninstalling {}".format(service_name)) # Display current SDK Plan before uninstall, helps with debugging stuck uninstalls log.info("Current plan status for {}".format(service_name)) sdk_cmd.svc_cli(package_name, service_name, "plan status deploy", check=False) try: _retried_uninstall_package_and_wait(package_name, service_name) except Exception: log.exception( "Got exception when uninstalling {}".format(service_name)) raise cleanup_start = time.time() try: if sdk_utils.dcos_version_less_than("1.10"): # 1.9 and earlier: Run janitor to unreserve resources log.info("Janitoring {}".format(service_name)) _retried_run_janitor(service_name) except Exception: log.exception("Got exception when cleaning up {}".format(service_name)) raise finish = time.time() log.info("Uninstalled {} after pkg({}) + cleanup({}) = total({})".format( service_name, sdk_utils.pretty_duration(cleanup_start - start), sdk_utils.pretty_duration(finish - cleanup_start), sdk_utils.pretty_duration(finish - start), )) # Sanity check: Verify that all resources and the framework have been successfully cleaned up, # and throw an exception if anything is left over (uninstall bug?) _verify_completed_uninstall(service_name) # Finally, remove the service from the installed list (used by sdk_diag) global _installed_service_names try: _installed_service_names.remove(service_name) except KeyError: pass # Expected when tests preemptively uninstall at start of test
def _cluster_request(): start = time.time() response = requests.request(method, url, auth=auth, verify=False, timeout=timeout_seconds, **kwargs) end = time.time() log_msg = "(HTTP {}) {}".format(method.upper(), cluster_path) if kwargs: # log arg content (or just arg names, with hack to avoid 'dict_keys([...])') if present log_msg += " (args: {})".format( kwargs if log_args else [e for e in kwargs.keys()]) log_msg += " => {} ({})".format(response.status_code, sdk_utils.pretty_duration(end - start)) log.info(log_msg) if log_response or not response.ok: # Response logging enabled, or query failed (>= 400). Before (potentially) throwing, # print response payload which may include additional error details. response_text = response.text if response_text: log.info("Response content ({} bytes):\n{}".format( len(response_text), response_text)) else: log.info("No response content") if raise_on_error: response.raise_for_status() return response
def install( package_name: str, service_name: str, expected_running_tasks: int, additional_options: dict = {}, package_version: PackageVersion = PackageVersion.STUB_UNIVERSE, timeout_seconds: int = TIMEOUT_SECONDS, wait_for_deployment: bool = True, insert_strict_options: bool = True, wait_for_all_conditions: bool = True, ) -> None: start = time.time() # If the package is already installed at this point, fail immediately. if sdk_marathon.app_exists(service_name): raise Exception( "Service is already installed: {}".format(service_name)) if insert_strict_options and sdk_utils.is_strict_mode(): # strict mode requires correct principal and secret to perform install. # see also: sdk_security.py options = sdk_utils.merge_dictionaries( { "service": { "service_account": "service-acct", "principal": "service-acct", "service_account_secret": "secret", "secret_name": "secret", } }, additional_options, ) else: options = additional_options # 1. Install package, wait for tasks, wait for marathon deployment _retried_install_impl( package_name, service_name, expected_running_tasks, package_version.value if isinstance( package_version, PackageVersion) else package_version, options, timeout_seconds, wait_for_all_conditions) # 2. Wait for the scheduler to be idle (as implied by deploy plan completion and suppressed bit) # This should be skipped ONLY when it's known that the scheduler will be stuck in an incomplete # state, or if the thing being installed doesn't have a deployment plan (e.g. standalone app) if wait_for_deployment: # this can take a while, default is 15 minutes. for example with HDFS, we can hit the expected # total task count via FINISHED tasks, without actually completing deployment log.info( "Waiting for package={} service={} to finish deployment plan...". format(package_name, service_name)) sdk_plan.wait_for_completed_deployment(service_name, timeout_seconds) log.info("Installed package={} service={} after {}".format( package_name, service_name, sdk_utils.pretty_duration(time.time() - start))) global _installed_service_names _installed_service_names.add(service_name)
def pytest_runtest_teardown(item: pytest.Item): """Hook to run after every test.""" # Inject footer at end of test, may be followed by additional teardown. # Don't do this when running in teamcity, where it's redundant. if not teamcity.is_running_under_teamcity(): global start_time duration = time.time() - start_time start_time = 0 print( """ ========== ======= END: {}::{} ({}) ==========""".format( sdk_diag.get_test_suite_name(item), item.name, sdk_utils.pretty_duration(duration) ) )
def _cluster_request() -> requests.Response: start = time.time() # check if we have verify key already exists. if kwargs is not None and kwargs.get("verify") is not None: kwargs["verify"] = False response = requests.request(method, url, auth=auth, timeout=timeout_seconds, **kwargs) else: response = requests.request( method, url, auth=auth, verify=False, timeout=timeout_seconds, **kwargs ) end = time.time() log_msg = "(HTTP {}) {}".format(method.upper(), cluster_path) if kwargs: # log arg content (or just arg names, with hack to avoid 'dict_keys([...])') if present log_msg += " (args: {})".format(kwargs if log_args else [e for e in kwargs.keys()]) log_msg += " => {} ({})".format( response.status_code, sdk_utils.pretty_duration(end - start) ) log.info(log_msg) if log_response or not response.ok: # Response logging enabled, or query failed (>= 400). Before (potentially) throwing, # print response payload which may include additional error details. response_text = response.text if response_text: log.info( "Response content ({} bytes):\n{}".format(len(response_text), response_text) ) else: log.info("No response content") if raise_on_error: response.raise_for_status() return response