예제 #1
0
 def test_cannot_recursively_use_context_manager(self):
     with thread_meeting.participate() as one:
         self.assertEqual("(primary)", one.name)
         with self.assertRaises(RuntimeError) as context:
             with thread_meeting.participate():
                 pass
         self.assertTrue("' already present" in str(context.exception),
                         str(context.exception))
 def test_transcribe_sees_attendee_enter_exit(self):
     with thread_meeting.transcriber() as transcriber:
         with thread_meeting.participate("Bilbo"):
             pass
         with thread_meeting.participate("Baggins"):
             pass
     expected = (TI('Transcript', TT.Enter), TI('Thread ID:', TT.Enter),
                 TI('Thread ID:', TT.Exit), TI('Thread ID:', TT.Enter),
                 TI('Thread ID:', TT.Exit), TI('Transcript', TT.Exit))
     self.verify_transcript_items(transcriber, *expected)
예제 #3
0
 def create_enter_exit_instance(self):
     """
     Since EnterExit objects can't be directly created,
     this helper function returns something that is
     an EnterExit object.
     """
     return thread_meeting.participate("Me")
 def test_transcribe_sees_baton_enter_exit(self):
     with thread_meeting.transcriber() as transcriber:
         with thread_meeting.participate("Bilbo") as bilbo:
             with bilbo.request_baton():
                 pass
     expected = (TI('Transcript', TT.Enter), TI('Thread ID:', TT.Enter),
                 TI('Baton', TT.Enter), TI('Baton', TT.Exit),
                 TI('Thread ID:', TT.Exit), TI('Transcript', TT.Exit))
     self.verify_transcript_items(transcriber, *expected)
예제 #5
0
 def hold_baton(data: dict):
     with thread_meeting.participate("hold_baton") as me:
         with me.request_baton() as baton:
             data['baton'] = baton
             data['state'] = 'baton'
             while data['state'] == 'baton':
                 time.sleep(0.1)
         data['state'] = 'done'
         while data['state'] == 'done':
             time.sleep(0.1)
예제 #6
0
    def thread_entry(self):
        """
        Thread entry point launched by start_all for each worker.
        """
        with thread_meeting.participate(
                self._requested_name) as self._attendee:
            self._fad = FuncAndData(self.on_idle)
            while self.state != WorkerState.FINAL:
                try:
                    # If we have any delayed messages to add to the queue,
                    # then add them (to the back).
                    self._check_for_delayed_messages()

                    # We're going to expand data as kwargs, so it must be
                    # in dict format... even if there's nothing in it.
                    data = self._fad.data if self._fad.data else dict()

                    # Don't log enter/exit for on_* functions in the base class
                    # if they are not overloaded, but do for everything else.
                    if self._fad.func in self._no_transcript_for:
                        func = self._fad.func
                    else:
                        func = transcribe_func(self, self._fad.func)

                    # Run the function and find out what the next function is.
                    if self._fad.data:
                        func_return = func(**data)
                    else:
                        func_return = func()

                    if callable(func_return):
                        # If the callee just returned the next function,
                        # there's no data.  Wrap it into a FuncAndData for them.
                        self._fad = FuncAndData(func_return)
                    elif isinstance(func_return, FuncAndData):
                        # The callee returned exactly what we want.
                        self._fad = func_return
                    elif func_return is None:
                        # No instructions.
                        state = self.state
                        if state == WorkerState.FINAL:
                            self._fad = None
                        elif bool(self._queue()):
                            # queue has items in it, we want to process next.
                            self._fad = FuncAndData(self.on_message)
                        else:
                            self._fad = FuncAndData(self.on_idle)
                    else:
                        raise RuntimeError(
                            "Illegal return value from function")

                except BaseException as e:
                    self._debug("Exception detected, thread FAILED")
                    raise
        return self.state
