123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- # -*- coding: utf-8 -*-
- # Import python libs
- from __future__ import absolute_import
- import time
- # Import Salt Testing libs
- from tests.support.case import ShellCase
- from tests.support.helpers import flaky, dedent
- from tests.support.mixins import ShellCaseCommonTestsMixin
- from tests.support.unit import skipIf
- # Import salt libs
- import salt.utils.files
- import salt.utils.yaml
- import pytest
- def minion_in_returns(minion, lines):
- return bool([True for line in lines if line == '{0}:'.format(minion)])
- @pytest.mark.windows_whitelisted
- class MatchTest(ShellCase, ShellCaseCommonTestsMixin):
- '''
- Test salt matchers
- '''
- _call_binary_ = 'salt'
- def test_list(self):
- '''
- test salt -L matcher
- '''
- data = self.run_salt('-L minion test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('-L minion,sub_minion test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- # compound matcher tests: 11
- def test_compound_min_with_grain(self):
- '''
- test salt compound matcher
- '''
- data = self.run_salt('-C "min* and G@test_grain:cheese" test.ping')
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is False
- def test_compound_and_not_grain(self):
- data = self.run_salt('-C "min* and not G@test_grain:foo" test.ping')
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is False
- def test_compound_not_grain(self):
- data = self.run_salt('-C "min* not G@test_grain:foo" test.ping')
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is False
- def test_compound_pcre_grain_and_grain(self):
- match = 'P@test_grain:^cheese$ and * and G@test_grain:cheese'
- data = self.run_salt('-t 1 -C "{0}" test.ping'.format(match))
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is False
- def test_compound_list_and_pcre_minion(self):
- match = 'L@sub_minion and E@.*'
- data = self.run_salt('-t 1 -C "{0}" test.ping'.format(match))
- assert minion_in_returns('sub_minion', data) is True
- assert minion_in_returns('minion', data) is False
- def test_compound_not_sub_minion(self):
- data = self.run_salt('-C "not sub_minion" test.ping')
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is False
- def test_compound_all_and_not_grains(self):
- data = self.run_salt('-C "* and ( not G@test_grain:cheese )" test.ping')
- assert minion_in_returns('minion', data) is False
- assert minion_in_returns('sub_minion', data) is True
- def test_compound_grain_regex(self):
- data = self.run_salt('-C "G%@planets%merc*" test.ping')
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is False
- def test_coumpound_pcre_grain_regex(self):
- data = self.run_salt('-C "P%@planets%^(mercury|saturn)$" test.ping')
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is True
- @skipIf(True, 'This test is unreliable. Need to investigate why more deeply.')
- @flaky
- def test_compound_pillar(self):
- data = self.run_salt("-C 'I%@companions%three%sarah*' test.ping")
- assert minion_in_returns('minion', data) is True
- assert minion_in_returns('sub_minion', data) is True
- @skipIf(True, 'This test is unreliable. Need to investigate why more deeply.')
- @flaky
- def test_coumpound_pillar_pcre(self):
- data = self.run_salt("-C 'J%@knights%^(Lancelot|Galahad)$' test.ping")
- self.assertTrue(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- # The multiline nodegroup tests are failing in develop.
- # This needs to be fixed for Fluorine. @skipIf wasn't used, because
- # the rest of the assertions above pass just fine, so we don't want
- # to bypass the whole test.
- # time.sleep(2)
- # data = self.run_salt("-C 'N@multiline_nodegroup' test.ping")
- # self.assertTrue(minion_in_returns('minion', data))
- # self.assertTrue(minion_in_returns('sub_minion', data))
- # time.sleep(2)
- # data = self.run_salt("-C 'N@multiline_nodegroup not sub_minion' test.ping")
- # self.assertTrue(minion_in_returns('minion', data))
- # self.assertFalse(minion_in_returns('sub_minion', data))
- # data = self.run_salt("-C 'N@multiline_nodegroup not @fakenodegroup not sub_minion' test.ping")
- # self.assertTrue(minion_in_returns('minion', data))
- # self.assertFalse(minion_in_returns('sub_minion', data))
- def test_nodegroup(self):
- '''
- test salt nodegroup matcher
- '''
- data = self.run_salt('-N min test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertFalse(minion_in_returns('sub_minion', data))
- time.sleep(2)
- data = self.run_salt('-N sub_min test.ping')
- self.assertFalse(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- time.sleep(2)
- data = self.run_salt('-N mins test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- time.sleep(2)
- data = self.run_salt('-N unknown_nodegroup test.ping')
- self.assertFalse(minion_in_returns('minion', data))
- self.assertFalse(minion_in_returns('sub_minion', data))
- time.sleep(2)
- data = self.run_salt('-N redundant_minions test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- time.sleep(2)
- data = '\n'.join(self.run_salt('-N nodegroup_loop_a test.ping'))
- self.assertIn('No minions matched', data)
- time.sleep(2)
- data = self.run_salt("-N multiline_nodegroup test.ping")
- self.assertTrue(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- def test_nodegroup_list(self):
- data = self.run_salt('-N list_group test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- data = self.run_salt('-N list_group2 test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertTrue(minion_in_returns('sub_minion', data))
- data = self.run_salt('-N one_list_group test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertFalse(minion_in_returns('sub_minion', data))
- data = self.run_salt('-N one_minion_list test.ping')
- self.assertTrue(minion_in_returns('minion', data))
- self.assertFalse(minion_in_returns('sub_minion', data))
- def test_glob(self):
- '''
- test salt glob matcher
- '''
- data = self.run_salt('minion test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('"*" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- def test_regex(self):
- '''
- test salt regex matcher
- '''
- data = self.run_salt('-E "^minion$" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('-E ".*" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- def test_grain(self):
- '''
- test salt grain matcher
- '''
- # Sync grains
- self.run_salt('-t1 "*" saltutil.sync_grains')
- # First-level grain (string value)
- data = self.run_salt('-t 1 -G "test_grain:cheese" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('-G "test_grain:spam" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertNotIn('minion', data.replace('sub_minion', 'stub'))
- # Custom grain
- data = self.run_salt('-t 1 -G "match:maker" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- # First-level grain (list member)
- data = self.run_salt('-t 1 -G "planets:earth" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('-G "planets:saturn" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertNotIn('minion', data.replace('sub_minion', 'stub'))
- data = self.run_salt('-G "planets:pluto" test.ping')
- expect = None
- if self.master_opts['transport'] in ('zeromq', 'tcp'):
- expect = (
- 'No minions matched the target. '
- 'No command was sent, no jid was '
- 'assigned.'
- )
- self.assertEqual(
- ''.join(data),
- expect
- )
- # Nested grain (string value)
- data = self.run_salt('-t 1 -G "level1:level2:foo" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('-G "level1:level2:bar" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertNotIn('minion', data.replace('sub_minion', 'stub'))
- # Nested grain (list member)
- data = self.run_salt('-t 1 -G "companions:one:ian" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('-G "companions:two:jamie" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertNotIn('minion', data.replace('sub_minion', 'stub'))
- # Test for issue: https://github.com/saltstack/salt/issues/19651
- data = self.run_salt('-G "companions:*:susan" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion:', data)
- self.assertNotIn('sub_minion', data)
- # Test to ensure wildcard at end works correctly
- data = self.run_salt('-G "companions:one:*" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion:', data)
- self.assertNotIn('sub_minion', data)
- # Test to ensure multiple wildcards works correctly
- data = self.run_salt('-G "companions:*:*" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion:', data)
- self.assertIn('sub_minion', data)
- def test_regrain(self):
- '''
- test salt grain matcher
- '''
- data = self.run_salt(
- '-t 1 --grain-pcre "test_grain:^cheese$" test.ping'
- )
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertNotIn('sub_minion', data)
- data = self.run_salt('--grain-pcre "test_grain:.*am$" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertNotIn('minion', data.replace('sub_minion', 'stub'))
- def test_pillar(self):
- '''
- test pillar matcher
- '''
- # First-level pillar (string value)
- data = self.run_salt('-I "monty:python" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- # First-level pillar (string value, only in sub_minion)
- data = self.run_salt('-I "sub:sub_minion" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertNotIn('minion', data.replace('sub_minion', 'stub'))
- # First-level pillar (list member)
- data = self.run_salt('-I "knights:Bedevere" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- # Nested pillar (string value)
- data = self.run_salt('-I "level1:level2:foo" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- # Nested pillar (list member)
- data = self.run_salt('-I "companions:three:sarah jane" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- def test_repillar(self):
- '''
- test salt pillar PCRE matcher
- '''
- data = self.run_salt('-J "monty:^(python|hall)$" test.ping')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- data = self.run_salt('--pillar-pcre "knights:^(Robin|Lancelot)$" test.ping')
- data = '\n'.join(data)
- self.assertIn('sub_minion', data)
- self.assertIn('minion', data.replace('sub_minion', 'stub'))
- def test_ipcidr(self):
- subnets_data = self.run_salt('--out yaml "*" network.subnets')
- yaml_data = salt.utils.yaml.safe_load('\n'.join(subnets_data))
- # We're just after the first defined subnet from 'minion'
- subnet = yaml_data['minion'][0]
- data = self.run_salt('-S {0} test.ping'.format(subnet))
- data = '\n'.join(data)
- self.assertIn('minion', data)
- self.assertIn('sub_minion', data)
- def test_static(self):
- '''
- test salt static call
- '''
- data = self.run_salt('minion test.ping --static')
- data = '\n'.join(data)
- self.assertIn('minion', data)
- def test_salt_documentation(self):
- '''
- Test to see if we're supporting --doc
- '''
- expect_to_find = 'test.ping:'
- stdout, stderr = self.run_salt('-d "*" test', catch_stderr=True)
- error_msg = dedent('''
- Failed to find \'{expected}\' in output
- {sep}
- --- STDOUT -----
- {stdout}
- {sep}
- --- STDERR -----
- {stderr}
- {sep}
- '''.format(sep='-' * 80,
- expected=expect_to_find,
- stdout='\n'.join(stdout).strip(),
- stderr='\n'.join(stderr).strip()))
- self.assertIn(expect_to_find, stdout, msg=error_msg)
- def test_salt_documentation_too_many_arguments(self):
- '''
- Test to see if passing additional arguments shows an error
- '''
- data = self.run_salt('-d minion salt ldap.search "filter=ou=People"', catch_stderr=True)
- self.assertIn('You can only get documentation for one method at one time', '\n'.join(data[1]))
|