예제 #1
0
    def test_updated_scheduled_next_run(self):
        call_request = CallRequest(itinerary_call)
        interval = datetime.timedelta(minutes=2)
        now = datetime.datetime.now(tz=dateutils.utc_tz())
        old_schedule = dateutils.format_iso8601_interval(interval, now)

        scheduled_id = self.scheduler.add(call_request, old_schedule)

        self.assertNotEqual(scheduled_id, None)

        scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(scheduled_id)})

        self.assertNotEqual(scheduled_call, None)

        old_interval, start_time = dateutils.parse_iso8601_interval(old_schedule)[:2]
        start_time = dateutils.to_naive_utc_datetime(start_time)

        self.assertEqual(scheduled_call['last_run'], None)
        self.assertEqual(scheduled_call['first_run'], start_time + old_interval)
        self.assertEqual(scheduled_call['next_run'], start_time + old_interval)

        interval = datetime.timedelta(minutes=1)
        new_schedule = dateutils.format_iso8601_interval(interval, now)

        self.scheduler.update(scheduled_id, schedule=new_schedule)
        updated_scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(scheduled_id)})

        new_interval = dateutils.parse_iso8601_interval(new_schedule)[0]

        self.assertEqual(updated_scheduled_call['last_run'], None)
        self.assertEqual(updated_scheduled_call['first_run'], start_time + old_interval)
        self.assertEqual(updated_scheduled_call['next_run'], start_time + new_interval)
예제 #2
0
 def test_interval_start_time(self):
     d = datetime.timedelta(minutes=2)
     t = datetime.datetime(year=2014, month=11, day=5, hour=0, minute=23)
     s = dateutils.format_iso8601_interval(d, t)
     i, e, r = dateutils.parse_iso8601_interval(s)
     self.assertEqual(d, i)
     self.assertEqual(t, e)
예제 #3
0
 def test_interval_recurrences(self):
     d = datetime.timedelta(hours=4, minutes=2, seconds=59)
     c = 4
     s = dateutils.format_iso8601_interval(d, recurrences=c)
     i, t, r = dateutils.parse_iso8601_interval(s)
     self.assertEqual(d, i)
     self.assertEqual(c, r)
예제 #4
0
 def test_interval_start_time(self):
     d = datetime.timedelta(minutes=2)
     t = datetime.datetime(year=2014, month=11, day=5, hour=0, minute=23)
     s = dateutils.format_iso8601_interval(d, t)
     i, e, r = dateutils.parse_iso8601_interval(s)
     self.assertEqual(d, i)
     self.assertEqual(t, e)
예제 #5
0
 def test_interval_recurrences(self):
     d = datetime.timedelta(hours=4, minutes=2, seconds=59)
     c = 4
     s = dateutils.format_iso8601_interval(d, recurrences=c)
     i, t, r = dateutils.parse_iso8601_interval(s)
     self.assertEqual(d, i)
     self.assertEqual(c, r)
예제 #6
0
 def test_interval_full(self):
     i1 = datetime.timedelta(hours=100)
     t1 = datetime.datetime(year=2, month=6, day=20, hour=2, minute=22, second=46)
     r1 = 5
     s = dateutils.format_iso8601_interval(i1, t1, r1)
     i2, t2, r2 = dateutils.parse_iso8601_interval(s)
     self.assertEqual(i1, i2)
     self.assertEqual(t1, t2)
     self.assertEqual(r1, r2)
예제 #7
0
 def test_interval_full(self):
     i1 = datetime.timedelta(hours=100)
     t1 = datetime.datetime(year=2, month=6, day=20, hour=2, minute=22, second=46)
     r1 = 5
     s = dateutils.format_iso8601_interval(i1, t1, r1)
     i2, t2, r2 = dateutils.parse_iso8601_interval(s)
     self.assertEqual(i1, i2)
     self.assertEqual(t1, t2)
     self.assertEqual(r1, r2)
예제 #8
0
 def test_calculate_next_run(self):
     call_request = CallRequest(call)
     interval = datetime.timedelta(minutes=1)
     schedule = dateutils.format_iso8601_interval(interval)
     scheduled_id = self.scheduler.add(call_request, schedule)
     scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(scheduled_id)})
     next_run = self.scheduler.calculate_next_run(scheduled_call)
     self.assertFalse(next_run is None)
     self.assertTrue(next_run == scheduled_call['first_run'])
     self.scheduler.update_last_run(scheduled_call)
     updated_scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(scheduled_id)})
     updated_next_run = self.scheduler.calculate_next_run(updated_scheduled_call)
     self.assertTrue(updated_next_run == updated_scheduled_call['last_run'])
예제 #9
0
 def test_calculate_next_run_duration(self):
     call_request = CallRequest(call)
     now = datetime.datetime.now()
     interval = isodate.Duration(months=1)
     schedule = dateutils.format_iso8601_interval(interval, now)
     schedule_id = self.scheduler.add(call_request, schedule)
     scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(schedule_id)})
     next_run = self.scheduler.calculate_next_run(scheduled_call)
     self.assertFalse(next_run is None)
     self.assertTrue(next_run == scheduled_call['first_run'])
     self.scheduler.update_last_run(scheduled_call)
     updated_scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(schedule_id)})
     updated_next_run = self.scheduler.calculate_next_run(updated_scheduled_call)
     self.assertTrue(updated_next_run == updated_scheduled_call['last_run'])
