def start(self): if self.get_pid(): raise Exception('pid file %s exist' % self.pid_path) Process.start(self, daemonize=True, synchronize=True) self.set_pid(self.pid) return self.get_pid()
def __init__(self, host=None, port=0, user=None, pipe=None, mailbox=None, home=None): if not home: self.home = ave.config.load_etc()['home'] else: self.home = home # load the default configuration file config = ave.gerrit.config.load(self.home) # override configuration file entries if host is not None: config['host'] = host if port != 0: config['port'] = port if user is not None: config['user'] = user if pipe and type(pipe) != Pipe: raise Exception('pipe must be an ave.networking.pipe.Pipe') if mailbox and (type(mailbox) != tuple or len(mailbox) != 2): raise Exception('mailbox must be a (host,port) tuple') # validate the final configuration ave.gerrit.config.validate(config) self.config = config self.pipe = pipe if mailbox: self.mailbox = RemoteControl(mailbox, None, None) # superclass initialization Process.__init__(self, target=self._run, proc_name='ave-gerrit-event-stream')
def __init__(self, pid_path, log_file, stdin=None,stdout=None,stderr=None): if not stdin: stdin = open('/dev/null', 'r') if not stdout: stdout = open('/dev/null', 'a+') if not stderr: stderr = open('/dev/null', 'a+', 0) if type(pid_path) not in [str, unicode]: raise Exception( 'pid_path is not a string: %s' % type(pid_path).__name__ ) if type(log_file) != file: raise Exception( 'log_file is not a file: %s' % type(log_file).__name__ ) if type(stdin) != file: raise Exception('stdin is not a file: %s' % type(stdin).__name__) if type(stdout) != file: raise Exception('stdout is not a file: %s' % type(stdout).__name__) if type(stderr) != file: raise Exception('stderr is not a file: %s' % type(stderr).__name__) self.pid_path = pid_path self.log_file = log_file self.stdin = stdin self.stdout = stdout self.stderr = stderr Process.__init__(self, target=self.run, args=None, logging=True)
def initialize(self): Process.initialize(self) self.deferred_joins = [] self.listener = Connection(('', self.port), self.socket) if not self.listener.socket: # do not replace caller provided socket self.listener.listen() self.poller = select.poll() self.pollable(self.listener.fileno(), self.listener, INMASK | ERRMASK)
def restart(self): if not self.get_pid(): raise Exception('pid file %s does not exist' % self.pid_path) old_pid = self.get_pid() self.target = self.rerun # override the default target=self.run Process.start(self, daemonize=True, synchronize=True) self.set_pid(self.pid) return self.get_pid()
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 __init__(self, port, authkey=None, socket=None, alt_keys={}, interval=None, home=None, proc_name=None, logging=False): if (not socket) and (type(port) != int or port < 1): raise Exception('client port must be integer >= 1') # authkey is used in hmac computation, which doesn't understand unicode if authkey and type(authkey) != str: raise Exception('authkey must be a regular string') Process.__init__(self, self.run, (), logging, proc_name) self.socket = socket self.port = port # listening port for all connections self.fds = {} if type(authkey) not in [str, types.NoneType]: raise Exception('authkey must be a regular string or None') self.keys = {0: authkey} # primary authentication key (may be None) if alt_keys: if type(alt_keys) != dict: raise Exception('alt_keys must be a dictionary') for k in alt_keys: if type(alt_keys[k]) not in [str, types.NoneType]: raise Exception('alt keys must be regular strings or None') self.keys[k] = alt_keys[k] if type(interval) not in [int, float, types.NoneType]: raise Exception( 'the interval (seconds) must be expressed as in integer, a ' 'float, or None') if not home: home = ave.config.load_etc()['home'] self.home = home self.interval = to_milliseconds(interval) self.unpend = [] # fd's to ignore in pending events handling self.rejecting = False self.accepting = [] # connections self.authenticating = {} # connection -> salt self.established = {} # connection -> authkey or None self.keepwatching = {} self.listener = None self.outgoing = {} # connection -> message self.buf_sizes = (1024 * 16, 1024 * 16) # setsockopt() parameters self.deferred_joins = None
def t06(pretty, factory): def killer(pid): for i in range(150): os.kill(pid, signal.SIGUSR1) time.sleep(0.05) ctrl = factory.make_control(home=factory.HOME.path, authkey='') proc = Process(target=killer, args=(ctrl.get_pid(),)) proc.start() # connect and authenticate conn = BlockingConnection(('',ctrl.port)) conn.connect() conn.put(make_digest(conn.get(), '')) finish_challenge(conn.get()) # feed messages slowly to the controller, check that it doesn't crash ok = True for i in range(15): blob = RemoteControl.make_rpc_blob('upper', None, 'a'*5000) conn.write(Connection.make_header(blob)) #print '<',i for char in blob: conn.write(char) time.sleep(0.00002) #print '>',i try: msg = conn.get(timeout=1) except Exception, e: print('FAIL %s: control crashed in step %d: %s' % (pretty, i, e)) ok = False break try: msg = json.loads(msg) except Exception, e: print('FAIL %s: could not decode response %d: %s' & (pretty, i, e)) ok = False break
def t6(factory): pretty = '%s t6' % __file__ print(pretty) handover = factory.make_master('master') avail = handover.list_available() def oob_client(address): r = RemoteBroker(address, home=factory.HOME.path) h, w = r.get_resources({'type': 'handset'}, {'type': 'workspace'}) w.run('sleep 3') # right, extremely busy, but it prevents other action while True: time.sleep(1) # don't let client die and loose all resources p = Process(target=oob_client, args=(handover.address, )) p.start() # make sure the oob client has gotten its resources ok = False for i in range(10): if len(handover.list_available()) != len(avail): ok = True break time.sleep(0.3) if not ok: print('FAIL %s: catastrophic' % pretty) adoption, config, fdtx_path = handover.begin_handover() takeover = factory.make_takeover('master', adoption, config, fdtx_path) handover.end_handover(1) result = True if len(takeover.list_available()) == len(avail): print('FAIL %s: wrong avail: %s' % (pretty, avail)) result = False p.terminate() p.join() return result
def close_fds(self, exclude): exclude.append(self.stdin.fileno()) exclude.append(self.stdout.fileno()) exclude.append(self.stderr.fileno()) exclude.append(self.log_file.fileno()) Process.close_fds(self, exclude)
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 start(self, daemonize=False, synchronize=False): Process.start(self, daemonize, synchronize) if self.socket: self.socket.close() # do not leave open in parent process
def make_client(self, fn, *argv): p = Process(target=fn, args=argv) p.start() self.processes.append(p) return p
def close_fds(self, exclude): if self.socket: exclude.append(self.socket.fileno()) Process.close_fds(self, exclude)
print(pretty) def srv(sock_path, so_path=None): try: tx = FdTx(so_path) dirname, filename = os.path.split(sock_path) time.sleep(0.5) # make sure a bunch of early connects fail tx.listen(dirname, filename) tx.accept() except Exception, e: traceback.print_exc() print('FAIL: srv failed') sock_path = os.path.join(w.path, 'fdtx.sock') p = Process(target=srv, args=(sock_path, so_path)) p.start() tx = FdTx(so_path) ok = True try: tx.connect(sock_path, 2) except Exception, e: print('FAIL %s: connect failed: %s' % (pretty, str(e))) ok = False p.terminate() p.join() return ok # like t4 but with the delay after the call to .listen(). also send something
def close_fds(self, exclude): Process.close_fds(self, exclude) # don't change default behavior
def t8(factory): pretty = '%s t8' % __file__ print(pretty) original = factory.make_master('master') avail = original.list_available() def oob_client(address): r = RemoteBroker(address, home=factory.HOME.path) h, w = r.get_resources({'type': 'handset'}, {'type': 'workspace'}) while True: time.sleep(1) p = Process(target=oob_client, args=(original.address, )) p.start() # make sure the oob client has gotten its resources ok = False for i in range(10): if len(original.list_available()) != len(avail): ok = True break time.sleep(0.1) if not ok: print('FAIL %s: catastrophic' % pretty) p.terminate() p.join() return False # do two handovers in a row adoption, config, fdtx_path = original.begin_handover() interim = factory.make_takeover('master', adoption, config, fdtx_path) original.end_handover(1) adoption, config, fdtx_path = interim.begin_handover() final = factory.make_takeover('master', adoption, config, fdtx_path) interim.end_handover(1) # check that all brokers have the same availability a1 = original.list_available() a2 = interim.list_available() a3 = final.list_available() if len(a1) != len(a2) != len(a3): print('FAIL %s: a handover failed somewhere: %s != %s != %s' % (pretty, a1, a2, a3)) p.terminate() p.join() return False # kill the client so that the brokers reclaim the equipment p.terminate() p.join() ok = False for i in range(10): a3 = final.list_available() if len(a3) == len(avail): ok = True break if not ok: print('FAIL %s: wrong availability: %d %d %d %d' % (pretty, len(a1), len(a2), len(a3), len(avail))) return False # check that the original and interim brokers have terminated now that they # don't have any sessions with allocations try: original.ping() # ping except Exit, e: pass # good
def close_fds(self, exclude): exclude.append(self.args[1].w) Process.close_fds(self, exclude)
pid = self.get_pid() if not pid: raise Exception('pid file %s does not exist' % self.pid_path) try: # can't call waitpid() on non-child. instead retry until exception while True: os.kill(pid, signal.SIGTERM) time.sleep(0.5) except OSError, e: if 'No such process' in str(e): if os.path.exists(self.pid_path): os.remove(self.pid_path) else: raise e def exit(self, code): # remove the pid file unless an overlapped restart is ongoing. this is # visible as a change of the contents of the pid file if self.get_pid() == os.getpid(): try: os.remove(self.pid_path) except Exception, e: self.log('could not delete pid file: %s' % e) Process.exit(self, code) def run(self): raise Exception('subclass must implement Daemon.run()') def rerun(self): raise Exception('subclass must implement Daemon.rerun()')
def t7(factory): pretty = '%s t7' % __file__ print(pretty) handover = factory.make_master('master') avail = handover.list_available() def oob_client(address): r = RemoteBroker(address, home=factory.HOME.path) h, w = r.get_resources({'type': 'handset'}, {'type': 'workspace'}) w.run('sleep 2') # right, extremely busy, but it prevents other action p = Process(target=oob_client, args=(handover.address, )) p.start() # make sure the oob client has gotten its resources ok = False for i in range(10): if len(handover.list_available()) != len(avail): ok = True break time.sleep(0.1) if not ok: print('FAIL %s: catastrophic' % pretty) p.terminate() p.join() return False adoption, config, fdtx_path = handover.begin_handover() takeover = factory.make_takeover('master', adoption, config, fdtx_path) handover.end_handover(1) # now wait for the client to die, so that its session dies, so that # the takeover detects this, so that the associated resouces can be reclaimed, # so that the takeover's availability is the same as when we started ok = False for i in range(10): if len(takeover.list_available()) == len(avail): ok = True break time.sleep(0.3) if not ok: print('FAIL %s: super busy session not tracked correctly' % pretty) p.terminate() p.join() return ok
print('FAIL %s: could not connect: %s' % (pretty, str(e))) return False try: msg = c.get(timeout=1) if msg != 'test the connection': print('FAIL %s: wrong message: %s' % (pretty, msg)) return False except Exception, e: traceback.print_exc() print('FAIL %s: get() failed: %s' % (pretty, e)) return False # bind socket to port but don't start listening sock, port = find_free_port(listen=False) pinger = Process(target=ping, args=(port, sock)) pinger.start() result = test(port) pinger.terminate() pinger.join() return result # check that connection attempts succeed if someone accepts soon enough def t04(): pretty = '%s t4' % __file__ print(pretty)
def t2(w, so_path): pretty = '%s t2' % __file__ print(pretty) sock_path = os.path.join(w.path, 'fdtx.sock') file_paths = [ os.path.join(w.path, 'file1.txt'), os.path.join(w.path, 'file2.txt'), os.path.join(w.path, 'file3.txt') ] p1 = Process(target=accepter, args=(sock_path, file_paths, so_path)) p2 = Process(target=connecter, args=(sock_path, 'star cream', 3, so_path)) p1.start() time.sleep(0.1) p2.start() p1.join() p2.join() for path in file_paths: with open(path) as f: contents = f.read() if contents != 'star cream': print('FAIL %s: wrong reception: %s' % (pretty, contents)) return False return True
def t1(w, so_path): pretty = '%s t1' % __file__ print(pretty) sock_path = os.path.join(w.path, 'fdtx.sock') file_path = os.path.join(w.path, 'file.txt') p1 = Process(target=accepter, args=(sock_path, [file_path], so_path)) p2 = Process(target=connecter, args=(sock_path, 'star cream', 1, so_path)) p1.start() time.sleep(0.1) p2.start() p1.join() p2.join() with open(file_path) as f: contents = f.read() if contents != 'star cream': print('FAIL %s: wrong reception: %s' % (pretty, contents)) return False return True
def close_fds(self, exclude): if self.pipe: exclude.append(self.pipe.w) Process.close_fds(self, exclude)
def close_fds(self, exclude): exclude.extend([self.args[1].w, self.args[2].r]) Process.close_fds(self, exclude)
def __init__(self, guid, json_data, home, logging): Process.__init__( self, self.run, (guid, json_data, home), logging, 'ave-panotti-shouter' )
def handle_SIGTERM(self, signum, frame): time.sleep(5) # very poor behavior Process.handle_SIGTERM(self, signum, frame)
def close_fds(self, exclude=[]): exclude.append(self.args[1].fileno()) Process.close_fds(self, exclude)
def __init__(self, home, logging, profiles, timeout): self.home = home self.profiles = profiles self.timeout = timeout Process.__init__(self, None, None, logging, 'ave-relay-reporter')