Beispiel #1
0
 def test_timeout1(self):
     a1, a2, a3 = [SLJ(x) for x in (0.5, 0.6, 0.7)]
     a2.requires(a1)
     a3.requires(a2)
     sched = PureScheduler(a1, a2, a3, timeout=1)
     # should timeout in the middle of stage 2
     self.assertFalse(sched.run())
     sched.list()
Beispiel #2
0
 def test_sequence6(self):
     "adding a sequence"
     sched = PureScheduler()
     a1 = J(sl(0.1), label=1)
     a2 = J(sl(0.1), label=2)
     a3 = J(sl(0.1), label=3)
     sched.add(Seq(a1, a2, a3))
     self.assertTrue(sched.run())
Beispiel #3
0
 def test_creation_scheduler(self):
     sched = PureScheduler()
     s = Seq(J(sl(1)), J(sl(2)), scheduler=sched)
     J(sl(3), required=s, scheduler=sched)
     # make sure that jobs appended in the sequence
     # even later on are also added to the scheduler
     s.append(J(sl(.5)))
     self.assertEqual(len(sched.jobs), 4)
     self.assertTrue(sched.check_cycles())
     self.assertTrue(sched.run())
Beispiel #4
0
    def _test_exc_critical(self, verbose):

        print("verbose = {}".format(verbose))
        a1, a2 = SLJ(1), J(co_exception(0.5),
                           label='critical boom',
                           critical=True)
        sched = PureScheduler(a1, a2, verbose=verbose)
        self.assertFalse(sched.run())
        print(common_sep + 'debrief()')
        sched.debrief()
Beispiel #5
0
    def test_cycle(self):
        """a simple loop with 3 jobs - cannot handle that"""
        a1, a2, a3 = J(sl(1.1)), J(sl(1.2)), J(sl(1.3))
        a1.requires(a2)
        a2.requires(a3)
        a3.requires(a1)

        sched = PureScheduler(a1, a2, a3)

        # these lines seem to trigger a nasty message about a coro not being
        # waited
        self.assertFalse(sched.check_cycles())
Beispiel #6
0
 def test_sequence2(self):
     "a job and a sequence"
     a1 = J(sl(0.1), label=1)
     a2 = J(sl(0.1), label=2)
     a3 = J(sl(0.1), label=3)
     s = Seq(a2, a3, required=a1)
     sched = PureScheduler(a1, s)
     list_sep(sched, common_sep + "sequence2")
     self.assertEqual(len(a1.required), 0)
     self.assertEqual(len(a2.required), 1)
     self.assertEqual(len(a3.required), 1)
     self.assertTrue(check_required_types(sched, "test_sequence2"))
     self.assertTrue(sched.run())
Beispiel #7
0
    def test_forever2(self):
        async def tick(n):
            while True:
                print('tick {}'.format(n))
                await asyncio.sleep(n)

        a1 = J(sl(0.5), label="finite")
        a2 = J(tick(0.1), forever=True, label="forever")
        sched = PureScheduler(a1, a2)
        result = sched.run()
        self.assertEqual(result, True)
        self.assertEqual(a1.is_done(), True)
        self.assertEqual(a2.is_done(), False)
Beispiel #8
0
 def test_sequence3(self):
     "a sequence and a job"
     a1 = J(sl(0.1), label=1)
     a2 = J(sl(0.1), label=2)
     s = Seq(a1, a2)
     a3 = J(sl(0.1), label=3, required=s)
     sched = PureScheduler()
     sched.update((s, a3))
     list_sep(sched, common_sep + "sequence3")
     self.assertEqual(len(a1.required), 0)
     self.assertEqual(len(a2.required), 1)
     self.assertEqual(len(a3.required), 1)
     self.assertTrue(check_required_types(sched, "test_sequence3"))
     self.assertTrue(sched.run())
Beispiel #9
0
    def test_nesting1(self):
        """
        one main scheduler in sequence
        one job
        one subscheduler that runs 2 jobs in parallel
        one job
        """

        watch = Watch('test_nesting1')
        # sub-scheduler - total approx 1 s
        sub_sched = PureScheduler(watch=watch)
        Job(co_print_sleep(watch, 0.5, "sub short"), scheduler=sub_sched)
        Job(co_print_sleep(watch, 1, "sub longs"), scheduler=sub_sched)

        # main scheduler - total approx 2 s
        main_sched = PureScheduler(watch=watch)
        Sequence(
            Job(co_print_sleep(watch, 0.5, "main begin")),
            # this is where the subscheduler is merged
            Job(sub_sched.co_run(), label='subscheduler'),
            Job(co_print_sleep(watch, 0.5, "main end")),
            scheduler=main_sched)

        print("===== test_nesting1", "LIST with details")
        main_sched.list(details=True)
        ok = main_sched.run()
        self.assertTrue(ok)

        # allow for a small variation around 2s of course
        duration = watch.seconds()
        self.assertAlmostEqual(duration, 2, delta=0.05)
