def startup(self):
     # asys1 is the main Actor System the tests will interact with
     self.asys1 = ActorSystem('multiprocTCPBase',
                              capabilities={'dog':'food',
                                            'Admin Port': 11192 + self.baseport},
                              logDefs = simpleActorTestLogging(),
                              transientUnique = True)
     # asys2 is a different Actor System that is initially
     # independent, but can support a Horse Actor.
     self.asys2 = ActorSystem('multiprocTCPBase',
                              capabilities={'barn': 'oats',
                                            'Admin Port': 11193 + self.baseport},
                              logDefs = simpleActorTestLogging(),
                              transientUnique = True)
    def setUp(self):
        self.systems = {}

        # Start sub-processes before primary ActorSystem so that the
        # latter is not duplicated in each sub-process.

        child_conn, parent_conn = Pipe()
        child = Process(target=DagobahSystem, args=(child_conn, self.actorSystemBase))
        child.start()
        self.systems['Dagobah'] = (parent_conn, child)

        child_conn, parent_conn = Pipe()
        child = Process(target=HothSystem, args=(child_conn, self.actorSystemBase))
        child.start()
        self.systems['Hoth'] = (parent_conn, child)

        child_conn, parent_conn = Pipe()
        child = Process(target=EndorSystem, args=(child_conn, self.actorSystemBase))
        child.start()
        self.systems['Endor'] = (parent_conn, child)

        child_conn, parent_conn = Pipe()
        child = Process(target=NabooSystem, args=(child_conn, self.actorSystemBase))
        child.start()
        self.systems['Naboo'] = (parent_conn, child)

        ActorSystem(self.actorSystemBase, {'Jedi Council': True,
                                           'Admin Port': 12121},
                    logDefs = simpleActorTestLogging())

        for each in self.systems:
            self.systems[each][0].send('Start now please')
        sleep(1)  # allow all Systems to startup
def remoteSystem(conn, systembase, adminPort, systemCapabilities):
    # shutdown anything still running
    ActorSystem(logDefs = simpleActorTestLogging()).shutdown()

    conn.recv()  # wait for startup indication from parent

    # Setup capabilities with defaults overridded by passed-in specifications
    caps = {}
    caps.update({ 'Admin Port': adminPort,
                  'Convention Address.IPv4': ('', 12121),
              })
    caps.update(systemCapabilities)
    ActorSystem(systembase, caps,
                logDefs = simpleActorTestLogging())
    if 'DeathStar' != conn.recv():  # wait for shutdown indication from parent
        ActorSystem().shutdown()
    conn.close()
    return False
