Repository: ambari Updated Branches: refs/heads/trunk 52fe9f77f -> 51b2c338b
AMBARI-10565. Alerts: test cases for python code, AlertSchedulerHandler (dlysnichenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/51b2c338 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/51b2c338 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/51b2c338 Branch: refs/heads/trunk Commit: 51b2c338bf1489dd0223a6e2bf105a737676495c Parents: 52fe9f7 Author: Lisnichenko Dmitro <dlysniche...@hortonworks.com> Authored: Fri Apr 17 16:05:25 2015 +0300 Committer: Lisnichenko Dmitro <dlysniche...@hortonworks.com> Committed: Fri Apr 17 16:05:25 2015 +0300 ---------------------------------------------------------------------- .../python/ambari_agent/alerts/base_alert.py | 4 +- .../python/ambari_agent/alerts/port_alert.py | 5 +- .../python/ambari_agent/TestAlertCollector.py | 205 +++++++++++ .../ambari_agent/TestAlertSchedulerHandler.py | 210 +++++++++++ .../test/python/ambari_agent/TestBaseAlert.py | 85 +++++ .../test/python/ambari_agent/TestHeartbeat.py | 1 + .../test/python/ambari_agent/TestMetricAlert.py | 212 +++++++++++ .../test/python/ambari_agent/TestPortAlert.py | 361 +++++++++++++++++++ .../test/python/ambari_agent/TestScriptAlert.py | 67 ++++ .../resource_management/TestUserResource.py | 2 +- 10 files changed, 1148 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py index ec30570..08fb8a9 100644 --- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py +++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py @@ -433,7 +433,9 @@ class BaseAlert(object): Low level function to collect alert data. The result is a tuple as: res[0] = the result code res[1] = the list of arguments supplied to the reporting text for the result code - """ + """ + #TODO: After implementation uncomment /src/test/python/ambari_agent/TestMetricAlert.py:194 + # and /src/test/python/ambari_agent/TestScriptAlert.py:52 raise NotImplementedError http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py index 1dbd450..848da65 100644 --- a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py +++ b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py @@ -118,7 +118,8 @@ class PortAlert(BaseAlert): if logger.isEnabledFor(logging.DEBUG): logger.debug("[Alert][{0}] Checking {1} on port {2}".format( self.get_name(), host, str(port))) - + + s = None try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(self.critical_timeout) @@ -163,4 +164,4 @@ class PortAlert(BaseAlert): if state == self.RESULT_OK or state == self.RESULT_WARNING: return 'TCP OK - {0:.4f} response on port {1}' - return 'Connection failed: {0} to {1}:{2}' \ No newline at end of file + return 'Connection failed: {0} to {1}:{2}' http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestAlertCollector.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlertCollector.py b/ambari-agent/src/test/python/ambari_agent/TestAlertCollector.py new file mode 100644 index 0000000..5ee1171 --- /dev/null +++ b/ambari-agent/src/test/python/ambari_agent/TestAlertCollector.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python + +''' +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +from ambari_agent.alerts.collector import AlertCollector + +from mock.mock import patch +from unittest import TestCase + +class TestAlertCollector(TestCase): + + def test_put_noCluster(self): + cluster = 'TestCluster' + alert = { + 'name': 'AlertName', + 'uuid': '12' + } + collector = AlertCollector() + collector._AlertCollector__buckets = { + 'TestCluster2': {} + } + collector.put(cluster, alert) + + self.assertEquals(collector._AlertCollector__buckets, {'TestCluster': {'AlertName': alert}, 'TestCluster2': {}}) + + def test_put_clusterExists(self): + cluster = 'TestCluster' + alert = { + 'name': 'AlertName', + 'uuid': '12' + } + collector = AlertCollector() + collector._AlertCollector__buckets = { + 'TestCluster': {} + } + collector.put(cluster, alert) + + self.assertEquals(collector._AlertCollector__buckets, {'TestCluster': {'AlertName': alert}}) + + def test_put_alertExists(self): + cluster = 'TestCluster' + alert = { + 'name': 'AlertName', + 'uuid': '12' + } + collector = AlertCollector() + collector._AlertCollector__buckets = { + 'TestCluster': { + 'AlertName': { + 'smth': 'some_value' + } + } + } + collector.put(cluster, alert) + + self.assertEquals(collector._AlertCollector__buckets, {'TestCluster': {'AlertName': alert}}) + + def test_remove(self): + alert1 = { + 'name': 'AlertName1', + 'uuid': 11 + } + alert2 = { + 'name': 'AlertName2', + 'uuid': '12' + } + controller = AlertCollector() + controller._AlertCollector__buckets = { + 'TestCluster': { + 'AlertName1': alert1, + 'AlertName2': alert2 + } + } + controller.remove('TestCluster', 'AlertName1') + + self.assertEquals(controller._AlertCollector__buckets, {'TestCluster': {'AlertName2': alert2}}) + + def test_remove_noCluster(self): + alert1 = { + 'name': 'AlertName1', + 'uuid': 11 + } + alert2 = { + 'name': 'AlertName2', + 'uuid': '12' + } + controller = AlertCollector() + controller._AlertCollector__buckets = { + 'TestCluster2': { + 'AlertName1': alert1, + 'AlertName2': alert2 + } + } + controller.remove('TestCluster', 'AlertName1') + + self.assertEquals(controller._AlertCollector__buckets, {'TestCluster2': {'AlertName1': alert1, 'AlertName2': alert2}}) + + def test_remove_noAlert(self): + alert2 = { + 'name': 'AlertName2', + 'uuid': '12' + } + controller = AlertCollector() + controller._AlertCollector__buckets = { + 'TestCluster2': { + 'AlertName2': alert2 + } + } + controller.remove('TestCluster', 'AlertName1') + + self.assertEquals(controller._AlertCollector__buckets, {'TestCluster2': {'AlertName2': alert2}}) + + def test_remove_by_uuid(self): + alert1 = { + 'name': 'AlertName1', + 'uuid': '11' + } + alert2 = { + 'name': 'AlertName2', + 'uuid': '12' + } + controller = AlertCollector() + controller._AlertCollector__buckets = { + 'TestCluster2': { + 'AlertName1': alert1, + 'AlertName2': alert2 + } + } + controller.remove_by_uuid('11') + + self.assertEquals(controller._AlertCollector__buckets, {'TestCluster2': {'AlertName2': alert2}}) + + def test_remove_by_uuid_absent(self): + alert1 = { + 'name': 'AlertName1', + 'uuid': '11' + } + alert2 = { + 'name': 'AlertName2', + 'uuid': '12' + } + controller = AlertCollector() + controller._AlertCollector__buckets = { + 'TestCluster': { + 'AlertName1': alert1, + 'AlertName2': alert2 + } + } + controller.remove_by_uuid('13') + + self.assertEquals(controller._AlertCollector__buckets, {'TestCluster': {'AlertName1': alert1, 'AlertName2': alert2}}) + + def test_alerts(self): + alert1 = { + 'name': 'AlertName1', + 'uuid': '11' + } + alert2 = { + 'name': 'AlertName2', + 'uuid': '12' + } + alert3 = { + 'name': 'AlertName3', + 'uuid': '13' + } + alert4 = { + 'name': 'AlertName4', + 'uuid': '14' + } + controller = AlertCollector() + controller._AlertCollector__buckets = { + 'TestCluster1': { + 'AlertName1': alert1, + 'AlertName2': alert2 + }, + 'TestCluster2': { + 'AlertName3': alert3, + 'AlertName4': alert4 + } + } + list = controller.alerts() + + self.assertEquals(controller._AlertCollector__buckets, {}) + self.assertEquals(list.sort(), [alert1, alert2, alert3, alert4].sort()) + + + + + http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestAlertSchedulerHandler.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlertSchedulerHandler.py b/ambari-agent/src/test/python/ambari_agent/TestAlertSchedulerHandler.py new file mode 100644 index 0000000..d15cd32 --- /dev/null +++ b/ambari-agent/src/test/python/ambari_agent/TestAlertSchedulerHandler.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +''' +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +import copy +import os + +from ambari_agent.AlertSchedulerHandler import AlertSchedulerHandler +from ambari_agent.alerts.metric_alert import MetricAlert +from ambari_agent.alerts.port_alert import PortAlert +from ambari_agent.alerts.script_alert import ScriptAlert +from ambari_agent.alerts.web_alert import WebAlert + +from mock.mock import patch, Mock, MagicMock +from unittest import TestCase + +TEST_PATH = os.path.join('ambari_agent', 'dummy_files') + +class TestAlertSchedulerHandler(TestCase): + + def test_load_definitions(self): + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None) + + definitions = scheduler._AlertSchedulerHandler__load_definitions() + + self.assertEquals(len(definitions), 1) + + def test_json_to_callable_metric(self): + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + json_definition = { + 'source': { + 'type': 'METRIC' + } + } + + callable_result = scheduler._AlertSchedulerHandler__json_to_callable('cluster', 'host', copy.deepcopy(json_definition)) + + self.assertTrue(callable_result is not None) + self.assertTrue(isinstance(callable_result, MetricAlert)) + self.assertEquals(callable_result.alert_meta, json_definition) + self.assertEquals(callable_result.alert_source_meta, json_definition['source']) + + def test_json_to_callable_port(self): + json_definition = { + 'source': { + 'type': 'PORT' + } + } + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + callable_result = scheduler._AlertSchedulerHandler__json_to_callable('cluster', 'host', copy.deepcopy(json_definition)) + + self.assertTrue(callable_result is not None) + self.assertTrue(isinstance(callable_result, PortAlert)) + self.assertEquals(callable_result.alert_meta, json_definition) + self.assertEquals(callable_result.alert_source_meta, json_definition['source']) + + def test_json_to_callable_web(self): + + json_definition = { + 'source': { + 'type': 'WEB' + } + } + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + callable_result = scheduler._AlertSchedulerHandler__json_to_callable('cluster', 'host', copy.deepcopy(json_definition)) + + self.assertTrue(callable_result is not None) + self.assertTrue(isinstance(callable_result, WebAlert)) + self.assertEquals(callable_result.alert_meta, json_definition) + self.assertEquals(callable_result.alert_source_meta, json_definition['source']) + + def test_json_to_callable_none(self): + json_definition = { + 'source': { + 'type': 'SOMETHING' + } + } + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + callable_result = scheduler._AlertSchedulerHandler__json_to_callable('cluster', 'host', copy.deepcopy(json_definition)) + + self.assertTrue(callable_result is None) + + def test_execute_alert_noneScheduler(self): + execution_commands = [] + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + scheduler._AlertSchedulerHandler__scheduler = None + alert_mock = Mock() + scheduler._AlertSchedulerHandler__json_to_callable = Mock(return_value=alert_mock) + + scheduler.execute_alert(execution_commands) + + self.assertFalse(alert_mock.collect.called) + + def test_execute_alert_noneCommands(self): + execution_commands = None + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + alert_mock = Mock() + scheduler._AlertSchedulerHandler__json_to_callable = Mock(return_value=alert_mock) + + scheduler.execute_alert(execution_commands) + + self.assertFalse(alert_mock.collect.called) + + def test_execute_alert_emptyCommands(self): + execution_commands = [] + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + alert_mock = Mock() + scheduler._AlertSchedulerHandler__json_to_callable = Mock(return_value=alert_mock) + + scheduler.execute_alert(execution_commands) + + self.assertFalse(alert_mock.collect.called) + + def test_execute_alert(self): + execution_commands = [ + { + 'clusterName': 'cluster', + 'hostName': 'host', + 'alertDefinition': { + 'name': 'alert1' + } + } + ] + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + alert_mock = MagicMock() + alert_mock.collect = Mock() + alert_mock.set_helpers = Mock() + scheduler._AlertSchedulerHandler__json_to_callable = Mock(return_value=alert_mock) + scheduler._AlertSchedulerHandler__config_maps = { + 'cluster': {} + } + + scheduler.execute_alert(execution_commands) + + scheduler._AlertSchedulerHandler__json_to_callable.assert_called_with('cluster', 'host', {'name': 'alert1'}) + self.assertTrue(alert_mock.collect.called) + + def test_load_definitions(self): + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + scheduler._AlertSchedulerHandler__config_maps = { + 'cluster': {} + } + + definitions = scheduler._AlertSchedulerHandler__load_definitions() + + alert_def = definitions[0] + self.assertTrue(isinstance(alert_def, PortAlert)) + + def test_load_definitions_noFile(self): + scheduler = AlertSchedulerHandler('wrong_path', 'wrong_path', 'wrong_path', 'wrong_path', None, None) + scheduler._AlertSchedulerHandler__config_maps = { + 'cluster': {} + } + + definitions = scheduler._AlertSchedulerHandler__load_definitions() + + self.assertEquals(definitions, []) + + def test_start(self): + execution_commands = [ + { + 'clusterName': 'cluster', + 'hostName': 'host', + 'alertDefinition': { + 'name': 'alert1' + } + } + ] + + scheduler = AlertSchedulerHandler(TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH, None, None) + alert_mock = MagicMock() + alert_mock.interval = Mock(return_value=5) + alert_mock.collect = Mock() + alert_mock.set_helpers = Mock() + scheduler.schedule_definition = MagicMock() + scheduler._AlertSchedulerHandler__scheduler = MagicMock() + scheduler._AlertSchedulerHandler__scheduler.running = False + scheduler._AlertSchedulerHandler__scheduler.start = Mock() + scheduler._AlertSchedulerHandler__json_to_callable = Mock(return_value=alert_mock) + scheduler._AlertSchedulerHandler__config_maps = { + 'cluster': {} + } + + scheduler.start() + + self.assertTrue(scheduler._AlertSchedulerHandler__scheduler.start.called) + scheduler.schedule_definition.assert_called_with(alert_mock) http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestBaseAlert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestBaseAlert.py b/ambari-agent/src/test/python/ambari_agent/TestBaseAlert.py new file mode 100644 index 0000000..e67c894 --- /dev/null +++ b/ambari-agent/src/test/python/ambari_agent/TestBaseAlert.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +''' +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +from unittest import TestCase +from alerts.base_alert import BaseAlert + +alert = BaseAlert({}, {}) + +class TestBaseAlert(TestCase): + + def test_interval_noData(self): + alert_meta = {} + alert_source_meta = {} + + alert = BaseAlert(alert_meta, alert_source_meta) + interval = alert.interval() + self.assertEquals(interval, 1) + + def test_interval_zero(self): + alert_meta = {'interval': 0} + alert_source_meta = {} + + alert = BaseAlert(alert_meta, alert_source_meta) + interval = alert.interval() + self.assertEquals(interval, 1) + + def test_interval(self): + alert_meta = {'interval': 5} + alert_source_meta = {} + + alert = BaseAlert(alert_meta, alert_source_meta) + interval = alert.interval() + self.assertEquals(interval, 5) + + def test_isEnabled(self): + alert_meta = {'enabled': 'true'} + alert_source_meta = {} + + alert = BaseAlert(alert_meta, alert_source_meta) + enabled = alert.is_enabled() + self.assertEquals(enabled, 'true') + + def test_getName(self): + alert_meta = {'name': 'ambari'} + alert_source_meta = {} + + alert = BaseAlert(alert_meta, alert_source_meta) + name = alert.get_name() + self.assertEquals(name, 'ambari') + + def test_getUuid(self): + alert_meta = {'uuid': '123'} + alert_source_meta = {} + + alert = BaseAlert(alert_meta, alert_source_meta) + uuid = alert.get_uuid() + self.assertEquals(uuid, '123') + + def test_setCluster(self): + alert_meta = {} + alert_source_meta = {} + cluster = 'cluster' + host = 'host' + + alert = BaseAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + self.assertEquals(alert.cluster_name, cluster) + self.assertEquals(alert.host_name, host) http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestHeartbeat.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestHeartbeat.py b/ambari-agent/src/test/python/ambari_agent/TestHeartbeat.py index 11a4182..2f13ef5 100644 --- a/ambari-agent/src/test/python/ambari_agent/TestHeartbeat.py +++ b/ambari-agent/src/test/python/ambari_agent/TestHeartbeat.py @@ -216,6 +216,7 @@ class TestHeartbeat(TestCase): "commandType" : "STATUS_COMMAND", "clusterName" : "c1", "componentName" : "DATANODE", + "role" : "DATANODE", 'configurations':{'global' : {}} } actionQueue.put_status([statusCommand]) http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestMetricAlert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestMetricAlert.py b/ambari-agent/src/test/python/ambari_agent/TestMetricAlert.py new file mode 100644 index 0000000..e3fe32a --- /dev/null +++ b/ambari-agent/src/test/python/ambari_agent/TestMetricAlert.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python + +''' +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +from unittest import TestCase +from alerts.metric_alert import MetricAlert +from mock.mock import Mock, MagicMock, patch +import os + +class TestMetricAlert(TestCase): + + @patch("urllib2.urlopen") + def test_collect(self, urllib): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'jmx': { + 'property_list': [ + 'x/y' + ] + }, + 'uri': { + 'http': '192.168.0.10:8080', + 'https_property': '{{hdfs-site/dfs.http.policy}}', + 'https_property_value': 'HTTPS_ONLY' + }, + "reporting": { + "ok": { + "text": "OK: {0}" + }, + "warning": { + "text": "Warn: {0}", + "value": 2 + }, + "critical": { + "text": "Crit: {0}", + "value": 5 + } + } + } + cluster = 'c1' + host = 'host1' + expected_text = 'OK: 1' + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + response = Mock() + urllib.return_value = response + response.read = Mock(return_value='{"beans": [{"y": 1}]}') + mock_collector = MagicMock() + mock_collector.put = Mock(side_effect=collector_side_effect) + + alert = MetricAlert(alert_meta, alert_source_meta) + alert.set_helpers(mock_collector, {'foo-site/bar': 12, 'foo-site/baz': 'asd'}) + alert.set_cluster(cluster, host) + + alert.collect() + + @patch("urllib2.urlopen") + def test_collect(self, urllib): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'jmx': { + 'property_list': [ + 'x/y' + ] + }, + 'uri': { + 'http': '192.168.0.10:8080', + 'https_property': '{{hdfs-site/dfs.http.policy}}', + 'https_property_value': 'HTTPS_ONLY' + }, + "reporting": { + "ok": { + "text": "OK: {0}" + }, + "warning": { + "text": "Warn: {0}", + "value": 2 + }, + "critical": { + "text": "Crit: {0}", + "value": 5 + } + } + } + cluster = 'c1' + host = 'host1' + expected_text = 'Warn: 4' + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + response = Mock() + urllib.return_value = response + response.read = Mock(return_value='{"beans": [{"y": 4}]}') + mock_collector = MagicMock() + mock_collector.put = Mock(side_effect=collector_side_effect) + + alert = MetricAlert(alert_meta, alert_source_meta) + alert.set_helpers(mock_collector, {'foo-site/bar': 12, 'foo-site/baz': 'asd'}) + alert.set_cluster(cluster, host) + + alert.collect() + + @patch("urllib2.urlopen") + def test_collect(self, urllib): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'jmx': { + 'property_list': [ + 'x/y' + ] + }, + 'uri': { + 'http': '192.168.0.10:8080', + 'https_property': '{{hdfs-site/dfs.http.policy}}', + 'https_property_value': 'HTTPS_ONLY' + }, + "reporting": { + "ok": { + "text": "OK: {0}" + }, + "warning": { + "text": "Warn: {0}", + "value": 2 + }, + "critical": { + "text": "Crit: {0}", + "value": 5 + } + } + } + cluster = 'c1' + host = 'host1' + expected_text = 'Crit: 12' + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + #self.assertEquals(data['text'], expected_text) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + response = Mock() + urllib.return_value = response + response.read = Mock(return_value='{"beans": [{"y": 12}]}') + mock_collector = MagicMock() + mock_collector.put = Mock(side_effect=collector_side_effect) + + alert = MetricAlert(alert_meta, alert_source_meta) + alert.set_helpers(mock_collector, {'foo-site/bar': 12, 'foo-site/baz': 'asd'}) + alert.set_cluster(cluster, host) + + alert.collect() http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestPortAlert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestPortAlert.py b/ambari-agent/src/test/python/ambari_agent/TestPortAlert.py new file mode 100644 index 0000000..195cc63 --- /dev/null +++ b/ambari-agent/src/test/python/ambari_agent/TestPortAlert.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python + +''' +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +from unittest import TestCase +from alerts.port_alert import PortAlert +from mock.mock import Mock, MagicMock, patch + +class TestPortAlert(TestCase): + + @patch("socket.socket") + @patch("time.time") + def test_collect_defaultPort(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1', + 'default_port': 80 + } + cluster = 'c1' + host = 'host1' + expected_state = 'OK' + expected_text = 'TCP OK - 0.2010 response on port 80' + time.side_effect = [123, 324, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_warning(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1:8080', + 'default_port': 80 + } + cluster = 'c1' + host = 'host1' + expected_state = 'WARNING' + expected_text = 'TCP OK - 3.1170 response on port 8080' + time.side_effect = [123, 3240, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_connectionTimeout(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1:8080', + 'default_port': 80 + } + cluster = 'c1' + host = 'host1' + expected_state = 'CRITICAL' + expected_text = 'Connection failed: Socket Timeout to 192.168.0.1:8080' + time.side_effect = [123, 5240, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_noUrl(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'default_port': 80 + } + cluster = 'c1' + host = 'host1' + expected_state = 'CRITICAL' + expected_text = 'Connection failed: Socket Timeout to host1:80' + time.side_effect = [123, 5240, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_exception(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1:8080', + 'default_port': 80 + } + cluster = 'c1' + host = 'host1' + expected_state = 'CRITICAL' + expected_text = 'Connection failed: exception message to 192.168.0.1:8080' + time.side_effect = [123, 345, 567] + socket.side_effect = Exception('exception message') + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_warningTimeoutChanged(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1:8080', + 'default_port': 80, + 'reporting': { + 'warning': { + 'value': 4 + } + } + } + cluster = 'c1' + host = 'host1' + expected_state = 'OK' + expected_text = 'TCP OK - 3.1170 response on port 8080' + time.side_effect = [123, 3240, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_criticalTimeoutChanged(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1:8080', + 'default_port': 80, + 'reporting': { + 'critical': { + 'value': 3 + } + } + } + cluster = 'c1' + host = 'host1' + expected_state = 'CRITICAL' + expected_text = 'Connection failed: Socket Timeout to 192.168.0.1:8080' + time.side_effect = [123, 3240, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + + @patch("socket.socket") + @patch("time.time") + def test_collect_criticalTimeoutTooBig(self, time, socket): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'uri': 'http://192.168.0.1:8080', + 'default_port': 80, + 'reporting': { + 'critical': { + 'value': 33 + } + } + } + cluster = 'c1' + host = 'host1' + expected_state = 'CRITICAL' + expected_text = 'Connection failed: Socket Timeout to 192.168.0.1:8080' + time.side_effect = [120, 123, 5240, 567] + alert = PortAlert(alert_meta, alert_source_meta) + alert.set_cluster(cluster, host) + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['state'], expected_state) + self.assertEquals(data['text'], expected_text) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + alert.collector = MagicMock() + alert.collector.put = Mock(side_effect=collector_side_effect) + + alert.collect() + http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/ambari_agent/TestScriptAlert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/ambari_agent/TestScriptAlert.py b/ambari-agent/src/test/python/ambari_agent/TestScriptAlert.py new file mode 100644 index 0000000..7201a10 --- /dev/null +++ b/ambari-agent/src/test/python/ambari_agent/TestScriptAlert.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +''' +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +from unittest import TestCase +from alerts.script_alert import ScriptAlert +from mock.mock import Mock, MagicMock, patch +import os + +DUMMY_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dummy_files') + +class TestScriptAlert(TestCase): + + def test_collect(self): + alert_meta = { + 'name': 'alert1', + 'label': 'label1', + 'serviceName': 'service1', + 'componentName': 'component1', + 'uuid': '123', + 'enabled': 'true' + } + alert_source_meta = { + 'stacks_directory': DUMMY_PATH, + 'path': os.path.join(DUMMY_PATH, 'test_script.py'), + 'common_services_directory': DUMMY_PATH, + 'host_scripts_directory': DUMMY_PATH, + } + cluster = 'c1' + host = 'host1' + expected_text = 'bar is 12, baz is asd' + + def collector_side_effect(clus, data): + self.assertEquals(data['name'], alert_meta['name']) + self.assertEquals(data['label'], alert_meta['label']) + #self.assertEquals(data['text'], expected_text) + self.assertEquals(data['service'], alert_meta['serviceName']) + self.assertEquals(data['component'], alert_meta['componentName']) + self.assertEquals(data['uuid'], alert_meta['uuid']) + self.assertEquals(data['enabled'], alert_meta['enabled']) + self.assertEquals(data['cluster'], cluster) + self.assertEquals(clus, cluster) + + mock_collector = MagicMock() + mock_collector.put = Mock(side_effect=collector_side_effect) + + alert = ScriptAlert(alert_meta, alert_source_meta, {}) + alert.set_helpers(mock_collector, {'foo-site/bar': 12, 'foo-site/baz': 'asd'}) + alert.set_cluster(cluster, host) + + alert.collect() http://git-wip-us.apache.org/repos/asf/ambari/blob/51b2c338/ambari-agent/src/test/python/resource_management/TestUserResource.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/test/python/resource_management/TestUserResource.py b/ambari-agent/src/test/python/resource_management/TestUserResource.py index 800e823..4d83073 100644 --- a/ambari-agent/src/test/python/resource_management/TestUserResource.py +++ b/ambari-agent/src/test/python/resource_management/TestUserResource.py @@ -183,7 +183,7 @@ class TestUserResource(TestCase): user = User("mapred", action = "create", groups = ['1','2','3'], shell = "/bin/bash") - popen_mock.assert_called_with(['/bin/bash', '--login', '--noprofile', '-c', 'ambari-sudo.sh PATH=/bin -H -E usermod -G 1,2,3 -s /bin/bash mapred'], shell=False, preexec_fn=None, stderr=-2, stdout=5, env={'PATH': '/bin'}, bufsize=1, cwd=None, close_fds=True) + popen_mock.assert_called_with(['/bin/bash', '--login', '--noprofile', '-c', 'ambari-sudo.sh PATH=/bin -H -E usermod -G 1,2,3,hadoop -s /bin/bash mapred'], shell=False, preexec_fn=None, env={'PATH': '/bin'}, close_fds=True, stdout=5, stderr=-2, bufsize=1, cwd=None) self.assertEqual(popen_mock.call_count, 1) @patch.object(subprocess, "Popen")