예제 #7
0
 def test_attendee_can_use_queue(self):
     with thread_meeting.participate("Bilbo"):
         # could have also use ... `as me` in the with statement.
         queue = thread_meeting.me().queue
         self.assertFalse(queue)
         thread_meeting.me().note("one", 1)
         self.assertTrue(queue)
         head = queue.get()
         self.assertFalse(queue)
         self.assertIsInstance(head, thread_meeting.Take)
         self.assertEqual(head.payload, 1)
         self.assertEqual(head.name, "one")
 def test_transcribe_sees_baton_enter_exit_with_exception(self):
     with thread_meeting.transcriber() as transcriber:
         with self.assertRaises(RuntimeError) as context:
             with thread_meeting.participate("Bilbo") as bilbo:
                 with bilbo.request_baton():
                     raise RuntimeError('this error is expected')
         self.assertTrue("this error is expected" in str(context.exception),
                         str(context.exception))
     expected = (TI('Transcript', TT.Enter), TI('Thread ID:', TT.Enter),
                 TI('Baton', TT.Enter), TI('Baton', TT.Exit),
                 TI('Thread ID:', TT.Exit), TI('Transcript', TT.Exit))
     self.verify_transcript_items(transcriber, *expected)
 def test_transcribe_sees_attendee_add_to_queue(self):
     with thread_meeting.transcriber() as transcriber:  # ENTER Transcript
         with thread_meeting.participate("Bilbo") as me:  # ENTER Bilbo
             me.note("Ring", "The One Ring")  # NOTE Ring
             me.note("Sword", "Sting")  # NOTE Sword
             me.queue.get().protest()  # NACK Ring
             # exit with scope here                       # EXIT Bilbo
         me.queue.get()  # ACK sword
         # exit with scope here                           # EXIT Transcript
     expected = (TI('Transcript', TT.Enter), TI('Thread ID:', TT.Enter),
                 TI('Ring', TT.Post), TI('Sword', TT.Post),
                 TI('Ring', TT.Nack), TI('Thread ID:', TT.Exit),
                 TI('Sword', TT.Ack), TI('Transcript', TT.Exit))
     self.verify_transcript_items(transcriber, *expected)
예제 #10
0
 def test_can_find_me_in_scope(self):
     with thread_meeting.participate("Bilbo") as bilbo:
         # Find bilbo through a function call.
         me = thread_meeting.me()
         self.assertEqual(me.name, bilbo.name)
         self.assertTrue(bilbo)
         self.assertTrue(me)
         # Ensure they are equivalent: get the baton with me.
         with me.request_baton() as baton:
             self.assertIsNotNone(baton)
     # Ensure that bilbo and me both went invalid when
     # we left the 'with' statement.
     self.assertFalse(bilbo)
     self.assertFalse(me)
     # And ensure that if I try to find me outside the with,
     # only None is returned.
     me = thread_meeting.me()
     self.assertIsNone(me)
예제 #11
0
 def test_attendee_cannot_get_baton_held_in_other_thread(self):
     data = dict(state='before')
     worker = threading.Thread(target=self.hold_baton, args=(data, ))
     worker.start()
     while data['state'] == 'before':
         time.sleep(0.1)
     with thread_meeting.participate("Bilbo") as me:
         # The worker should have the baton, we should not.
         with me.request_baton() as baton:
             self.assertIsNone(baton)
             self.assertTrue(data['baton'])
         data['state'] = 'after'
         while data['state'] == 'after':
             time.sleep(0.1)
         # Worker should have given up the baton, we can wait.
         self.assertFalse(data['baton'])
         with me.request_baton() as baton:
             self.assertIsNotNone(baton)
     # Tell the worker to quit, and wait on it.
     data['state'] = 'quit'
     worker.join()
예제 #12
0
 def test_attendee_name_will_default(self):
     with thread_meeting.participate() as attendee:
         self.assertEqual("(primary)", attendee.name)
예제 #13
0
 def test_attendee_can_get_baton_twice(self):
     with thread_meeting.participate("Bilbo") as me:
         with me.request_baton() as baton:
             self.assertIsNotNone(baton)
         with me.request_baton() as baton:
             self.assertIsNotNone(baton)
예제 #14
0
 def test_attendee_cannot_recursively_get_baton(self):
     with thread_meeting.participate("Bilbo") as me:
         with me.request_baton() as baton:
             self.assertIsNotNone(baton)
             with me.request_baton() as baton2:
                 self.assertIsNone(baton2)
예제 #15
0
 def test_attendee_cannot_change_name_in_meeting(self):
     with thread_meeting.participate("Bilbo") as one:
         with self.assertRaises(AttributeError) as context:
             one.name = "Baggins"
         self.assertTrue("can't set attribute" in str(context.exception),
                         str(context.exception))
예제 #16
0
 def test_attendee_can_change_names_while_gone(self):
     with thread_meeting.participate("Bilbo") as one:
         self.assertEqual(one.name, "Bilbo")
     with thread_meeting.participate("Baggins") as one:
         self.assertEqual(one.name, "Baggins")
예제 #17
0
 def test_attendee_can_leave_and_come_back(self):
     with thread_meeting.participate() as one:
         self.assertEqual("(primary)", one.name)
     with thread_meeting.participate() as two:
         self.assertEqual("(primary)", two.name)
예제 #18
0
 def test_attendee_knows_name(self):
     with thread_meeting.participate("Bilbo") as attendee:
         self.assertEqual("Bilbo", attendee.name)
예제 #19
0
 def test_can_create_attendee_indirectly(self):
     with thread_meeting.participate("Bilbo") as attendee:
         self.assertIsInstance(attendee, thread_meeting.Attendee)