def System2(conn, base, capabilities):
    ActorSystem().shutdown()  # shutdown anything still running
    sleep(0.05)  # give ConventionLeader in main process time to startup
    ActorSystem(base,
                capabilities,
                logDefs = simpleActorTestLogging())
    conn.recv()  # wait for shutdown indication from parent
    ActorSystem().shutdown()
    conn.close()
 def startSystems(self, portOffset):
     # Only define base capabilities, not extended capabilities
     self.capabilities = { 'One': { 'Admin Port': 19001 + portOffset + self.basePortOffset, },
                           'Two': { 'Admin Port': 19002 + portOffset + self.basePortOffset,
                                    'Convention Address.IPv4': ('', 19001 + portOffset + self.basePortOffset), },
                           'Three': { 'Admin Port': 19003 + portOffset + self.basePortOffset,
                                      'Convention Address.IPv4': ('', 19001 + portOffset + self.basePortOffset), },
                       }
     for each in ['One', 'Two', 'Three']:  # 'One' must be first
         self.systems[each] = ActorSystem(self.actorSystemBase, self.capabilities[each],
                                          logDefs = simpleActorTestLogging(),
                                          transientUnique = True)
     time.sleep(0.25)  # Wait for Actor Systems to start
    def startSystems(self, portOffset):
        system1Port = 43000 + self.portBase + portOffset
        system2Port = 42000 + self.portBase + portOffset
        self.system1Caps = {'dog':'food',
                            'Admin Port': system1Port,
                            #'Convention Address': not specified, but is the leader anyhow
        }

        self.parent_conn, child_conn = Pipe()
        self.child = Process(target=System2,
                             args=(child_conn,
                                   self.baseName,
                                   { 'Admin Port': system2Port,
                                     'Convention Address.IPv4': ('localhost:%d'%system1Port),
                                     'Humanitarian': True,
                                     'Adoption': True},
                               ))
        self.child.start()
        ActorSystem(self.baseName,
                    capabilities = self.system1Caps,
                    logDefs = simpleActorTestLogging())
        sleep(0.15)  # allow System2 to start and join the Convention
    def startSystems(self, portOffset):
        system1Port = 43000 + self.portBase + portOffset
        system2Port = 42000 + self.portBase + portOffset
        self.system1Caps = {'dog':'food',
                            'Admin Port': system1Port,
                            #'Convention Address': not specified, but is the leader anyhow
        }
        self.system1Caps.update(getattr(self, 'extra_capabilities', {}))
        if getattr(self, 'leaderTXOnly', False):
            self.system1Caps['Outbound Only'] = True

        self.system2Caps = { 'Admin Port': system2Port,
                             'Humanitarian': True,
                             'Adoption': True}
        self.system2Caps.update(getattr(self, 'extra_capabilities', {}))
        if not getattr(self, 'leaderTXOnly', False):
            self.system2Caps['Convention Address.IPv4'] = 'localhost:%d'%system1Port

        self.parent_conn, child_conn = Pipe()
        self.child = Process(target=System2,
                             args=(child_conn,
                                   self.baseName,
                                   self.system2Caps,
                               ))
        self.child.start()
        ActorSystem(self.baseName,
                    capabilities = self.system1Caps,
                    logDefs = simpleActorTestLogging())
        sleep(0.15)  # allow System2 to start and join the Convention

        if getattr(self, 'leaderTXOnly', False):
            self.assertEqual('Registered',
                             ActorSystem().ask(ActorSystem().createActor(PreRegActor),
                                               'localhost:%d'%system2Port,
                                               timedelta(seconds=3)))
            sleep(0.25)  # allow System2 to start and join the Convention
    def testNotifications(self):

        systems = {}

        try:

            # Start sub-processes before ActorSystem so that the
            # ActorSystem doesn't get duplicated in all the
            # sub-processes.  The sub-processes will wait for a
            # startup message from this process before creating their
            # ActorSystems.

            parent_conn1, child_conn1 = Pipe()
            child1 = Process(target=DagobahSystem, args=(child_conn1, self.actorSystemBase))
            child1.start()
            systems['Dagobah'] = (parent_conn1, child1)

            parent_conn1, child_conn1 = Pipe()
            child1 = Process(target=EndorSystem, args=(child_conn1, self.actorSystemBase))
            child1.start()
            systems['Endor'] = (parent_conn1, child1)

            # Start the Primary ActorSystem and an Actor that
            # registers for Convention entry/exit from other
            # ActorSystems.

            ActorSystem(self.actorSystemBase, {'Jedi Council': True,
                                               'Admin Port': 12121},
                        logDefs =  simpleActorTestLogging())

            watcher = ActorSystem().createActor(Notified)
            ActorSystem().tell(watcher, 'register')
            sleep(0.2)  # wait for watcher to register

            # Now start each of the secondary ActorSystems; their
            # registration should be noted by the Actor registered for
            # such notifications.

            for each in systems:
                systems[each][0].send('Start now please')

            # Verify all anticipated registrations actually occurred.

            for X in range(50):
                registrations = ActorSystem().ask(watcher, 'notifications', 1).split('&')
                print(registrations)
                if 2 == len(registrations):
                    break
                sleep(0.01)    # wait for systems to startup and register
            self.assertEqual(2, len(registrations))

            # Now there are 3 actor Systems:
            #    Jedi Council (convention leader)
            #    Endor (Trees)
            #    Dagobah (Swamp)
            # Create some Actors:
            #    Yoda (from Primary, created in system Dagobah)
            #       ObiWan  (from Yoda, through Jedi Council to system Endor)
            #       Luke    (from Yoda, but cannot start this anywhere)
            # Verify that ObiWan starts and stays started, but that Luke "starts" and subsequently exits.

            yoda = ActorSystem().createActor(Yoda)
            self.assertEqual('Use the Force, you must, to train', ActorSystem().ask(yoda, 'train', 2))
            self.assertEqual( (0,0), ActorSystem().ask(yoda, 'Training Completed?', 2))
            ActorSystem().tell(yoda, 'Obi Wan')
            ActorSystem().tell(yoda, 'Padawan')
            sleep(0.25)  # allow time for Yoda to fail training a young Padawan
            self.assertEqual( (2,1), ActorSystem().ask(yoda, 'Training Completed?', 2))

            # Now ask an ActorSystem to exit.  This is the ActorSystem
            # where Obi Wan is, so that will cause Obi Wan to go away
            # as well.

            systems['Endor'][0].send('Please exit nicely')
            del systems['Endor']

            # KWQ: how to get Endor to abruptly exit without shutting
            # down ObiWan first so that Dagobah system cleanup can
            # tell Yoda that ObiWan is gone.

            # Verify that the convention deregistration occurred

            for X in range(60):
                registrations2 = ActorSystem().ask(watcher, 'notifications', 1).split('&')
                print(str(registrations2))
                if 3 == len(registrations2):
                    break
                sleep(0.01)  # wait for Endor system to exit and deregister
            self.assertEqual(3, len(registrations2))

            outs = [X for X in registrations2 if X.startswith('OUT')]
            self.assertEqual(1, len(outs))

            # Verify that destroying the Endor system shutdown all Actors within it
            self.assertEqual( (2,2), ActorSystem().ask(yoda, 'Training Completed?', 2))

        finally:
            for system in systems:
                systems[system][0].send('OK, all done')
            sleep(0.3)  # allow other actorsystems (non-convention-leaders) to exit
            ActorSystem().shutdown()
    def testNotifications(self):

        systems = {}

        try:

            # Start sub-processes before ActorSystem so that the
            # ActorSystem doesn't get duplicated in all the
            # sub-processes.  The sub-processes will wait for a
            # startup message from this process before creating their
            # ActorSystems.

            parent_conn1, child_conn1 = Pipe()
            child1 = Process(target=DagobahSystem, args=(child_conn1, self.actorSystemBase))
            child1.start()
            systems['Dagobah'] = (parent_conn1, child1)

            child_conn2, parent_conn2 = Pipe()
            child2 = Process(target=HothSystem, args=(child_conn2, self.actorSystemBase))
            child2.start()
            systems['Hoth'] = (parent_conn2, child2)

            child_conn3, parent_conn3 = Pipe()
            child3 = Process(target=EndorSystem, args=(child_conn3, self.actorSystemBase))
            child3.start()
            systems['Endor'] = (parent_conn3, child3)

            child_conn4, parent_conn4 = Pipe()
            child4 = Process(target=NabooSystem, args=(child_conn4, self.actorSystemBase))
            child4.start()
            systems['Naboo'] = (parent_conn4, child4)

            # Start the Primary ActorSystem and an Actor that
            # registers for Convention entry/exit from other
            # ActorSystems.

            ActorSystem(self.actorSystemBase, {'Jedi Council': True,
                                               'Admin Port': 12121},
                        logDefs =  simpleActorTestLogging())

            watcher = ActorSystem().createActor(Notified)
            ActorSystem().tell(watcher, 'register')
            sleep(0.10)  # wait for watcher to register

            # Now start each of the secondary ActorSystems; their
            # registration should be noted by the Actor registered for
            # such notifications.

            for each in systems:
                systems[each][0].send('Start now please')

            # Verify all anticipated registrations actually occurred.

            for X in range(30):
                registrations = ActorSystem().ask(watcher, 'notifications', 1).split('&')
                print(registrations)
                if 4 == len(registrations):
                    break
                sleep(0.01)  # wait for more registrations to complete
            self.assertEqual(4, len(registrations))

            # Now ask an ActorSystem to exit

            systems['Hoth'][0].send('OK, all done')
            del systems['Hoth']

            # Verify that the convention deregistration occurred

            for X in range(30):
                registrations2 = ActorSystem().ask(watcher, 'notifications', 1).split('&')
                if 5 == len(registrations2):
                    break
                sleep(0.01)  # wait for Hoth system to exit and deregister
            self.assertEqual(5, len(registrations2))

            outs = [X for X in registrations2 if X.startswith('OUT')]
            self.assertEqual(1, len(outs))

        finally:
            for system in systems:
                systems[system][0].send('OK, all done')
            sleep(0.1)  # allow other actorsystems (non-convention-leaders) to exit
            ActorSystem().shutdown()
 def setUp(self):
     ActorSystem('multiprocUDPBase',
                 capabilities={'dog':'food'},
                 logDefs = simpleActorTestLogging())
 def setUp(self):
     caps = {'dog':'food'}
     caps.update(getattr(self, 'extra_capabilities', {}))
     ActorSystem('multiprocTCPBase', capabilities=caps,
                 logDefs = simpleActorTestLogging())