예제 #10
0
    def test_next_run_updated(self):
        call_request = CallRequest(itinerary_call)
        now = datetime.datetime.now()
        interval = datetime.timedelta(minutes=1)
        schedule = dateutils.format_iso8601_interval(interval, now)
        schedule_id = self.scheduler.add(call_request, schedule)

        scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(schedule_id)})
        next_next_run = self.scheduler.calculate_next_run(scheduled_call)

        self.scheduler._get_scheduled_call_groups()

        updated_scheduled_call = self.scheduled_call_collection.find_one({'_id': ObjectId(schedule_id)})
        self.assertEqual(next_next_run, updated_scheduled_call['next_run'])
예제 #11
0
    def test_scheduled_collision(self):
        call_request_scheduled = CallRequest(itinerary_call)
        schedule  = dateutils.format_iso8601_interval(datetime.timedelta(minutes=1),
                                                      datetime.datetime.now())
        schedule_id = self.scheduler.add(call_request_scheduled, schedule)

        call_request_in_progress = CallRequest(dummy_call)
        call_report_in_progress = CallReport.from_call_request(call_request_in_progress)
        call_report_in_progress.schedule_id = schedule_id

        # return a call report list out of the coordinator that has tasks from
        # this schedule in it
        # this will be cleaned up by the base class tearDown method
        mocked_coordinator = mock.Mock()
        mocked_call_reports = mock.Mock(return_value=[call_report_in_progress])
        mocked_coordinator.find_call_reports = mocked_call_reports
        dispatch_factory.coordinator = mock.Mock(return_value=mocked_coordinator)

        call_group_generator = self.scheduler._get_call_request_groups_for_scheduled_itineraries()

        # call reports should have indicated a collision, in which we do not
        # run the scheduled call group again, indicated here by an "empty"
        # generator
        self.assertRaises(StopIteration, next, call_group_generator)
예제 #12
0
 def test_interval(self):
     d = datetime.timedelta(hours=1)
     s = dateutils.format_iso8601_interval(d)
     i, t, r = dateutils.parse_iso8601_interval(s)
     self.assertTrue(d == i)
예제 #13
0
 def test_interval(self):
     d = datetime.timedelta(hours=1)
     s = dateutils.format_iso8601_interval(d)
     i, t, r = dateutils.parse_iso8601_interval(s)
     self.assertTrue(d == i)
예제 #14
0
파일: repo.py 프로젝트: stpierre/sponge
def rebalance_sync_schedule(errors=None):
    repoapi = RepositoryAPI()
    repos = get_repos()

    # get a list of sync frequencies
    syncgroups = dict()  # dict of sync time -> [groups]
    default = None
    for ckey, sync in config.list(filter=dict(name__startswith="sync_frequency_")).items():
        group = ckey.replace("sync_frequency_", "")
        if sync is None:
            logger.error("Sync frequency for %s is None, skipping" % group)
            continue
        synctime = 60 * 60 * int(sync)
        if "group" == "default":
            default = synctime
        else:
            try:
                syncgroups[synctime].append(group)
            except KeyError:
                syncgroups[synctime] = [group]

    # divide the repos up by sync time and sort them by inheritance,
    # reversed, to ensure that children get synced before parents and
    # a package doesn't just go straight to the final child
    cycles = dict()  # dict of repo -> sync time
    for repo in repos.values():
        cycles[repo["id"]] = default
        for synctime, groups in syncgroups.items():
            if set(groups) & set(repo["groupid"]) and (cycles[repo["id"]] is None or synctime > cycles[repo["id"]]):
                cycles[repo["id"]] = synctime

    # finally, build a dict of sync time -> [repos]
    syncs = dict()
    for repoid, synctime in cycles.items():
        if synctime is None:
            continue
        try:
            syncs[synctime].append(repos[repoid])
        except KeyError:
            syncs[synctime] = [repos[repoid]]

    for synctime, syncrepos in syncs.items():
        syncrepos = sort_repos_by_ancestry(syncrepos)
        syncrepos.reverse()

        # we count the total number of packages in all repos, and
        # divide them evenly amongst the timespan allotted.  It's
        # worth noting that we count clones just the same as we count
        # "regular" repos, because it's createrepo, not the sync, that
        # really takes a lot of time and memory.
        pkgs = 0
        for repo in syncrepos:
            if repo["package_count"] < 10:
                # we still have to run createrepo even if there are
                # very few (or no!) packages, so count very small
                # repos as 10 packages
                pkgs += 10
            else:
                pkgs += repo["package_count"]

        try:
            pkgtime = float(synctime) / pkgs
        except ZeroDivisionError:
            pkgtime = 1
            logger.debug("Allowing %s seconds per package" % pkgtime)

        # find tomorrow morning at 12:00 am
        tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
        start = datetime.datetime(tomorrow.year, tomorrow.month, tomorrow.day)

        if errors is None:
            errors = []

        for repo in syncrepos:
            iso8601_start = format_iso8601_datetime(start)
            iso8601_interval = format_iso8601_interval(datetime.timedelta(seconds=synctime))
            logger.debug("Scheduling %s to start at %s, sync every %s" % (repo["id"], iso8601_start, iso8601_interval))
            schedule = parse_interval_schedule(iso8601_interval, iso8601_start, None)

            try:
                repoapi.change_sync_schedule(repo["id"], dict(schedule=schedule, options=dict()))
                reload_repo(repo["id"])
            except ServerRequestError, err:
                errors.append("Could not set schedule for %s: %s" % (repo["id"], err[1]))

            start += datetime.timedelta(seconds=int(pkgtime * repo["package_count"]))