diff --git a/salt/client/__init__.py b/salt/client/__init__.py index 3a0565c728..bb116ee242 100644 --- a/salt/client/__init__.py +++ b/salt/client/__init__.py @@ -228,7 +228,7 @@ class LocalClient(object): kwarg=None, **kwargs): ''' - Asyncronously send a command to connected minions + Asynchronously send a command to connected minions Prep the job directory and publish a command to any targeted minions. @@ -269,7 +269,7 @@ class LocalClient(object): kwarg=None, **kwargs): ''' - Asyncronously send a command to connected minions + Asynchronously send a command to connected minions The function signature is the same as :py:meth:`cmd` with the following exceptions. @@ -392,7 +392,7 @@ class LocalClient(object): kwarg=None, **kwargs): ''' - Syncronously execute a command on targeted minions + Synchronously execute a command on targeted minions The cmd method will execute and wait for the timeout period for all minions to reply, then it will return all minion data at once. diff --git a/tests/unit/client_test.py b/tests/unit/client_test.py new file mode 100644 index 0000000000..2caef6eedf --- /dev/null +++ b/tests/unit/client_test.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +''' + :codauthor: :email:`Mike Place ` +''' + +# Import Salt Testing libs +from salttesting import TestCase, skipIf +from salttesting.helpers import ensure_in_syspath +from salttesting.mock import patch, call, NO_MOCK, NO_MOCK_REASON, DEFAULT, MagicMock +from salt import client +from salt.exceptions import EauthAuthenticationError, SaltInvocationError + +ensure_in_syspath('../') + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +class LocalClientTestCase(TestCase): + def setUp(self): + self.local_client = client.LocalClient() + + def test_create_local_client(self): + local_client = client.LocalClient() + self.assertIsInstance(local_client, client.LocalClient, "LocalClient did not create a LocalClient instance") + + def test_check_pub_data(self): + just_minions = {'minions': ['m1', 'm2']} + jid_no_minions = {'jid': '1234', 'minions': []} + valid_pub_data = {'minions': ['m1', 'm2'], 'jid': '1234'} + + self.assertRaises(EauthAuthenticationError, self.local_client._check_pub_data, None) + self.assertDictEqual({}, + self.local_client._check_pub_data(just_minions), + "Did not handle lack of jid correctly") + + self.assertDictEqual( + {}, + self.local_client._check_pub_data({'jid': '0'}), + "Passing JID of zero is not handled gracefully") + + with patch.dict(self.local_client.opts, {}): + self.local_client._check_pub_data(jid_no_minions) + + self.assertDictEqual(valid_pub_data, self.local_client._check_pub_data(valid_pub_data)) + + @patch('salt.client.LocalClient.cmd', return_value={'minion1': ['first.func', 'second.func'], + 'minion2': ['first.func', 'second.func']}) + def test_cmd_subset(self, cmd_mock): + with patch('salt.client.LocalClient.cmd_cli') as cmd_cli_mock: + self.local_client.cmd_subset('*', 'first.func', sub=1, cli=True) + cmd_cli_mock.assert_called_with(['minion1'], 'first.func', (), kwarg=None, expr_form='list', + ret=['first.func', 'second.func']) + + + self.local_client.cmd_subset('*', 'first.func', sub=10, cli=True) + cmd_cli_mock.assert_called_with(['minion1', 'minion2'], 'first.func', (), kwarg=None, expr_form='list', + ret=['first.func', 'second.func']) + + def test_pub(self): + # Make sure we cleanly return if the publisher isn't running + with patch('os.path.exists', return_value=False): + ret = self.local_client.pub('*', 'test.ping') + expected_ret = {'jid': '0', 'minions': []} + self.assertDictEqual(ret, expected_ret) + + # Check nodegroups behavior + with patch('os.path.exists', return_value=True): + with patch.dict(self.local_client.opts, + {'nodegroups': + {'group1': 'L@foo.domain.com,bar.domain.com,baz.domain.com or bl*.domain.com'}}): + # Do we raise an exception if the nodegroup can't be matched? + self.assertRaises(SaltInvocationError, + self.local_client.pub, + 'non_existant_group', 'test.ping', expr_form='nodegroup') + + + + + + +