def t22(HOME): pretty = '%s t22' % __file__ print(pretty) ave.config.create_default(HOME.path) path = os.path.join(HOME.path, '.ave', 'config', 'broker.json') with open(path, 'w') as f: json.dump({'logging': False}, f) sock, port = find_free_port() b = Broker(socket=sock, authkeys={'admin': 'key'}, home=HOME.path) b.start() r = RemoteBroker(('', port), home=HOME.path) try: r.stop() print('FAIL %s: stop() did not fail' % pretty) b.join() return False except Exception, e: if 'not authorized to make this call' not in str(e): print('FAIL %s: wrong error message: %s' % (pretty, str(e))) b.terminate() b.join() return False
def make_lister(self, timeout, logging): sock, port = find_free_port(listen=False) c = BlockingConnection(('', port), sock) l = DevantechRelayLister(port, None, timeout, logging) l.start() self.processes.append(l) return c
def t7(h1, h2): pretty = '%s t7' % __file__ print(pretty) # start a mocked broker to receive updates from the lister pipe = Pipe() sock, port = find_free_port() broker = MockBroker(port, sock, pipe) lister = HandsetLister(port, None, [], False) # filter out all paths broker.start() lister.start() def stop(): broker.terminate() lister.terminate() broker.join() lister.join() try: profile = pipe.get(timeout=3) print('FAIL %s: unfiltered profile seen: %s' % (pretty, profile)) stop() return False except ConnectionTimeout: pass # good stop() return True
def connect(self): AdbForward.check_global_limits() # find a free port that isn't already forwarded and pass it to ADB attempts = 0 # retry until a local port has been bound. redundant calls to connect() # have no effect because .local will be set the first time. while self.local == None: sock,port = find_free_port() # must close the associated socket before giving the port number to # ADB. it would be nice if ADB could to passed the open socket or # had an option to find a free port itself or whatever. yay! race # conditions! sock.shutdown(socket.SHUT_RDWR) sock.close() cmd = ['-s', self.serial, 'forward', 'tcp:%d' % port, self.remote] s,o = run_adb(cmd) if s == 0: self.local = 'tcp:%d' % port break if attempts >= 10: o = o.splitlines()[0] raise Exception('could not set up port forwarding: %s' % o) return self.local
def make_panotti_server(self, home): sock,port = find_free_port() c = PanottiControl(port, sock, home=home) r = RemoteControl(('',port), None, 1) c.start() self.processes.append(c) return r
def make_slave(master_address, prefix, HOME): sock, port = find_free_port() handsets = setup.make_handsets(prefix) config = { 'host': '', 'port': master_address[1], 'policy': 'share', 'authkey': u'share_key' } ws_cfg = { 'root': os.path.join(HOME.path, prefix), 'env': [], 'tools': {}, 'pretty': prefix } broker = setup.MockBroker(('', port), sock, config, handsets, [], [], None, ws_cfg, None, None, [], True, home=HOME.path) remote = setup.RemoteSlaveBroker(address=('', port), authkey='admin_key', home=HOME.path) return broker, remote
def make_control(self, home=None, authkey=None, max_tx=-1, timeout=1): sock,port = find_free_port() c = MockControl(port, authkey, sock, home=home, max_tx=max_tx) r = RemoteControl(('',port), None, timeout, home=home) c.start() self.processes.append(c) return r
def make_proxy(self, target): sock,port = find_free_port() c = MockControl(port, None, sock, proxee=target) r = RemoteControl(('',port), None, 1) c.start() self.processes.append(c) return r
def mock_death(self): # try to keep Control sockets open after process death by spawning a # subprocess and then commit suicide, using SIGKILL. the observable # behavior (when this works) is that the call to mock_death() never # returns to the client because no answer is sent (the process is dead) # while its open sockets keep lingering (is this due to a GC detail in # Python that keeps sockets open as long as a child process is still # around?). from the client's point of view, the call to mock_death # hangs indefinitely. # TODO: there is a race condition if the subprocess has not been fully # started when the parent gets SIGKILL'ed. should try to remove the call # to sync_ping(). however, this should not be a problem in real life # because all processes except the root broker process are governed by # their parents, which never receive SIGKILL. only the broker will ever # get SIGKILL'ed, and even that should never happen in real deployment. # a simple protection against that eventuality would be to respawn it # immediately on startup and register the spawn for PDEATHSIG, before # it starts accepting client connections, so that everything after this # point is guaranteed to be insulated from the race condition. sock, port = find_free_port() c = MockControl(port, 'authkey', sock) c.start() r = RemoteControl(('',port), 'authkey', timeout=5) try: r.connect(2) except Exception, e: traceback.print_exc() os.kill(self.pid, signal.SIGKILL) # suicide! return
def t6(pretty, HOME): sock, port = find_free_port() sock.shutdown( socket.SHUT_RDWR) # close the socket since it can't be passed sock.close() # to ADB (which would have been very nice). config = {'port': port, 'persist': True, 'demote': False, 'logging': False} def concurrent(home, config): srv = AdbServer(home, config) srv.run() p = Process(target=concurrent, args=(HOME.path, config)) p.start() seen = [] for i in range(5): # find the current server pid = find_one_server_process(port, 4) if pid in seen: print('FAIL %s: pid %d was seen before: %s' % (pretty, pid, seen)) p.terminate() p.join() return False seen.append(pid) # kill the current server. expect the next step in the loop to find a # new one in its place AdbServer.kill_all_servers(port) p.terminate() p.join() return True
def t5(pretty, HOME): sock, port = find_free_port() sock.shutdown( socket.SHUT_RDWR) # close the socket since it can't be passed sock.close() # to ADB (which would have been very nice). config = { 'port': port, 'persist': False, 'demote': False, 'logging': False } def concurrent(home, config): srv = AdbServer(home, config) srv.run() p = Process(target=concurrent, args=(HOME.path, config)) p.start() try: find_one_server_process(port, 2) except Exception, e: print('FAIL %s: %s' % (pretty, e)) p.terminate() p.join() return False
def spawn(self): if not self.children: self.children = [] sock, port = find_free_port() d = Defiant(port, None, sock) d.start() self.children.append(d) return [d.pid, port]
def make_broker(self): sock, port = find_free_port() self.write_config('broker.json', {'port': port, 'logging': False}) broker = self._make_broker(sock, port) broker.start() remote = RemoteBroker(('', port), 5, 'admin', self.HOME.path) self.processes.append(broker) return remote
def t9(h1, h2): pretty = '%s t9' % __file__ print(pretty) p1 = h1.get_profile()['sysfs_path'] p2 = h2.get_profile()['sysfs_path'] # start a mocked broker to receive updates from the lister pipe = Pipe() sock, port = find_free_port() broker = MockBroker(port, sock, pipe) lister = HandsetLister(port, None, [p1], False) # only filter one handset broker.start() lister.start() def stop(): broker.terminate() lister.terminate() broker.join() lister.join() # reboot the handsets h1.reboot() h2.reboot() h1.wait_power_state('boot_completed', timeout=120) h2.wait_power_state('boot_completed', timeout=120) # give the lister a couple of seconds to report to the broker (the handset # makes a call by itself to the lister class, not waiting for the lister to # report state which may cause a situation where the handset's "wait power # state" is done but the broker has not yet been notified) time.sleep(3) # check that various power states were reported by the lister for the # filtered handset seen = [] while True: try: profile = pipe.get(False) if profile['sysfs_path'] != p1: print('FAIL %s: wrong profile added: %s' % (pretty, profile)) stop() return False seen.append(profile['power_state']) except ConnectionTimeout: break if 'offline' not in seen: print('FAIL %s: offline state not reported: %s' % (pretty, seen)) stop() return False if 'boot_completed' not in seen: print('FAIL %s: boot_completed state not reported: %s' % (pretty, seen)) stop() return False stop() return True
def t15(factory): pretty = '%s t15' % __file__ print(pretty) ws_config = { 'root' : factory.HOME.path, 'env' : [], 'tools' : {}, 'flocker': { "ftp": { "password": "******", "store": "/srv/www/flocker", "port": 21, "timeout": 30, "user": "******" }, "host": "cnbjlx20050", "enable" : True, "http": { "doc-root": "/srv/www", "port": 80 } } } factory.write_config('workspace.json', json.dumps(ws_config)) sock, port = find_free_port() # set remote explicitly to avoid reading config from disk broker = Broker( ('',port), sock, remote={}, authkeys={'admin':None}, hsl_paths=[], home=factory.HOME.path ) broker.start() proc = psutil.Process(broker.pid) remote = RemoteBroker(address=('',port), home=factory.HOME.path) l = remote.list_available() # just to make sure the connection is up del remote # client disconnects itself # check the CPU utilization of the broker through it's PID result = True for i in range(10): if 'get_cpu_percent' in dir(proc): load = proc.get_cpu_percent() * psutil.NUM_CPUS else: load = proc.cpu_percent() * psutil.cpu_count() if load > 90.0: print('FAIL %s: runaway CPU load: %f' % (pretty, load)) result = False break time.sleep(0.3) broker.terminate() broker.join() return result
def t5(pretty, factory): factory.write_config('authkeys.json', setup.AUTHKEYS) broker = factory.make_broker() sock,port = find_free_port() factory.write_config('relay.json', {'port':port, 'logging':False}) try: s = RelayServer(factory.HOME.path, None, None, sock) except Exception, e: print('could not create server: %s' % (pretty, e)) return False
def t2(pretty, factory): class Defiant(Process): def handle_SIGTERM(self, signum, frame): time.sleep(5) # very poor behavior Process.handle_SIGTERM(self, signum, frame) def run(self): while True: time.sleep(1) class Spawner(Control): @Control.rpc def spawn(self): pids = [] for i in range(500): d = Defiant() d.start() self.join_later(d) pids.append(d.pid) return pids @Control.rpc def list_orphans(self): return [p._pid for p in self.deferred_joins] sock, port = find_free_port() spawner = Spawner(port, None, sock) spawner.start() factory.processes.append(spawner) master = RemoteControl(('', port), None, 5) defiers = master.spawn() for pid in defiers: os.kill(pid, signal.SIGTERM) orphans = master.list_orphans() if len(orphans) != 500: print('FAIL %s: there are not 500 orphans: %s' % (pretty, orphans)) return False for pid in defiers: os.kill(pid, signal.SIGKILL) for i in range(10): orphans = master.list_orphans() if not orphans: break time.sleep(0.3) if orphans: print('FAIL %s: some orphans survived: %d' % (pretty, len(orphans))) return False return True
def make_control(self): from ave.network.control import Control, RemoteControl class MockControl(Control): @Control.rpc def stop(self): Control.stop(self) sock, port = find_free_port() server = MockControl(port, 'admin', sock, {}, 1, self.HOME.path) remote = RemoteControl(('', port), 'admin', 2) server.start() self.processes.append(server) return remote
def make_server(self, inherited=None, make_socket=True): if make_socket: sock, port = find_free_port() config = {'port': port, 'logging': False} self.write_config('relay.json', config) server = MockServer(self.HOME.path, config, inherited, sock) remote = RemoteRelayServer(('', port), 'admin', home=self.HOME.path) else: # rely on configuration file in HOME server = MockServer(self.HOME.path, None, inherited) remote = RemoteRelayServer(None, 'admin', home=self.HOME.path) server.start() self.processes.append(server) return remote
def t1(pretty, HOME): # need a free port number or the server will exit immediately sock, port = find_free_port() sock.shutdown( socket.SHUT_RDWR) # close the socket since it can't be passed sock.close() # to ADB (which would have been very nice). cmd = ['/usr/bin/adb', '-P', str(port), 'start-server'] os.system(' '.join(cmd)) try: find_one_server_process(port, 10) except Exception, e: if 'did not find the server process' in str(e): print('FAIL %s: can not start adb server' % pretty) return False else: print('FAIL %s: unexpected exception: %s' % (pretty, str(e))) return False
def t1(factory): pretty = '%s t1' % __file__ print(pretty) sock, port = find_free_port() sock.shutdown(socket.SHUT_RDWR) sock.close() for i in range(10): try: broker = Broker(('',port), home=factory.HOME.path) broker.start() remote = RemoteBroker(('',port), 5, 'admin_key', factory.HOME.path) remote.stop(__async__=True) broker.join() except Exception, e: print('FAIL %s: stopping broker %d failed: %s' % (pretty,i,str(e))) return False
def t8(h1, h2): pretty = '%s t8' % __file__ print(pretty) p1 = h1.get_profile()['sysfs_path'] p2 = h2.get_profile()['sysfs_path'] # start a mocked broker to receive updates from the lister pipe = Pipe() sock, port = find_free_port() broker = MockBroker(port, sock, pipe) lister = HandsetLister(port, None, None, False) # filter in all paths broker.start() lister.start() def stop(): broker.terminate() lister.terminate() broker.join() lister.join() found = False seen = [] while True: try: seen.append(pipe.get(timeout=3)['sysfs_path']) if p1 in seen and p2 in seen: found = True break except ConnectionTimeout: break if not found: print('FAIL %s: filtered profile not seen' % pretty) stop() return False stop() return True
def t23(HOME): pretty = '%s t23' % __file__ print(pretty) ave.config.create_default(HOME.path) path = os.path.join(HOME.path, '.ave', 'config', 'broker.json') with open(path, 'w') as f: json.dump({'logging': False}, f) sock, port = find_free_port() b = Broker(socket=sock, authkeys={'admin': 'key'}, home=HOME.path) b.start() r = RemoteBroker(('', port), authkey='key', home=HOME.path) try: r.stop() except ConnectionClosed: pass # good except Exception, e: print('FAIL %s: admin authkey not accepted: %s' % (pretty, str(e))) b.terminate() b.join() return False
def t6(h1, h2): pretty = '%s t6' % __file__ print(pretty) p1 = h1.get_profile()['sysfs_path'] p2 = h2.get_profile()['sysfs_path'] # start a mocked broker to receive updates from the lister pipe = Pipe() sock, port = find_free_port() broker = MockBroker(port, sock, pipe) lister = HandsetLister(port, None, [p1, p2], False) broker.start() lister.start() def stop(): broker.terminate() lister.terminate() broker.join() lister.join() seen = [] try: seen.append(pipe.get(timeout=3)) except ConnectionTimeout: print('FAIL %s: filtered profile not seen' % pretty) stop() return False for s in seen: if s['sysfs_path'] not in [p1, p2]: print('FAIL %s: wrong path: %s' % (pretty, s['sysfs_path'])) stop() return False stop() return True
def make_child(self): sock, port = find_free_port() child = MockControl(port, None, sock, home=self.home) child.start() return port, child.pid
def t3(pretty, factory): class Defiant(Process): def run(self): while True: time.sleep(1) class Spawner(Control): def __init__(self, port, sock, not_a_child): Control.__init__(self, port, None, sock, logging=False) self.deferred_joins = [not_a_child] def run(self): self.join_later(not_a_child) Control.run(self) @Control.rpc def spawn(self): pids = [] for i in range(5): d = Defiant() d.start() self.join_later(d) self.join_later(d) # add twice pids.append(d.pid) return pids @Control.rpc def stillbirth(self): for i in range(5): d = Defiant() self.join_later(d) # forgot to start @Control.rpc def list_orphans(self): return [p._pid for p in self.deferred_joins] not_a_child = Defiant() not_a_child.start() sock, port = find_free_port() spawner = Spawner(port, sock, not_a_child) spawner.start() factory.processes.append(spawner) master = RemoteControl(('', port), None, 5) master.stillbirth() defiers = master.spawn() orphans = master.list_orphans() # by now the deferred join should already have weeded out the impossible # processes and discarded them. that leaves the 5 double adds (10 procs). if len(orphans) != 10: print('FAIL %s: there are not 10 orphans: %s' % (pretty, orphans)) return False for pid in defiers: os.kill(pid, signal.SIGTERM) for i in range(10): orphans = master.list_orphans() if not orphans: break time.sleep(0.3) if orphans: print('FAIL %s: some orphans survived: %d' % (pretty, len(orphans))) return False return True
def __init__(self): sock,port = find_free_port() Control.__init__(self, port, None, sock, logging=True, interval=1)
def t1(pretty, factory): class Defiant(Control): def handle_SIGTERM(self, signum, frame): pass # go on living @Control.rpc def ping(self): return 'pong', self.pid @Control.rpc def stop(self): Control.stop(self) class Spawner(Control): children = None @Control.rpc def spawn(self): if not self.children: self.children = [] sock, port = find_free_port() d = Defiant(port, None, sock) d.start() self.children.append(d) return [d.pid, port] @Control.rpc def orphanize(self): if not self.children: return None child, self.children = self.children[0], self.children[1:] child.terminate() self.join_later(child) @Control.rpc def list_orphans(self): return [p.pid for p in self.deferred_joins] sock, port = find_free_port() spawner = Spawner(port, None, sock) spawner.start() factory.processes.append(spawner) master = RemoteControl(('', port), None, 1) defiers = [] for i in range(5): pid, port = master.spawn() remote = RemoteControl(('', port), None, 5) defiers.append(remote) orphans = master.list_orphans() if orphans: print('FAIL %s: there are orphans: %s' % (pretty, orphans)) return False for i in range(5): master.orphanize() orphans = master.list_orphans() if len(orphans) != 5: print('FAIL %s: there are not 5 orphans: %s' % (pretty, orphans)) return False for remote in defiers: try: remote.ping() except Exception, e: print('FAIL %s: orphan died too soon: %s' % (pretty, remote)) return False remote.stop(__async__=True)