You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2015/04/17 15:05:55 UTC
ambari git commit: AMBARI-10565. Alerts: test cases for python code,
AlertSchedulerHandler (dlysnichenko)
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 <dl...@hortonworks.com>
Authored: Fri Apr 17 16:05:25 2015 +0300
Committer: Lisnichenko Dmitro <dl...@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")