def test_update_log_level(self, basicConfig_mock, setLevel_mock): config = AgentConfig("", "") _, tmpoutfile = tempfile.mkstemp() # Testing with default setup (config file does not contain loglevel entry) # Log level should not be changed config.set('agent', 'log_level', None) main.update_log_level(config, tmpoutfile) self.assertFalse(setLevel_mock.called) setLevel_mock.reset_mock() # Testing debug mode config.set('agent', 'log_level', 'DEBUG') main.update_log_level(config, tmpoutfile) setLevel_mock.assert_called_with(logging.DEBUG) setLevel_mock.reset_mock() # Testing any other mode config.set('agent', 'log_level', 'INFO') main.update_log_level(config, tmpoutfile) setLevel_mock.assert_called_with(logging.INFO) setLevel_mock.reset_mock() config.set('agent', 'log_level', 'WRONG') main.update_log_level(config, tmpoutfile) setLevel_mock.assert_called_with(logging.INFO)
def test_registration_build(self): tmpdir = tempfile.gettempdir() ver_dir = os.path.join(tmpdir, "infra") config = AgentConfig(tmpdir, ver_dir) config.set('agent', 'prefix', tmpdir) config.set('agent', 'current_ping_port', '33777') try: os.mkdir(ver_dir) except OSError as exception: if exception.errno != errno.EEXIST: raise pass ver_file = os.path.join(ver_dir, "version") with open(ver_file, "w") as text_file: text_file.write("1.3.0") register = Register(config) data = register.build(1) #print ("Register: " + pprint.pformat(data)) self.assertEquals(len(data['hardwareProfile']) > 0, True, "hardwareProfile should contain content") self.assertEquals(data['hostname'] != "", True, "hostname should not be empty") self.assertEquals(data['publicHostname'] != "", True, "publicHostname should not be empty") self.assertEquals(data['responseId'], 1) self.assertEquals(data['timestamp'] > 1353678475465L, True, "timestamp should not be empty") self.assertEquals(data['agentVersion'], '1.3.0', "agentVersion should not be empty") self.assertEquals(len(data), 8) self.assertEquals(os.path.join(tmpdir, "app/definition"), config.getResolvedPath("app_pkg_dir")) self.assertEquals(os.path.join(tmpdir, "app/install"), config.getResolvedPath("app_install_dir")) self.assertEquals(os.path.join(ver_dir, "app/log"), config.getResolvedPath("app_log_dir")) self.assertEquals(os.path.join(ver_dir, "infra/log"), config.getResolvedPath("log_dir")) self.assertEquals(os.path.join(ver_dir, "app/command-log"), config.getResolvedPath("app_task_dir")) os.remove(ver_file) os.removedirs(ver_dir)
def test_execute_status_command(self, CustomServiceOrchestrator_mock, build_mock, execute_command_mock, requestComponentStatus_mock, read_stack_version_mock, determine_command_format_version_mock, status_update_callback): CustomServiceOrchestrator_mock.return_value = None dummy_controller = MagicMock() actionQueue = ActionQueue(AgentConfig("", ""), dummy_controller) build_mock.return_value = "dummy report" # Check execution ov V1 status command determine_command_format_version_mock.return_value = ActionQueue.COMMAND_FORMAT_V1 actionQueue.execute_status_command(self.status_command) report = actionQueue.result() expected = 'dummy report' self.assertEqual(len(report['componentStatus']), 1) self.assertEqual(report['componentStatus'][0], expected) self.assertFalse(requestComponentStatus_mock.called) # Check execution ov V2 status command requestComponentStatus_mock.reset_mock() determine_command_format_version_mock.return_value = ActionQueue.COMMAND_FORMAT_V2 actionQueue.execute_status_command(self.status_command) report = actionQueue.result() expected = 'dummy report' self.assertEqual(len(report['componentStatus']), 1) self.assertEqual(report['componentStatus'][0], expected) self.assertTrue(requestComponentStatus_mock.called)
def test_perform_prestart_checks(self, hostname_mock, isdir_mock, isfile_mock, exit_mock, remove_mock): main.config = AgentConfig("", "") # Trying case if there is another instance running isfile_mock.return_value = True isdir_mock.return_value = True main.perform_prestart_checks(main.config) self.assertFalse(exit_mock.called) self.assertTrue(remove_mock.called) isfile_mock.reset_mock() isdir_mock.reset_mock() exit_mock.reset_mock() # Trying case if agent prefix dir does not exist isfile_mock.return_value = False isdir_mock.return_value = False main.perform_prestart_checks(main.config) self.assertTrue(exit_mock.called) isfile_mock.reset_mock() isdir_mock.reset_mock() exit_mock.reset_mock() # Trying normal case isfile_mock.return_value = False isdir_mock.return_value = True main.perform_prestart_checks(main.config) self.assertFalse(exit_mock.called)
def test_build(self): config = AgentConfig("", "") config.set('agent', 'prefix', 'tmp') config.set('agent', 'cache_dir', "/var/lib/ambari-agent/cache") config.set('agent', 'tolerate_download_failures', "true") dummy_controller = MagicMock() actionQueue = ActionQueue(config, dummy_controller) heartbeat = Heartbeat(actionQueue, config) result = heartbeat.build(100) print "Heartbeat: " + str(result) self.assertEquals(result['hostname'] != '', True, "hostname should not be empty") self.assertEquals(result['responseId'], 100) self.assertEquals(result['componentStatus'] is not None, True, "Heartbeat should contain componentStatus") self.assertEquals(result['reports'] is not None, True, "Heartbeat should contain reports") self.assertEquals(result['timestamp'] >= 1353679373880L, True) self.assertEquals(len(result['nodeStatus']), 2) self.assertEquals(result['nodeStatus']['cause'], "NONE") self.assertEquals(result['nodeStatus']['status'], "HEALTHY") # result may or may NOT have an agentEnv structure in it self.assertEquals((len(result) is 6) or (len(result) is 7), True) self.assertEquals(not heartbeat.reports, True, "Heartbeat should not contain task in progress")
def test_process_command(self, execute_status_command_mock, execute_command_mock, print_exc_mock): dummy_controller = MagicMock() actionQueue = ActionQueue(AgentConfig("", ""), dummy_controller) execution_command = { 'commandType': ActionQueue.EXECUTION_COMMAND, } status_command = { 'commandType': ActionQueue.STATUS_COMMAND, } wrong_command = { 'commandType': "SOME_WRONG_COMMAND", } # Try wrong command actionQueue.process_command(wrong_command) self.assertFalse(execute_command_mock.called) self.assertFalse(execute_status_command_mock.called) self.assertFalse(print_exc_mock.called) execute_command_mock.reset_mock() execute_status_command_mock.reset_mock() print_exc_mock.reset_mock() # Try normal execution actionQueue.process_command(execution_command) self.assertTrue(execute_command_mock.called) self.assertFalse(execute_status_command_mock.called) self.assertFalse(print_exc_mock.called) execute_command_mock.reset_mock() execute_status_command_mock.reset_mock() print_exc_mock.reset_mock() actionQueue.process_command(status_command) self.assertFalse(execute_command_mock.called) self.assertTrue(execute_status_command_mock.called) self.assertFalse(print_exc_mock.called) execute_command_mock.reset_mock() execute_status_command_mock.reset_mock() print_exc_mock.reset_mock() # Try exception to check proper logging def side_effect(self): raise Exception("TerribleException") execute_command_mock.side_effect = side_effect actionQueue.process_command(execution_command) self.assertTrue(print_exc_mock.called) print_exc_mock.reset_mock() execute_status_command_mock.side_effect = side_effect actionQueue.process_command(execution_command) self.assertTrue(print_exc_mock.called)
def test_resolve_config(self, read_mock, exists_mock): config = AgentConfig("", "") # Trying case if conf file exists exists_mock.return_value = True main.update_config_from_file(config) self.assertTrue(read_mock.called) exists_mock.reset_mock() read_mock.reset_mock() # Trying case if conf file does not exist exists_mock.return_value = False main.update_config_from_file(config) self.assertFalse(read_mock.called)
def test_build(self): config = AgentConfig("", "") config.set('agent', 'prefix', 'tmp') dummy_controller = MagicMock() actionQueue = ActionQueue(config, dummy_controller) heartbeat = Heartbeat(actionQueue, config) result = heartbeat.build({}, 100) print "Heartbeat: " + str(result) self.assertEquals(result['hostname'] != '', True, "hostname should not be empty") self.assertEquals(result['responseId'], 100) self.assertEquals('componentStatus' not in result, True, "Heartbeat should contain componentStatus") self.assertEquals(result['reports'] is not None, True, "Heartbeat should contain reports") self.assertEquals(result['timestamp'] >= 1353679373880L, True) self.assertEquals(len(result['nodeStatus']), 2) self.assertEquals(result['nodeStatus']['cause'], "NONE") self.assertEquals(result['nodeStatus']['status'], "HEALTHY") # result may or may NOT have an agentEnv structure in it self.assertEquals((len(result) is 4) or (len(result) is 5), True) self.assertEquals(not heartbeat.reports, True, "Heartbeat should not contain task in progress")
def test_determine_command_format_version(self, CustomServiceOrchestrator_mock): CustomServiceOrchestrator_mock.return_value = None v1_command = {'commandParams': {'schema_version': '1.0'}} v2_command = {'commandParams': {'schema_version': '2.0'}} current_command = { # Absent 'commandParams' section } dummy_controller = MagicMock() actionQueue = ActionQueue(AgentConfig("", ""), dummy_controller) self.assertEqual( actionQueue.determine_command_format_version(v1_command), ActionQueue.COMMAND_FORMAT_V1) self.assertEqual( actionQueue.determine_command_format_version(v2_command), ActionQueue.COMMAND_FORMAT_V2) self.assertEqual( actionQueue.determine_command_format_version(current_command), ActionQueue.COMMAND_FORMAT_V1)
def test_execute_status_command(self, CustomServiceOrchestrator_mock, execute_command_mock, requestComponentStatus_mock, status_update_callback): CustomServiceOrchestrator_mock.return_value = None dummy_controller = MagicMock() actionQueue = ActionQueue(AgentConfig("", ""), dummy_controller) requestComponentStatus_mock.return_value = {'exitcode': 'dummy report'} actionQueue.execute_status_command(self.status_command) report = actionQueue.result() expected = 'dummy report' self.assertEqual(len(report['componentStatus']), 1) self.assertEqual(report['componentStatus'][0]["status"], expected) self.assertEqual(report['componentStatus'][0]["componentName"], "ACCUMULO_MASTER") self.assertEqual(report['componentStatus'][0]["serviceName"], "ACCUMULO") self.assertEqual(report['componentStatus'][0]["clusterName"], "c1") self.assertTrue(requestComponentStatus_mock.called)
def test_execute_status_command_expect_config( self, CustomServiceOrchestrator_mock, execute_command_mock, runCommand_mock, status_update_callback): csoMocks = [MagicMock()] CustomServiceOrchestrator_mock.side_effect = csoMocks csoMocks[0].status_commands_stdout = None csoMocks[0].status_commands_stderr = None dummy_controller = MagicMock() actionQueue = ActionQueue(AgentConfig("", ""), dummy_controller) runCommand_mock.return_value = {'configurations': {}} actionQueue.execute_status_command(self.status_command_with_config) report = actionQueue.result() self.assertEqual(len(report['componentStatus']), 1) self.assertEqual(report['componentStatus'][0]["componentName"], "ACCUMULO_MASTER") self.assertEqual(report['componentStatus'][0]["serviceName"], "ACCUMULO") self.assertEqual(report['componentStatus'][0]["clusterName"], "c1") self.assertEqual(report['componentStatus'][0]["configurations"], {}) self.assertFalse(runCommand_mock.called)
def test_build_long_result(self, result_mock): config = AgentConfig("", "") config.set('agent', 'prefix', 'tmp') config.set('agent', 'cache_dir', "/var/lib/ambari-agent/cache") config.set('agent', 'tolerate_download_failures', "true") dummy_controller = MagicMock() actionQueue = ActionQueue(config, dummy_controller) result_mock.return_value = { 'reports': [{'status': 'IN_PROGRESS', 'stderr': 'Read from /tmp/errors-3.txt', 'stdout': 'Read from /tmp/output-3.txt', 'clusterName': u'cc', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'taskId': 3, 'exitCode': 777}, {'status': 'COMPLETED', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': 'clusterName', 'roleCommand': 'UPGRADE', 'serviceName': 'serviceName', 'role': 'role', 'actionId': 17, 'taskId': 'taskId', 'exitCode': 0}, {'status': 'FAILED', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': u'cc', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'taskId': 3, 'exitCode': 13}, {'status': 'COMPLETED', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': u'cc', 'configurationTags': {'global': {'tag': 'v1'}}, 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'taskId': 3, 'exitCode': 0} ], 'componentStatus': [ {'status': 'HEALTHY', 'componentName': 'DATANODE'}, {'status': 'UNHEALTHY', 'componentName': 'NAMENODE'}, ], } heartbeat = Heartbeat(actionQueue, config) hb = heartbeat.build(10) hb['hostname'] = 'hostname' hb['timestamp'] = 'timestamp' expected = {'nodeStatus': {'status': 'HEALTHY', 'cause': 'NONE'}, 'timestamp': 'timestamp', 'hostname': 'hostname', 'responseId': 10, 'reports': [ {'status': 'IN_PROGRESS', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'Read from /tmp/errors-3.txt', 'stdout': 'Read from /tmp/output-3.txt', 'clusterName': u'cc', 'taskId': 3, 'exitCode': 777}, {'status': 'COMPLETED', 'roleCommand': 'UPGRADE', 'serviceName': 'serviceName', 'role': 'role', 'actionId': 17, 'stderr': 'stderr', 'stdout': 'out', 'clusterName': 'clusterName', 'taskId': 'taskId', 'exitCode': 0}, {'status': 'FAILED', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': u'cc', 'taskId': 3, 'exitCode': 13}, {'status': 'COMPLETED', 'stdout': 'out', 'configurationTags': {'global': {'tag': 'v1'}}, 'taskId': 3, 'exitCode': 0, 'roleCommand': u'INSTALL', 'clusterName': u'cc', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'stderr'}], 'componentStatus': [ {'status': 'HEALTHY', 'componentName': 'DATANODE'}, {'status': 'UNHEALTHY', 'componentName': 'NAMENODE'}]} self.assertEquals(hb, expected)
def test_heartbeatWithServer(self, dumpsMock, loadsMock, sleepMock, event_mock): original_value = self.controller.config self.controller.config = AgentConfig("", "") out = StringIO.StringIO() sys.stdout = out hearbeat = MagicMock() self.controller.heartbeat = hearbeat dumpsMock.return_value = "data" sendRequest = MagicMock(name="sendRequest") self.controller.sendRequest = sendRequest self.controller.responseId = 1 response = {"responseId":"2", "restartAgent":"false"} loadsMock.return_value = response def one_heartbeat(*args, **kwargs): self.controller.DEBUG_STOP_HEARTBEATING = True return "data" sendRequest.side_effect = one_heartbeat actionQueue = MagicMock() actionQueue.isIdle.return_value = True # one successful request, after stop self.controller.actionQueue = actionQueue self.controller.heartbeatWithServer() self.assertTrue(sendRequest.called) calls = [] def retry(*args, **kwargs): if len(calls) == 0: calls.append(1) response["responseId"] = "3" raise Exception() if len(calls) > 0: self.controller.DEBUG_STOP_HEARTBEATING = True return "data" # exception, retry, successful and stop sendRequest.side_effect = retry self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() self.assertEqual(1, self.controller.DEBUG_SUCCESSFULL_HEARTBEATS) # retry registration response["registrationCommand"] = "true" sendRequest.side_effect = one_heartbeat self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() self.assertTrue(self.controller.repeatRegistration) # components are not mapped response["registrationCommand"] = "false" response["hasMappedComponents"] = False sendRequest.side_effect = one_heartbeat self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() self.assertFalse(self.controller.hasMappedComponents) # components are mapped response["hasMappedComponents"] = True sendRequest.side_effect = one_heartbeat self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() self.assertTrue(self.controller.hasMappedComponents) # components are mapped del response["hasMappedComponents"] sendRequest.side_effect = one_heartbeat self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() self.assertTrue(self.controller.hasMappedComponents) # wrong responseId => restart response = {"responseId":"2", "restartAgent":"false"} loadsMock.return_value = response restartAgent = MagicMock(name="restartAgent") self.controller.restartAgent = restartAgent self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() restartAgent.assert_called_once_with() # executionCommands self.controller.responseId = 1 addToQueue = MagicMock(name="addToQueue") self.controller.addToQueue = addToQueue response["executionCommands"] = "executionCommands" self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() addToQueue.assert_has_calls([call("executionCommands")]) # statusCommands response["statusCommands"] = "statusCommands" self.controller.DEBUG_STOP_HEARTBEATING = False self.controller.heartbeatWithServer() addToQueue.assert_has_calls([call("statusCommands")]) # restartAgent command self.controller.responseId = 1 self.controller.DEBUG_STOP_HEARTBEATING = False response["restartAgent"] = "true" restartAgent = MagicMock(name="restartAgent") self.controller.restartAgent = restartAgent self.controller.heartbeatWithServer() restartAgent.assert_called_once_with() # actionQueue not idle self.controller.responseId = 1 self.controller.DEBUG_STOP_HEARTBEATING = False actionQueue.isIdle.return_value = False response["restartAgent"] = "false" self.controller.heartbeatWithServer() sleepMock.assert_called_with( self.controller.netutil.MINIMUM_INTERVAL_BETWEEN_HEARTBEATS) sys.stdout = sys.__stdout__ self.controller.sendRequest = Controller.Controller.sendRequest self.controller.sendRequest = Controller.Controller.addToQueue self.controller.config = original_value pass
def test_registration_build(self): tmpdir = tempfile.gettempdir() ver_dir = os.path.join(tmpdir, "infra") config = AgentConfig(tmpdir, ver_dir) config.set('agent', 'prefix', tmpdir) config.set('agent', 'current_ping_port', '33777') try: os.mkdir(ver_dir) except OSError as exception: if exception.errno != errno.EEXIST: raise pass ver_file = os.path.join(ver_dir, "version") with open(ver_file, "w") as text_file: text_file.write("1.3.0") register = Register(config) data = register.build(1) #print ("Register: " + pprint.pformat(data)) self.assertEquals(data['hostname'] != "", True, "hostname should not be empty") self.assertEquals(data['publicHostname'] != "", True, "publicHostname should not be empty") self.assertEquals(data['responseId'], 1) self.assertEquals(data['timestamp'] > 1353678475465L, True, "timestamp should not be empty") self.assertEquals(data['agentVersion'], '1.3.0', "agentVersion should not be empty") self.assertEquals(len(data), 5) self.assertEquals(os.path.join(tmpdir, "app/definition"), config.getResolvedPath("app_pkg_dir")) self.assertEquals(os.path.join(tmpdir, "app/install"), config.getResolvedPath("app_install_dir")) self.assertEquals(os.path.join(ver_dir, "app/log"), config.getResolvedPath("app_log_dir")) self.assertEquals(os.path.join(ver_dir, "infra/log"), config.getResolvedPath("log_dir")) self.assertEquals(os.path.join(ver_dir, "app/command-log"), config.getResolvedPath("app_task_dir")) os.remove(ver_file) os.removedirs(ver_dir)
def test_build_long_result(self, result_mock): config = AgentConfig("", "") config.set('agent', 'prefix', 'tmp') dummy_controller = MagicMock() actionQueue = ActionQueue(config, dummy_controller) result_mock.return_value = { 'reports': [{ 'status': 'IN_PROGRESS', 'stderr': 'Read from /tmp/errors-3.txt', 'stdout': 'Read from /tmp/output-3.txt', 'clusterName': u'cc', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'taskId': 3, 'exitCode': 777 }, { 'status': 'COMPLETED', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': 'clusterName', 'roleCommand': 'UPGRADE', 'serviceName': 'serviceName', 'role': 'role', 'actionId': 17, 'taskId': 'taskId', 'exitCode': 0 }, { 'status': 'FAILED', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': u'cc', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'taskId': 3, 'exitCode': 13 }, { 'status': 'COMPLETED', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': u'cc', 'configurationTags': { 'global': { 'tag': 'v1' } }, 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'taskId': 3, 'exitCode': 0 }], 'componentStatus': [ { 'status': 'HEALTHY', 'componentName': 'DATANODE', 'reportResult': True }, { 'status': 'UNHEALTHY', 'componentName': 'NAMENODE', 'reportResult': True }, { 'status': 'UNHEALTHY', 'componentName': 'HBASE_MASTER', 'reportResult': False }, ], } heartbeat = Heartbeat(actionQueue, config) hb = heartbeat.build({}, 10) hb['hostname'] = 'hostname' hb['timestamp'] = 'timestamp' expected = { 'nodeStatus': { 'status': 'HEALTHY', 'cause': 'NONE' }, 'timestamp': 'timestamp', 'hostname': 'hostname', 'responseId': 10, 'reports': [{ 'status': 'IN_PROGRESS', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'Read from /tmp/errors-3.txt', 'stdout': 'Read from /tmp/output-3.txt', 'clusterName': u'cc', 'taskId': 3, 'exitCode': 777 }, { 'status': 'COMPLETED', 'roleCommand': 'UPGRADE', 'serviceName': 'serviceName', 'role': 'role', 'actionId': 17, 'stderr': 'stderr', 'stdout': 'out', 'clusterName': 'clusterName', 'taskId': 'taskId', 'exitCode': 0 }, { 'status': 'FAILED', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'stderr', 'stdout': 'out', 'clusterName': u'cc', 'taskId': 3, 'exitCode': 13 }, { 'status': 'COMPLETED', 'stdout': 'out', 'configurationTags': { 'global': { 'tag': 'v1' } }, 'taskId': 3, 'exitCode': 0, 'roleCommand': u'INSTALL', 'clusterName': u'cc', 'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'stderr' }], 'componentStatus': [{ 'status': 'HEALTHY', 'componentName': 'DATANODE' }, { 'status': 'UNHEALTHY', 'componentName': 'NAMENODE' }] } self.assertEquals(hb, expected)