Beispiel #10
0
 def test_sequence4(self):
     "a sequence of 2 sequences"
     a1 = J(sl(0.1), label=1)
     a2 = J(sl(0.1), label=2)
     a3 = J(sl(0.1), label=3)
     a4 = J(sl(0.1), label=4)
     s1 = Seq(a1, a2)
     s2 = Seq(a3, a4)
     sched = PureScheduler(Seq(s1, s2))
     list_sep(sched, common_sep + "sequence4")
     self.assertEqual(len(a1.required), 0)
     self.assertEqual(len(a2.required), 1)
     self.assertEqual(len(a3.required), 1)
     self.assertEqual(len(a4.required), 1)
     self.assertTrue(check_required_types(sched, "test_sequence4"))
     self.assertTrue(sched.run())
Beispiel #11
0
    def __init__(self,
                 *jobs_or_sequences,
                 jobs_window=None,
                 timeout=None,
                 shutdown_timeout=1,
                 watch=None,
                 verbose=False,
                 **kwds):

        PureScheduler.__init__(self,
                               *jobs_or_sequences,
                               jobs_window=jobs_window,
                               timeout=timeout,
                               shutdown_timeout=shutdown_timeout,
                               watch=watch,
                               verbose=verbose)
        AbstractJob.__init__(self, **kwds)
Beispiel #12
0
 def test_forever1(self):
     a1, a2, t1 = SLJ(1), SLJ(1.5), TJ(.6)
     a2.requires(a1)
     sched = PureScheduler(a1, a2, t1)
     sched.list()
     self.assertTrue(sched.run())
     sched.list()
Beispiel #13
0
    def test_nesting2(self):
        """
        2 sub schedulers run in parallel while
        the third main one controls them both
        """
        watch = Watch('test_nesting2')
        # sub-scheduler - total approx 0.5 s
        sub2 = diamond_scheduler(watch,
                                 0.5,
                                 "SUB2",
                                 scheduler_class=PureScheduler)
        sub2.watch = watch
        # sub-scheduler - total approx 1 s
        sub3 = diamond_scheduler(watch,
                                 1,
                                 "SUB3",
                                 scheduler_class=PureScheduler)
        sub3.watch = watch

        # main scheduler - total approx
        # 0.5 + max(0.5, 1) + 0.5 = 2 s
        expected_duration = 2
        main_sched = PureScheduler(watch=watch)
        mainj1 = Job(co_print_sleep(watch, 0.5, "mainj1"),
                     label="mainj1",
                     scheduler=main_sched)
        mainj2 = Job(sub2.co_run(),
                     label="mainj2",
                     required=mainj1,
                     scheduler=main_sched)
        mainj3 = Job(sub3.co_run(),
                     label="mainj3",
                     required=mainj1,
                     scheduler=main_sched)
        Job(co_print_sleep(watch, 0.5, "mainj4"),
            label="mainj4",
            required=(mainj2, mainj3),
            scheduler=main_sched)

        ok = main_sched.run()
        self.assertTrue(ok)

        # allow for a small variation around 2s of course
        duration = watch.seconds()
        self.assertAlmostEqual(duration, expected_duration, delta=0.05)
Beispiel #14
0
    def test_graph1(self):

        watch = Watch()

        s = PureScheduler()
        s.add(
            Sequence(
                Job(co_print_sleep(watch, .25, 'begin')),
                Job(co_print_sleep(watch, 1., 'middle'), label='middle'),
                Job(co_print_sleep(watch, .25, 'end')),
            ))
        print("test_graph1 NO DETAILS")
        s.list()
        print("test_graph1 WITH DETAILS")
        s.list(details=True)
        print("GRAPH")
        self.assertEqual(len(s), 3)
        s.run()
        self.assertAlmostEqual(watch.seconds(), 1.5, delta=0.05)
        produce_png(s, "test_graph1")
