def Test_D_user_group(self): """ Now start the legion with user and group strings. """ self.set_path('PATH', env.examples_bin) self.log.info("PATH: %s", os.environ['PATH']) os.environ['EXAMPLES_BASE'] = env.examples_dir os.environ['EXAMPLES_TESTUSER'] = pwd.getpwuid(os.getuid()).pw_name os.environ['EXAMPLES_TESTGROUP'] = grp.getgrgid(os.getgid()).gr_name os.environ['EXAMPLES_LISTEN'] = self.tcp_listen new_roles = env.test_roles self.set_roles(new_roles) self.log.info("Setting roles %s", new_roles) self.log.info("Will run: %s", ' '.join(support.taskforce.command_line(env, []))) tf = support.taskforce(env, [], log=self.log) self.log.info("Checking startup of %s roles", new_roles) db_started = tf.search([r"Task 'db_server' already started"], log=self.log) assert db_started kids = len(support.proctree().processes[tf.pid].children) assert self.find_children(tf, roles=new_roles) == expected_frontback_process_count self.log.info("User/group names ok") support.check_procsim_errors(self.__module__, env, log=self.log) tf.close()
def Test_C_role_switch(self): """ Check that a role change stops and starts processes correctly. Also excercise the uid-setting code (even though this just sets it to ourself as we are not necessarily running as root). """ self.set_path('PATH', env.examples_bin) self.log.info("PATH: %s", os.environ['PATH']) os.environ['EXAMPLES_BASE'] = env.examples_dir os.environ['EXAMPLES_TESTUSER'] = str(os.getuid()) os.environ['EXAMPLES_TESTGROUP'] = str(os.getgid()) os.environ['EXAMPLES_LISTEN'] = self.tcp_listen new_roles = env.test_roles self.set_roles(new_roles) self.log.info("Setting roles %s", new_roles) self.log.info("Will run: %s", ' '.join(support.taskforce.command_line(env, []))) tf = support.taskforce(env, [], log=self.log) new_roles = env.test_roles self.log.info("Checking startup of %s roles", new_roles) db_started = tf.search([r"Task 'db_server' already started"], log=self.log) assert db_started kids = len(support.proctree().processes[tf.pid].children) assert self.find_children(tf, roles=new_roles) == expected_frontback_process_count self.log.info("Startup ok") new_roles = env.test_roles[0] self.log.info("Switching to role %s", new_roles) self.set_roles(new_roles) db_stopped = tf.search([r"Task 'db_server' (still|pid)", r"Task 'ws_server' already started"], log=self.log) assert db_stopped children_found = self.find_children(tf, roles=new_roles) if children_found != expected_frontend_process_count: self.log.warning("Found %d children, expected %d", children_found, expected_frontend_process_count) assert children_found == expected_frontend_process_count self.log.info("Switch to %s ok, pid to check is %d", new_roles, tf.pid) new_roles = env.test_roles[1] self.log.info("Switching to role %s", new_roles) self.set_roles(new_roles) db_restarted = tf.search([ r"Task 'db_server' already started", r"Task 'db_server' a[l]ready started", # Bit of a kludge to be sure we see this at least twice r"Task 'httpd' already started" ], log=self.log) assert db_restarted assert self.find_children(tf, roles=new_roles) == expected_backend_process_count self.log.info("Switch to %s ok, pid to check is %d", new_roles, tf.pid) support.check_procsim_errors(self.__module__, env, log=self.log) tf.close()
def Test_B_http_unx_status(self): httpc = self.start_tf(self.unx_address, use_ssl=None) # Check the version info is sane resp = httpc.getmap('/status/version') self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp # Same, but use post resp = httpc.postmap('/status/version') self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp # Try a control operation that should be disabled on this path try: resp = httpc.post('/manage/control?db_server=off') assert "No exception on unauthorized control" is False except taskforce.http.HttpError as e: self.log.info("%s Expected exception on bad url: %s", my(self), str(e)) # Again but with different arg layout try: resp = httpc.post('/manage/control', query={'db_server': 'off'}) assert "No exception on unauthorized control" is False except taskforce.http.HttpError as e: self.log.info("%s Expected exception on bad url: %s", my(self), str(e)) # Try an illegal URL try: resp = httpc.getmap('/') assert "No exception on bad url" is False except taskforce.http.HttpError as e: self.log.info("%s Expected exception on bad url: %s", my(self), str(e)) support.check_procsim_errors(self.__module__, env, log=self.log) self.stop_tf()
def Test_C_https_unx_status(self): httpc = self.start_tf(self.unx_address, use_ssl=False, allow_control=True) # Check the version info is sane resp = httpc.getmap('/status/version') self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp assert 'platform' in resp assert 'release' in resp['platform'] # Allow some process startup time time.sleep(2) taskname = 'ws_server' initial_ws_server_count = self.get_process_count(httpc, taskname) if initial_ws_server_count != self.expected_ws_server_count: self.log.info("%s %d or %d expected %s processs at startup", my(self), initial_ws_server_count, self.expected_ws_server_count, taskname) # Send an invalid management path log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.get('/manage/nosuchpath') self.log.setLevel(log_level) assert "No exception on bad management path" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad management path: %s", my(self), str(e)) # Send a now-valid command but have it expect a JSON return, which doesn't happen log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/control', valuemap={'db_server': 'off'}) self.log.setLevel(log_level) assert "No exception on bad JSON return" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad url: %s", my(self), str(e)) # Repeat the last change to test the no-change response (off_code, content, content_type) = httpc.post('/manage/control', valuemap={'db_server': 'off'}) self.log.info('%s repeat-off response info: %d %s "%s"', taskname, off_code, content_type, content.strip()) assert off_code == 200 assert content.strip().endswith('no change') # Turn task back on. (wait_code, content, content_type) = httpc.post('/manage/control', valuemap={'db_server': 'wait'}) self.log.info('%s restart response info: %d %s "%s"', taskname, wait_code, content_type, content.strip()) assert wait_code == 202 assert content.strip().endswith('ok') # Send a control to an unknown task log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/control', valuemap={'no_such_task': 'off'}) self.log.setLevel(log_level) assert "No exception on bad task name" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad task name: %s", my(self), str(e)) # Send an invalid control to an known task log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/control', valuemap={'db_server': 'no_such_control'}) self.log.setLevel(log_level) assert "No exception on bad control name" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad control name: %s", my(self), str(e)) prior_ws_server_count = self.get_process_count( httpc, taskname, self.expected_ws_server_count) assert prior_ws_server_count == self.expected_ws_server_count # Change the count # new_count = 2 (count_code, content, content_type) = httpc.get('/manage/count?%s=%d' % (taskname, new_count)) self.log.info('%s count response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert count_code < 300 ws_server_count = self.get_process_count(httpc, taskname, new_count) assert ws_server_count == new_count # Repeat the last change to test the no-change response (count_code, content, content_type) = httpc.get('/manage/count?%s=%d' % (taskname, new_count)) self.log.info('%s repeat-count response info: %d %s "%s"', taskname, off_code, content_type, content.strip()) assert off_code == 200 assert content.strip().endswith('no change') # Send a count to an unknown task log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/count', valuemap={'no_such_task': '1'}) self.log.setLevel(log_level) assert "No exception on bad task name for count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info( "%s Expected exception on bad task name for count: %s", my(self), str(e)) # Send an invalid count log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.get('/manage/count?%s=nonumberhere' % (taskname, )) self.log.setLevel(log_level) self.log.error("%s Invalid bad count response: %s", my(self), str(resp)) assert "No exception on bad count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad count value: %s", my(self), str(e)) # Send a zero count log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.post('/manage/count?%s=%d' % ( taskname, 0, )) self.log.setLevel(log_level) self.log.error("%s Invalid zero count response: %s", my(self), str(resp)) assert "No exception on zero count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on zero count: %s", my(self), str(e)) # Send a negative count log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.post('/manage/count', valuemap={taskname: '-42'}) self.log.setLevel(log_level) self.log.error("%s Invalid negative count response: %s", my(self), str(resp)) assert "No exception on negative count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on negative count: %s", my(self), str(e)) # Reload config to put it back (reload_code, content, content_type) = httpc.get('/manage/reload') self.log.info('%s reload response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert reload_code == 202 assert content.strip().endswith('reload initiated') ws_server_count = self.get_process_count(httpc, taskname, self.expected_ws_server_count) assert ws_server_count == self.expected_ws_server_count (reset_code, content, content_type) = httpc.get('/manage/reset') self.log.info('%s reset response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert reset_code < 300 assert content.strip().endswith('reset initiated') time.sleep(2) # Reconnect to service and wait for the reset to complete then check that the version info is sane. # resp = None httpc = None for attempt in range(30): try: httpc = self.start_client(self.unx_address, use_ssl=False) resp = httpc.getmap('/status/version') break except taskforce.http.HttpError as e: self.log.error( "%s HTTP exception while waiting for reset to complete on attempt %d -- %s", my(self), attempt + 1, str(e)) break except Exception as e: self.log.info( "%s Error waiting or reset to complete on attempt %d -- %s", my(self), attempt + 1, str(e), exc_info=True) time.sleep(0.5) self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp try: (stop_code, content, content_type) = httpc.get('/manage/stop') self.log.info('%s stop response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert stop_code < 300 assert content.strip().endswith('exit initiated') except (taskforce.http.BadStatusLine, taskforce.http.HttpError) as e: self.log.info('%s Expected possible error from stop manage -- %s', my(self), str(e)) except socket.error as e: if e.errno == errno.ECONNRESET: self.log.info( '%s Expected possible socket error from stop manage -- %s', my(self), str(e)) else: raise e support.check_procsim_errors(self.__module__, env, log=self.log) self.stop_tf()
def Test_A_https_tcp_status(self): httpc = self.start_tf(self.tcp_address, use_ssl=False) # Check the version info is sane resp = httpc.getmap('/status/version') self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp assert 'platform' in resp # This is not a control path, so the os release and platform should be hidden assert 'release' not in resp['platform'] assert 'platform' not in resp['platform'] # Try a bogus format try: resp = httpc.getmap('/status/version?indent=4&fmt=xml') assert "No 'version' exception on bad 'fmt'" is False except taskforce.http.HttpError as e: self.log.info("%s Expected 'version' exception on bad format: %s", my(self), str(e)) give_up = time.time() + 30 toi = 'db_server' toi_started = None while time.time() < give_up: resp = httpc.getmap('/status/tasks') self.log.debug('Resp %s', json.dumps(resp, indent=4)) if toi in resp: if 'processes' in resp[toi] and len( resp[toi]['processes']) > 0: if 'started_t' in resp[toi]['processes'][0]: toi_started = resp[toi]['processes'][0]['started_t'] self.log.info( "%s Task of interest '%s' started %s ago", my(self), toi, deltafmt(time.time() - toi_started)) break else: self.log.info("%s Task of interest '%s' is has procs", my(self), toi) else: self.log.info("%s Task of interest '%s' is known", my(self), toi) time.sleep(9) # Try a bogus format try: resp = httpc.getmap('/status/tasks?indent=4&fmt=xml') assert "No 'tasks' exception on bad 'fmt'" is False except taskforce.http.HttpError as e: self.log.info("%s Expected 'tasks' exception on bad format: %s", my(self), str(e)) # Check the config info is sane resp = httpc.getmap('/status/config?pending=0') assert 'tasks' in resp # Try a bogus format try: resp = httpc.getmap('/status/config?indent=4&fmt=xml') assert "No 'config' exception on bad 'fmt'" is False except taskforce.http.HttpError as e: self.log.info("%s Expected 'config' exception on bad format: %s", my(self), str(e)) support.check_procsim_errors(self.__module__, env, log=self.log) self.stop_tf() assert toi_started is not None
def Test_C_https_unx_status(self): httpc = self.start_tf(self.unx_address, use_ssl=False, allow_control=True) # Check the version info is sane resp = httpc.getmap('/status/version') self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp assert 'platform' in resp assert 'release' in resp['platform'] # Allow some process startup time time.sleep(2) taskname = 'ws_server' initial_ws_server_count = self.get_process_count(httpc, taskname) if initial_ws_server_count != self.expected_ws_server_count: self.log.info("%s %d or %d expected %s processs at startup", my(self), initial_ws_server_count, self.expected_ws_server_count, taskname) # Send an invalid management path log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.get('/manage/nosuchpath') self.log.setLevel(log_level) assert "No exception on bad management path" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad management path: %s", my(self), str(e)) # Send a now-valid command but have it expect a JSON return, which doesn't happen log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/control', valuemap={'db_server': 'off'}) self.log.setLevel(log_level) assert "No exception on bad JSON return" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad url: %s", my(self), str(e)) # Repeat the last change to test the no-change response (off_code, content, content_type) = httpc.post('/manage/control', valuemap={'db_server': 'off'}) self.log.info('%s repeat-off response info: %d %s "%s"', taskname, off_code, content_type, content.strip()) assert off_code == 200 assert content.strip().endswith('no change') # Turn task back on. (wait_code, content, content_type) = httpc.post('/manage/control', valuemap={'db_server': 'wait'}) self.log.info('%s restart response info: %d %s "%s"', taskname, wait_code, content_type, content.strip()) assert wait_code == 202 assert content.strip().endswith('ok') # Send a control to an unknown task log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/control', valuemap={'no_such_task': 'off'}) self.log.setLevel(log_level) assert "No exception on bad task name" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad task name: %s", my(self), str(e)) # Send an invalid control to an known task log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/control', valuemap={'db_server': 'no_such_control'}) self.log.setLevel(log_level) assert "No exception on bad control name" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad control name: %s", my(self), str(e)) prior_ws_server_count = self.get_process_count(httpc, taskname, self.expected_ws_server_count) assert prior_ws_server_count == self.expected_ws_server_count # Change the count # new_count = 2 (count_code, content, content_type) = httpc.get('/manage/count?%s=%d' % (taskname, new_count)) self.log.info('%s count response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert count_code < 300 ws_server_count = self.get_process_count(httpc, taskname, new_count) assert ws_server_count == new_count # Repeat the last change to test the no-change response (count_code, content, content_type) = httpc.get('/manage/count?%s=%d' % (taskname, new_count)) self.log.info('%s repeat-count response info: %d %s "%s"', taskname, off_code, content_type, content.strip()) assert off_code == 200 assert content.strip().endswith('no change') # Send a count to an unknown task log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.postmap('/manage/count', valuemap={'no_such_task': '1'}) self.log.setLevel(log_level) assert "No exception on bad task name for count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad task name for count: %s", my(self), str(e)) # Send an invalid count log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.get('/manage/count?%s=nonumberhere' % (taskname, )) self.log.setLevel(log_level) self.log.error("%s Invalid bad count response: %s", my(self), str(resp)) assert "No exception on bad count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on bad count value: %s", my(self), str(e)) # Send a zero count log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.post('/manage/count?%s=%d' % (taskname, 0, )) self.log.setLevel(log_level) self.log.error("%s Invalid zero count response: %s", my(self), str(resp)) assert "No exception on zero count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on zero count: %s", my(self), str(e)) # Send a negative count log_level = self.log.getEffectiveLevel() try: # Mask the log message as we expect a failure self.log.setLevel(logging.CRITICAL) resp = httpc.post('/manage/count', valuemap={taskname: '-42'}) self.log.setLevel(log_level) self.log.error("%s Invalid negative count response: %s", my(self), str(resp)) assert "No exception on negative count" is False except taskforce.http.HttpError as e: self.log.setLevel(log_level) self.log.info("%s Expected exception on negative count: %s", my(self), str(e)) # Reload config to put it back (reload_code, content, content_type) = httpc.get('/manage/reload') self.log.info('%s reload response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert reload_code == 202 assert content.strip().endswith('reload initiated') ws_server_count = self.get_process_count(httpc, taskname, self.expected_ws_server_count) assert ws_server_count == self.expected_ws_server_count (reset_code, content, content_type) = httpc.get('/manage/reset') self.log.info('%s reset response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert reset_code < 300 assert content.strip().endswith('reset initiated') time.sleep(2) # Reconnect to service and wait for the reset to complete then check that the version info is sane. # resp = None httpc = None for attempt in range(30): try: httpc = self.start_client(self.unx_address, use_ssl=False) resp = httpc.getmap('/status/version') break except taskforce.http.HttpError as e: self.log.error("%s HTTP exception while waiting for reset to complete on attempt %d -- %s", my(self), attempt+1, str(e)) break except Exception as e: self.log.info("%s Error waiting or reset to complete on attempt %d -- %s", my(self), attempt+1, str(e), exc_info=True) time.sleep(0.5) self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp try: (stop_code, content, content_type) = httpc.get('/manage/stop') self.log.info('%s stop response info: %d %s "%s"', taskname, count_code, content_type, content.strip()) assert stop_code < 300 assert content.strip().endswith('exit initiated') except (taskforce.http.BadStatusLine, taskforce.http.HttpError) as e: self.log.info('%s Expected possible error from stop manage -- %s', my(self), str(e)) except socket.error as e: if e.errno == errno.ECONNRESET: self.log.info('%s Expected possible socket error from stop manage -- %s', my(self), str(e)) else: raise e support.check_procsim_errors(self.__module__, env, log=self.log) self.stop_tf()
def Test_A_https_tcp_status(self): httpc = self.start_tf(self.tcp_address, use_ssl=False) # Check the version info is sane resp = httpc.getmap('/status/version') self.log.info("Version info: %s", str(resp)) assert 'taskforce' in resp assert 'platform' in resp # This is not a control path, so the os release and platform should be hidden assert 'release' not in resp['platform'] assert 'platform' not in resp['platform'] # Try a bogus format try: resp = httpc.getmap('/status/version?indent=4&fmt=xml') assert "No 'version' exception on bad 'fmt'" is False except taskforce.http.HttpError as e: self.log.info("%s Expected 'version' exception on bad format: %s", my(self), str(e)) give_up = time.time() + 30 toi = 'db_server' toi_started = None while time.time() < give_up: resp = httpc.getmap('/status/tasks') self.log.debug('Resp %s', json.dumps(resp, indent=4)) if toi in resp: if 'processes' in resp[toi] and len(resp[toi]['processes']) > 0: if 'started_t' in resp[toi]['processes'][0]: toi_started = resp[toi]['processes'][0]['started_t'] self.log.info("%s Task of interest '%s' started %s ago", my(self), toi, deltafmt(time.time() - toi_started)) break else: self.log.info("%s Task of interest '%s' is has procs", my(self), toi) else: self.log.info("%s Task of interest '%s' is known", my(self), toi) time.sleep(9) # Try a bogus format try: resp = httpc.getmap('/status/tasks?indent=4&fmt=xml') assert "No 'tasks' exception on bad 'fmt'" is False except taskforce.http.HttpError as e: self.log.info("%s Expected 'tasks' exception on bad format: %s", my(self), str(e)) # Check the config info is sane resp = httpc.getmap('/status/config?pending=0') assert 'tasks' in resp # Try a bogus format try: resp = httpc.getmap('/status/config?indent=4&fmt=xml') assert "No 'config' exception on bad 'fmt'" is False except taskforce.http.HttpError as e: self.log.info("%s Expected 'config' exception on bad format: %s", my(self), str(e)) support.check_procsim_errors(self.__module__, env, log=self.log) self.stop_tf() assert toi_started is not None