def destroy_app(self, app_name, timeout=120): """Remove a marathon app Abort the test if the removal was unsuccessful. Args: app_name: name of the application to remove timeout: seconds to wait for destruction before failing test """ @retrying.retry(wait_fixed=1000, stop_max_delay=timeout * 1000, retry_on_result=lambda ret: not ret, retry_on_exception=lambda x: False) def _destroy_complete(deployment_id): r = self.get('v2/deployments') r.raise_for_status() for deployment in r.json(): if deployment_id == deployment.get('id'): logging.info('Waiting for application to be destroyed') return False logging.info('Application destroyed') return True r = self.delete(path_join('v2/apps', app_name)) r.raise_for_status() try: _destroy_complete(r.json()['deploymentId']) except retrying.RetryError: raise Exception("Application destroy failed - operation was not " "completed in {} seconds.".format(timeout))
def destroy_app(self, app_name, timeout=120): """Remove a marathon app Abort the test if the removal was unsuccessful. Args: app_name: name of the application to remove timeout: seconds to wait for destruction before failing test """ @retrying.retry(wait_fixed=1000, stop_max_delay=timeout * 1000, retry_on_result=lambda ret: not ret, retry_on_exception=lambda x: False) def _destroy_complete(deployment_id): r = self.get('v2/deployments') r.raise_for_status() for deployment in r.json(): if deployment_id == deployment.get('id'): logging.info('Waiting for application to be destroyed') return False logging.info('Application destroyed') return True r = self.delete(path_join('v2/apps', app_name)) r.raise_for_status() try: _destroy_complete(r.json()['deploymentId']) except retrying.RetryError: raise Exception("Application destroy failed - operation was not " "completed in {} seconds.".format(timeout))
def _poll_marathon_for_app_deployment(app_id): Endpoint = collections.namedtuple("Endpoint", ["host", "port", "ip"]) # Some of the counters need to be explicitly enabled now and/or in # future versions of Marathon: req_params = (('embed', 'apps.lastTaskFailure'), ('embed', 'apps.counts')) r = self.get(path_join('v2/apps', app_id), params=req_params) r.raise_for_status() data = r.json() if not ignore_failed_tasks: assert 'lastTaskFailure' not in data['app'], ( 'Application deployment failed, reason: {}'.format( data['app']['lastTaskFailure']['message'])) check_tasks_running = ( data['app']['tasksRunning'] == app_definition['instances']) check_tasks_healthy = (not check_health or data['app']['tasksHealthy'] == app_definition['instances']) if check_tasks_running and check_tasks_healthy: res = [ Endpoint(t['host'], t['ports'][0], t['ipAddresses'][0]['ipAddress']) if len(t['ports']) is not 0 else Endpoint( t['host'], 0, t['ipAddresses'][0]['ipAddress']) for t in data['app']['tasks'] ] logging.info('Application deployed, running on {}'.format(res)) return res elif not check_tasks_running: logging.info('Waiting for application to be deployed: ' 'Not all instances are running: {}'.format( repr(data))) return None elif not check_tasks_healthy: logging.info('Waiting for application to be deployed: ' 'Not all instances are healthy: {}'.format( repr(data))) return None else: logging.info( 'Waiting for application to be deployed: {}'.format( repr(data))) return None
def _poll_marathon_for_app_deployment(app_id): Endpoint = collections.namedtuple("Endpoint", ["host", "port", "ip"]) # Some of the counters need to be explicitly enabled now and/or in # future versions of Marathon: req_params = (('embed', 'apps.lastTaskFailure'), ('embed', 'apps.counts')) log.info('Waiting for application to be deployed...') r = self.get(path_join('v2/apps', app_id), params=req_params) r.raise_for_status() data = r.json() log.debug('Current application state data: {}'.format(repr(data))) if 'lastTaskFailure' in data['app']: message = data['app']['lastTaskFailure']['message'] if not ignore_failed_tasks: raise AssertionError('Application deployment failed, reason: {}'.format(message)) else: log.warn('Task failure detected: {}'.format(message)) check_tasks_running = (data['app']['tasksRunning'] == app_definition['instances']) check_tasks_healthy = (not check_health or data['app']['tasksHealthy'] == app_definition['instances']) if check_tasks_running and check_tasks_healthy: res = [Endpoint(t['host'], t['ports'][0], t['ipAddresses'][0]['ipAddress']) if len(t['ports']) is not 0 else Endpoint(t['host'], 0, t['ipAddresses'][0]['ipAddress']) for t in data['app']['tasks']] log.info('Application deployed, running on {}'.format(res)) return res elif not check_tasks_running: log.debug('Not all instances are running!') return None elif not check_tasks_healthy: log.debug('Not all instances are healthy!') return None else: log.debug('Still waiting for application to scale...') return None
def _pool_for_marathon_app(app_id): Endpoint = collections.namedtuple("Endpoint", ["host", "port", "ip"]) # Some of the counters need to be explicitly enabled now and/or in # future versions of Marathon: req_params = (('embed', 'apps.lastTaskFailure'), ('embed', 'apps.counts')) r = self.get(path_join('v2/apps', app_id), params=req_params) r.raise_for_status() data = r.json() if not ignore_failed_tasks: assert 'lastTaskFailure' not in data['app'], ( 'Application deployment failed, reason: {}'.format(data['app']['lastTaskFailure']['message']) ) check_tasks_running = (data['app']['tasksRunning'] == app_definition['instances']) check_tasks_healthy = (not check_health or data['app']['tasksHealthy'] == app_definition['instances']) if (check_tasks_running and check_tasks_healthy): res = [Endpoint(t['host'], t['ports'][0], t['ipAddresses'][0]['ipAddress']) if len(t['ports']) is not 0 else Endpoint(t['host'], 0, t['ipAddresses'][0]['ipAddress']) for t in data['app']['tasks']] logging.info('Application deployed, running on {}'.format(res)) return res elif (not check_tasks_running): logging.info('Waiting for application to be deployed: ' 'Not all instances are running: {}'.format(repr(data))) return None elif (not check_tasks_healthy): logging.info('Waiting for application to be deployed: ' 'Not all instances are healthy: {}'.format(repr(data))) return None else: logging.info('Waiting for application to be deployed: {}'.format(repr(data))) return None