def testServerStartSecondary(self): """Another started server appends itself to instance list.""" test_cfg = env.import_test_cfg(self._test_workspace) codechecker_1 = test_cfg['codechecker_1'] codechecker_2 = test_cfg['codechecker_2'] EVENT_2.clear() start_server(codechecker_2, EVENT_2) # Workspaces must match, servers were started in the same workspace. instance_workspaces = [ i['workspace'] for i in instance_manager.list(self.home) if i['workspace'] == self._test_workspace ] self.assertEqual( len(instance_workspaces), 2, "Two servers in the same workspace but the workspace" " was not found twice in the instance list.") # Exactly one server should own each port generated instance_ports = [ i['port'] for i in instance_manager.list(self.home) if i['port'] == codechecker_1['viewer_port'] or i['port'] == codechecker_2['viewer_port'] ] self.assertEqual( len(instance_ports), 2, "The ports for the two started servers were not found" " in the instance list.")
def testShutdownRecordKeeping(self): """Test that one server's shutdown keeps the other records.""" # NOTE: Do NOT rename this method. It MUST come lexicographically # AFTER testServerStartSecondary, because we shut down a server started # by the aforementioned method. # Kill the second started server. EVENT_2.set() # Give the server some grace period to react to the kill command. time.sleep(5) test_cfg = env.import_test_cfg(self._test_workspace) codechecker_1 = test_cfg['codechecker_1'] codechecker_2 = test_cfg['codechecker_2'] instance_1 = [ i for i in instance_manager.list(self.home) if i['port'] == codechecker_1['viewer_port'] and i['workspace'] == self._test_workspace ] instance_2 = [ i for i in instance_manager.list(self.home) if i['port'] == codechecker_2['viewer_port'] and i['workspace'] == self._test_workspace ] self.assertNotEqual( instance_1, [], "The stopped server deleted another server's " "record from the instance list!") self.assertEqual( instance_2, [], "The stopped server did not disappear from the" " instance list.")
def testShutdownTerminateStopAll(self): """Tests that --stop-all kills all servers on the host.""" # NOTE: Yet again keep the lexicographical flow, no renames! test_cfg = env.import_test_cfg(self._test_workspace) codechecker_1 = test_cfg['codechecker_1'] codechecker_2 = test_cfg['codechecker_2'] EVENT_1.clear() EVENT_2.clear() start_server(codechecker_1, EVENT_1) start_server(codechecker_2, EVENT_2) self.assertEqual( len(instance_manager.list(self.home)), 2, "Two servers were started but they don't appear " "in the instance list.") # Kill the servers via cmdline. self.assertEqual( 0, self.run_cmd([env.codechecker_cmd(), 'server', '--stop-all']), "The stop-all command didn't return exit code 0.") time.sleep(5) self.assertEqual( len(instance_manager.list(self.home)), 0, "Both servers were allegedly stopped but they " "did not disappear.")
def __instance_management(args): """Handles the instance-manager commands --list/--stop/--stop-all.""" # TODO: The server stopping and listing must be revised on its invocation # once "workspace", as a concept, is removed. # QUESTION: What is the bestest way here to identify a server for the user? if 'list' in args: instances = instance_manager.list() instances_on_multiple_hosts = any(True for inst in instances if inst['hostname'] != socket.gethostname()) if not instances_on_multiple_hosts: head = ['Workspace', 'View port'] else: head = ['Workspace', 'Computer host', 'View port'] rows = [] for instance in instance_manager.list(): if not instances_on_multiple_hosts: rows.append((instance['workspace'], str(instance['port']))) else: rows.append((instance['workspace'], instance['hostname'] if instance['hostname'] != socket.gethostname() else '', str(instance['port']))) print("Your running CodeChecker servers:") print(output_formatters.twodim_to_str('table', head, rows)) elif 'stop' in args or 'stop_all' in args: for i in instance_manager.list(): if i['hostname'] != socket.gethostname(): continue # A STOP only stops the server associated with the given workspace # and view-port. if 'stop' in args and \ not (i['port'] == args.view_port and os.path.abspath(i['workspace']) == os.path.abspath(args.config_directory)): continue try: util.kill_process_tree(i['pid']) LOG.info("Stopped CodeChecker server running on port {0} " "in workspace {1} (PID: {2})". format(i['port'], i['workspace'], i['pid'])) except: # Let the exception come out if the commands fail LOG.error("Couldn't stop process PID #" + str(i['pid'])) raise
def testServerStart(self): """Started server writes itself to instance list.""" test_cfg = env.import_test_cfg(self._test_workspace) codechecker_1 = test_cfg['codechecker_1'] EVENT_1.clear() start_server(codechecker_1, EVENT_1, ['--skip-db-cleanup']) time.sleep(5) instance = [i for i in instance_manager.list(self.home) if i['port'] == codechecker_1['viewer_port'] and i['workspace'] == self._test_workspace] self.assertNotEqual(instance, [], "The started server did not register itself to the" " instance list.")
def testShutdownTerminateByCmdline(self): """Tests that the command-line command actually kills the server, and that it does not kill anything else.""" # NOTE: Yet again keep the lexicographical flow, no renames! test_cfg = env.import_test_cfg(self._test_workspace) codechecker_1 = test_cfg['codechecker_1'] codechecker_2 = test_cfg['codechecker_2'] EVENT_2.clear() start_server(codechecker_2, EVENT_2) # Kill the server, but yet again give a grace period. self.assertEqual( 0, self.run_cmd([ env.codechecker_cmd(), 'server', '--stop', '--view-port', str(codechecker_2['viewer_port']), '--workspace', self._test_workspace ]), "The stop command didn't return exit code 0.") time.sleep(5) # Check if the remaining server is still there, # we need to make sure that --stop only kills the specified server! instance_1 = [ i for i in instance_manager.list(self.home) if i['port'] == codechecker_1['viewer_port'] and i['workspace'] == self._test_workspace ] instance_2 = [ i for i in instance_manager.list(self.home) if i['port'] == codechecker_2['viewer_port'] and i['workspace'] == self._test_workspace ] self.assertNotEqual( instance_1, [], "The stopped server deleted another server's " "record from the instance list!") self.assertEqual( instance_2, [], "The stopped server did not disappear from the" " instance list.") # Kill the first server via cmdline too. self.assertEqual( 0, self.run_cmd([ env.codechecker_cmd(), 'server', '--stop', '--view-port', str(codechecker_1['viewer_port']), '--workspace', self._test_workspace ]), "The stop command didn't return exit code 0.") time.sleep(5) instance_1 = [ i for i in instance_manager.list(self.home) if i['port'] == codechecker_1['viewer_port'] and i['workspace'] == self._test_workspace ] instance_2 = [ i for i in instance_manager.list(self.home) if i['port'] == codechecker_2['viewer_port'] and i['workspace'] == self._test_workspace ] self.assertEqual( instance_1, [], "The stopped server did not disappear from the" " instance list.") self.assertEqual( instance_2, [], "The stopped server made another server's record " "appear in the instance list.")
def handle_server(args): """ Starts the report viewer server. """ if not host_check.check_zlib(): sys.exit(1) workspace = args.workspace if (args.list or args.stop or args.stop_all) and \ not (args.list ^ args.stop ^ args.stop_all): print("CodeChecker server: error: argument -l/--list and -s/--stop" "and --stop-all are mutually exclusive.") sys.exit(2) if args.list: instances = instance_manager.list() instances_on_multiple_hosts = any(True for inst in instances if inst['hostname'] != socket.gethostname()) if not instances_on_multiple_hosts: rows = [('Workspace', 'View port')] else: rows = [('Workspace', 'Computer host', 'View port')] for instance in instance_manager.list(): if not instances_on_multiple_hosts: rows.append((instance['workspace'], str(instance['port']))) else: rows.append((instance['workspace'], instance['hostname'] if instance['hostname'] != socket.gethostname() else '', str(instance['port']))) print("Your running CodeChecker servers:") print(util.twodim_to_table(rows)) sys.exit(0) elif args.stop or args.stop_all: for i in instance_manager.list(): # A STOP only stops the server associated with the given workspace # and view-port. if i['hostname'] != socket.gethostname() or ( args.stop and not (i['port'] == args.view_port and os.path.abspath(i['workspace']) == os.path.abspath(workspace))): continue try: util.kill_process_tree(i['pid']) LOG.info("Stopped CodeChecker server running on port {0} " "in workspace {1} (PID: {2})". format(i['port'], i['workspace'], i['pid'])) except: # Let the exception come out if the commands fail LOG.error("Couldn't stop process PID #" + str(i['pid'])) raise sys.exit(0) # WARNING # In case of SQLite args.dbaddress default value is used # for which the is_localhost should return true. if util.is_localhost(args.dbaddress) and not os.path.exists(workspace): os.makedirs(workspace) suppress_handler = generic_package_suppress_handler.\ GenericSuppressHandler(None) if args.suppress is None: LOG.warning('No suppress file was given, suppressed results will ' 'be only stored in the database.') else: if not os.path.exists(args.suppress): LOG.error('Suppress file ' + args.suppress + ' not found!') sys.exit(1) context = generic_package_context.get_context() context.codechecker_workspace = workspace session_manager.SessionManager.CodeChecker_Workspace = workspace context.db_username = args.dbusername check_env = analyzer_env.get_check_env(context.path_env_extra, context.ld_lib_path_extra) sql_server = SQLServer.from_cmdline_args(args, context.migration_root, check_env) conn_mgr = client.ConnectionManager(sql_server, args.check_address, args.check_port) if args.check_port: LOG.debug('Starting CodeChecker server and database server.') sql_server.start(context.db_version_info, wait_for_start=True, init=True) conn_mgr.start_report_server() else: LOG.debug('Starting database.') sql_server.start(context.db_version_info, wait_for_start=True, init=True) # Start database viewer. db_connection_string = sql_server.get_connection_string() suppress_handler.suppress_file = args.suppress LOG.debug('Using suppress file: ' + str(suppress_handler.suppress_file)) checker_md_docs = os.path.join(context.doc_root, 'checker_md_docs') checker_md_docs_map = os.path.join(checker_md_docs, 'checker_doc_map.json') with open(checker_md_docs_map, 'r') as dFile: checker_md_docs_map = json.load(dFile) package_data = {'www_root': context.www_root, 'doc_root': context.doc_root, 'checker_md_docs': checker_md_docs, 'checker_md_docs_map': checker_md_docs_map, 'version': context.package_git_tag} try: client_db_access_server.start_server(package_data, args.view_port, db_connection_string, suppress_handler, args.not_host_only, context) except socket.error as err: if err.errno == errno.EADDRINUSE: LOG.error("Server can't be started, maybe the given port number " "({}) is already used. Check the connection " "parameters.".format(args.view_port)) sys.exit(1) else: raise