Beispiel #15
0
 def test_timeout2(self):
     a1 = J(sl(1), label="a1")
     a2 = J(sl(2), label="a2")
     a3 = J(sl(10), label="a3")
     result = PureScheduler(a1, a2, a3, timeout=3).run()
     self.assertEqual(result, False)
     self.assertEqual(a1.is_done(), True)
     self.assertEqual(a1.result(), 1)
     self.assertEqual(a2.is_done(), True)
     self.assertEqual(a2.result(), 2)
     self.assertEqual(a3.is_done(), False)
Beispiel #16
0
 def test_sequence5(self):
     "sequences with required"
     a1 = J(sl(0.1), label=1)
     a2 = J(sl(0.1), label=2)
     a3 = J(sl(0.1), label=3)
     a4 = J(sl(0.1), label=4)
     a5 = J(sl(0.1), label=5)
     a6 = J(sl(0.1), label=6)
     s1 = Seq(a1, a2)
     s2 = Seq(a3, a4, required=s1)
     s3 = Seq(a5, a6, required=s2)
     sched = PureScheduler(s1, s2, s3)
     list_sep(sched, common_sep + "sequence5")
     self.assertEqual(len(a1.required), 0)
     self.assertEqual(len(a2.required), 1)
     self.assertEqual(len(a3.required), 1)
     self.assertEqual(len(a4.required), 1)
     self.assertEqual(len(a5.required), 1)
     self.assertEqual(len(a6.required), 1)
     self.assertTrue(check_required_types(sched, "test_sequence5"))
     self.assertTrue(sched.run())
Beispiel #17
0
    def _test_window(self, total, window):
        atom = .1
        tolerance = 8  # more or less % in terms of overall time
        s = PureScheduler(jobs_window=window)
        for i in range(1, total + 1):
            s.add(PrintJob("{}-th {}s job".format(i, atom), sleep=atom))
        beg = time.time()
        ok = s.run()
        ok or s.debrief(details=True)
        end = time.time()
        duration = end - beg

        # estimate global time
        # unwindowed: overall duration is atom
        # otherwise a multiple of it (assuming total = k*window)
        expected = atom if not window else (total / window) * atom
        print('overall expected {} - measured {}'.format(expected, duration))

        distortion = duration / expected
        time_ok = 1 - tolerance / 100 <= distortion <= 1 + tolerance / 100
        if not time_ok:
            print("_test_window - window = {} :"
                  "wrong execution time {} - not within {}% of {}".format(
                      window, end - beg, tolerance, expected))

        self.assertTrue(time_ok)
        self.assertTrue(ok)
Beispiel #18
0
    def test_graph2(self):
        class TextJob(Job):
            def __init__(self, text, *args, **kwds):
                self.text = text
                super().__init__(*args, **kwds)

            def text_label(self):
                return "[[TextJob {}]]".format(self.text[::-1])

            def details(self):
                return f"TextJob details say\n" \
                    f"that initial text was {self.text}"

        class GraphJob(Job):
            def __init__(self, graph, *args, **kwds):
                self.graph = graph
                super().__init__(*args, **kwds)

            def graph_label(self):
                return "[[GraphJob\n{}]]".format(self.graph[::-1])

            def details(self):
                return f"GraphJob details\nare even more verbose and say\n" \
                       f"that initial graph message\nwas {self.graph}"

        watch = Watch()
        s = PureScheduler()
        s.add(
            Sequence(
                TextJob('textjob-with',
                        co_print_sleep(watch, 0.1, 'textjob, no label ')),
                TextJob('textjob-without',
                        co_print_sleep(watch, 0.1, 'textjob, with label '),
                        label='TextLabel'),
                GraphJob('graphjob-with',
                         co_print_sleep(watch, 0.1, 'graphjob, no label ')),
                GraphJob('graphjob-without',
                         co_print_sleep(watch, 0.1, 'graphjob, with label '),
                         label='GraphLabel'),
            ))
        print("test_graph2 NO DETAILS")
        s.list()
        print("test_graph2 WITH DETAILS")
        s.list(details=True)
        print("GRAPH")
        self.assertEqual(len(s), 4)
        produce_png(s, "test_graph2")
Beispiel #19
0
 def _set_sched_id(self, start, id_format):
     """
     Works as a complicit to PureScheduler._set_sched_ids.
     It sets local the ``_sched_id`` attribute and returns the index
     for the next job.
     """
     # first set index on the current (kind of fake) node
     i = AbstractJob._set_sched_id(
         self,  # pylint: disable=w0212
         start,
         id_format)
     # go on with the jobs in sub scheduler
     return PureScheduler._set_sched_ids(
         self,  # pylint: disable=w0212
         i,
         id_format)
