text: # -*- coding: utf-8 -*-
  # pylint: disable=invalid-name
  
  # 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
  
  
  def minion_in_returns(minion, lines):
      return bool([True for line in lines if line == '{0}:'.format(minion)])
  
  
  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]))
  