diff --git a/robottelo/host_helpers/capsule_mixins.py b/robottelo/host_helpers/capsule_mixins.py index 9e283509696..e3fc4b3cf7c 100644 --- a/robottelo/host_helpers/capsule_mixins.py +++ b/robottelo/host_helpers/capsule_mixins.py @@ -1,6 +1,11 @@ -from datetime import datetime +from datetime import ( + datetime, + timedelta, +) import time +from dateutil.parser import parse + from robottelo.constants import PUPPET_CAPSULE_INSTALLER, PUPPET_COMMON_INSTALLER_OPTS from robottelo.logging import logger from robottelo.utils.installer import InstallerCommand @@ -67,20 +72,51 @@ def wait_for_sync(self, timeout=600, start_time=None): # is started (or finished already) if start_time is None: start_time = datetime.utcnow().replace(microsecond=0) + # 1s margin of safety for rounding + start_time = (start_time - timedelta(seconds=1)).strftime('%Y-%m-%d %H:%M:%S UTC') logger.info(f"Waiting for capsule {self.hostname} sync to finish ...") sync_status = self.nailgun_capsule.content_get_sync() logger.info(f"Active tasks {sync_status['active_sync_tasks']}") - assert ( - len(sync_status['active_sync_tasks']) - or datetime.strptime(sync_status['last_sync_time'], '%Y-%m-%d %H:%M:%S UTC') - >= start_time - ) + ongoing_sync = True if sync_status['active_sync_tasks'] else False + + if not sync_status['last_sync_time']: # never synced + # we expect some in-progress sync task(s) ongoing + assert len(sync_status['active_sync_tasks']) > 0, ( + f'last_sync_time for capsule {self.hostname} was None (never),' + ' expected one or more ongoing sync task(s), but found none.' + ) + else: + if parse(sync_status['last_sync_time']) >= parse(start_time): + # last sync time was at or after start_time + pass + else: + # last sync is prior to start_time, expect some ongoing sync task(s) + assert len(sync_status['active_sync_tasks']) > 0, ( + f'last_sync_time: ({sync_status["last_sync_time"]}), for capsule {self.hostname},' + f' was older than start_time: {start_time}.' + ' Expected one or more ongoing sync task(s), but found none.' + ) # Wait till capsule sync finishes and assert the sync task succeeded for task in sync_status['active_sync_tasks']: self.satellite.api.ForemanTask(id=task['id']).poll(timeout=timeout) + # after any in-progress sync task(s) finished, get updated sync_status sync_status = self.nailgun_capsule.content_get_sync() - assert len(sync_status['last_failed_sync_tasks']) == 0 + if ongoing_sync: + # with the ongoing task(s) finished, find that last sync was at or after start_time + assert parse(sync_status['last_sync_time']) >= parse(start_time), ( + f'After polling finished in-progress sync task(s), for capsule {self.hostname},' + f' last_sync_time: {sync_status["last_sync_time"]}, was not on or after start_time: {start_time}.' + ) + # after finishing task(s), updated status shows no active tasks + assert ( + len(sync_status['active_sync_tasks']) == 0 + ), f'Expected no active sync task(s) remaining for capsule {self.hostname}' + # no failed tasks + assert len(sync_status['last_failed_sync_tasks']) == 0, ( + f'One or more sync tasks have failed for capsule {self.hostname},' + f' {sync_status["last_failed_sync_tasks"]}' + ) def get_published_repo_url(self, org, prod, repo, lce=None, cv=None): """Forms url of a repo or CV published on a Satellite or Capsule.