Beispiel #20
0
    def test_display(self):
        class FakeTask:
            def __init__(self):
                self._result = 0
                self._exception = None

        def annotate_job_with_fake_task(job, state, boom):
            task = FakeTask()
            if state == "done":
                task._state = asyncio.futures._FINISHED
                job._task = task
                job._running = True
            elif state == "running":
                task._state = "NONE"
                job._task = task
                job._running = True
            elif state == "scheduled":
                task._state = "NONE"
                job._task = task
                job._running = False
            else:
                pass

            # here we assume that a job that has raised an exception is
            # necessarily done
            if boom:
                if state in ("idle", "scheduled", "running"):
                    print("incompatible combination boom x idle - ignored")
                    return
                else:
                    job._task._exception = True
            return job

        class AJ(AbstractJob):
            pass

        sched = PureScheduler()
        previous = None
        for state in "idle", "scheduled", "running", "done":
            for boom in True, False:
                for critical in True, False:
                    for forever in True, False:
                        j = AJ(critical=critical,
                               forever=forever,
                               label="forever={} crit.={} status={} boom={}".
                               format(forever, critical, state, boom),
                               required=previous)
                        if annotate_job_with_fake_task(j, state, boom):
                            sched.add(j)
                            previous = j
        sched.list()
Beispiel #21
0
    def test_simple(self):
        """a simple topology, that should work"""
        jobs = SLJ(0.1), SLJ(0.2), SLJ(0.3), SLJ(0.4), SLJ(0.5), J(sl(0.6)), J(
            sl(0.7))
        a1, a2, a3, a4, a5, a6, a7 = jobs
        a4.requires(a1, a2, a3)
        a5.requires(a4)
        a6.requires(a4)
        a7.requires(a5)
        a7.requires(a6)

        sched = PureScheduler(*jobs)
        list_sep(sched, common_sep + "LIST BEFORE")
        self.assertTrue(sched.check_cycles())
        self.assertTrue(sched.run())
        for j in jobs:
            self.assertFalse(j.raised_exception())
        list_sep(sched, common_sep + "LIST AFTER")
        print(common_sep + "DEBRIEF")
        sched.debrief()
Beispiel #22
0
 def test_empty(self):  # pylint: disable=r0201
     s = PureScheduler()
     s.list()
     s.list(details=True)
     self.assertTrue(s.run())
Beispiel #23
0
    def test_nesting3(self):
        """
        same as test_nesting2
        but using a Scheduler instance
        2 sub schedulers run in parallel while
        the third main one controls them both
        """

        # main scheduler - total approx
        # 0.5 + max(0.5, 1) + 0.5 = 2 s
        expected_duration = 2

        watch = Watch('test_nesting3')
        main_sched = PureScheduler(verbose=True, watch=watch)
        main_sched.label = "main3"
        mainj1 = Job(co_print_sleep(watch, 0.5, "mainj1"),
                     label="mainj1",
                     scheduler=main_sched)

        # sub-scheduler 2 - total approx 0.5 s
        sub_sched2 = diamond_scheduler(watch, 0.5, "SUB2")
        main_sched.add(sub_sched2)
        sub_sched2.requires(mainj1)
        sub_sched2.label = "sub_sched2"
        sub_sched2.verbose = True

        # sub-scheduler 3 - total approx 1 s
        sub_sched3 = diamond_scheduler(watch, 1, "SUB3")
        main_sched.add(sub_sched3)
        sub_sched3.requires(mainj1)
        sub_sched3.label = "sub_sched3"
        sub_sched3.verbose = True

        # last job in main scheduler
        Job(co_print_sleep(watch, 0.5, "mainj4"),
            label="mainj4",
            required=(sub_sched2, sub_sched3),
            scheduler=main_sched)

        for s in main_sched, sub_sched2, sub_sched3:
            if not s.sanitize():
                print(f"OOPS, had to sanitize sched {s.label}")

        print("===== test_nesting3", "LIST without details")
        main_sched.list(details=False)
        produce_png(main_sched, "test_nesting3")

        watch.reset()
        print("---run")
        ok = main_sched.run()
        if not ok:
            main_sched.debrief()
        self.assertTrue(ok)

        # allow for a small variation around 2s of course
        duration = watch.seconds()
        self.assertAlmostEqual(duration, expected_duration, delta=0.05)
Beispiel #24
0
 def test_seq(self):
     s = PureScheduler()
     Seq(J(sl(.1)), J(sl(.2)), scheduler=s)
     self.assertTrue(s.run())