def test_multi(self): now = 1379406823.9 fo = MockStdout() with mock.patch('dnf.cli.progress._term_width', return_value=60), \ mock.patch('dnf.cli.progress.time', lambda: now): p = dnf.cli.progress.MultiFileProgressMeter(fo) p.start(2, 30) pload1 = FakePayload('foo', 10.0) pload2 = FakePayload('bar', 20.0) for i in range(11): p.progress(pload1, float(i)) if i == 10: p.end(pload1, None, None) now += 0.5 p.progress(pload2, float(i*2)) self.assertEqual(self._REFERENCE_TAB[i], fo.visible_lines()) if i == 10: p.end(pload2, dnf.callback.STATUS_FAILED, 'some error') now += 0.5 # check "end" events self.assertEqual(fo.visible_lines(), [ '(1/2): foo 1.0 B/s | 10 B 00:10 ', '[FAILED] bar: some error ']) self.assertTrue(2.0 < p.rate < 4.0)
def test_frontend_none(self): c_path, c_content = self._create_conf() new_path, new_content = self._create_rpmnew() with self.rpmconf_plugin as rpmconf, mock.patch( "rpmconf.rpmconf.RpmConf.flush_input", return_value="M" ), mock.patch("sys.stdout", new_callable=StringIO), mock.patch.dict("os.environ"): if os.environ.get("MERGE"): del os.environ["MERGE"] try: rpmconf.frontent = "env" rpmconf.run() except SystemExit as e: if e.code in (errno.ENOENT, errno.EINTR): self.fail("rpmconf has exited prematurely in the merge phase") else: self.fail("rpmconf has exited prematurely" "with unknown exit code {0}".format(safe_repr(e.code))) self.assertTrue(os.access(c_path, os.F_OK)) with open(c_path, "rb") as f: c_result = f.read() self.assertEqual(c_result, c_content) self.assertTrue(os.access(new_path, os.F_OK)) with open(new_path, "rb") as f: new_result = f.read() self.assertEqual(new_result, new_content)
def test_print_versions(self): base = support.MockBase() output = support.MockOutput() with mock.patch("sys.stdout") as stdout, mock.patch("dnf.sack.rpmdb_sack", return_value=base.sack): dnf.cli.cli.print_versions(["pepper", "tour"], base, output) written = "".join([mc[1][0] for mc in stdout.method_calls if mc[0] == "write"]) self.assertEqual(written, VERSIONS_OUTPUT)
def test_print_versions(self): output = tests.support.MockOutput() with mock.patch('sys.stdout') as stdout,\ mock.patch('dnf.sack._rpmdb_sack', return_value=self.base.sack): dnf.cli.cli.print_versions(['pepper', 'tour'], self.base, output) written = ''.join([mc[1][0] for mc in stdout.method_calls if mc[0] == 'write']) self.assertEqual(written, VERSIONS_OUTPUT)
def __enter__(self): self._patches = [ mock.patch("rpm.TransactionSet.dbMatch", return_value=self.packages), mock.patch("rpm.fi", return_value=((self._conf_file, None, None, None, 1),)), ] for patch in self._patches: patch.__enter__() return self
def test_fit_lock_dir(self): orig = '/some' with mock.patch('dnf.util.am_i_root', return_value=True): self.assertEqual(dnf.lock._fit_lock_dir(orig), '/some') with mock.patch('dnf.util.am_i_root', return_value=False): dir_ = dnf.lock._fit_lock_dir(orig) match = re.match( r'/run/user/\d+/dnf/8e58d9adbd213a8b602f30604a8875f2', dir_) self.assertTrue(match)
def test_motd(self): m = mock_open() with mock.patch('dnf.automatic.emitter.open', m, create=True): emitter = dnf.automatic.emitter.MotdEmitter('myhost') emitter.notify_available('packages...') emitter.notify_downloaded() with mock.patch('dnf.automatic.emitter.DOWNLOADED', 'downloaded on %s:'): emitter.commit() handle = m() handle.write.assert_called_once_with(MSG)
def test_clean_files_local(self): """Do not delete files from a local repo.""" base = tests.support.MockBase("main") repo = base.repos['main'] repo.baseurl = ['file:///dnf-bad-test'] repo.basecachedir = '/tmp/dnf-bad-test' with mock.patch('dnf.cli.commands.clean._clean_filelist'),\ mock.patch('os.path.exists', return_value=True) as exists_mock: dnf.cli.commands.clean._clean_files(base.repos, ['rpm'], 'pkgdir', 'package') # local repo is not even checked for directory existence: self.assertIsNone(exists_mock.call_args)
def test_clean_binary_cache(self): base = tests.support.MockBase('main') with mock.patch('os.access', return_value=True) as access,\ mock.patch('dnf.cli.commands.clean._clean_filelist'): clean._clean_binary_cache(base.repos, base.conf.cachedir) self.assertEqual(len(access.call_args_list), 3) fname = access.call_args_list[0][0][0] assert fname.startswith(dnf.const.TMPDIR) assert fname.endswith(hawkey.SYSTEM_REPO_NAME + '.solv') fname = access.call_args_list[1][0][0] assert fname.endswith('main.solv') fname = access.call_args_list[2][0][0] assert fname.endswith('main-filenames.solvx')
def test_pkg_option(self): args = ["--pkg", "foo"] self.cmd.base.add_remote_rpms([os.path.join(self.path, "noarch/foo-4-6.noarch.rpm")]) with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: support.command_run(self.cmd, args) expected_out = ["package: foo-4-6.noarch from @commandline", " unresolved deps:", " bar = 4-6"] self.assertEqual(stdout.getvalue()[:-1], "\n".join(expected_out)) args = ["--pkg", "bar"] with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: support.command_run(self.cmd, args) self.assertEmpty(stdout.getvalue())
def test_non_interactive(self): c_path, c_content = self._create_conf() new_path, new_content = self._create_rpmnew() with self.rpmconf_plugin as rpmconf, mock.patch( "rpmconf.rpmconf.RpmConf.flush_input", return_value="S" ), mock.patch("sys.stdout", new_callable=StringIO) as stdout: rpmconf._interactive = False rpmconf.run() lines = stdout.getvalue().splitlines() self.assertEqual(len(lines), 0)
def test_check_option(self): args = ["--check", "@commandline"] self.cmd.base.repos.add(support.RepoStub("main")) self.cmd.base.add_remote_rpm(os.path.join(self.path, "noarch/foo-4-6.noarch.rpm")) self.cmd.configure(args) with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: self.cmd.run(args) expected_out = ["package: foo-4-6.noarch from @commandline", " unresolved deps:", " bar = 4-6"] self.assertEqual(stdout.getvalue()[:-1], "\n".join(expected_out)) args = ["--check", "main"] self.cmd.configure(args) with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: self.cmd.run(args) self.assertEmpty(stdout.getvalue())
def test_mirror(self): fo = MockStdout() p = dnf.cli.progress.MultiFileProgressMeter(fo, update_period=-1) p.start(1, 5) pload = FakePayload('foo', 5.0) now = 1379406823.9 with mock.patch('dnf.cli.progress._term_width', return_value=60), \ mock.patch('dnf.cli.progress.time', lambda: now): p.progress(pload, 3) p.end(pload, dnf.callback.STATUS_MIRROR, 'Timeout.') p.progress(pload, 4) self.assertEqual(fo.visible_lines(), [ '[MIRROR] foo: Timeout. ', 'foo 80% [======== ] --- B/s | 4 B --:-- ETA'])
def setUp(self): """Prepare the test fixture.""" super(UpdateInfoCommandTest, self).setUp() cachedir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, cachedir) self.cli.base.conf.cachedir = cachedir self.cli.base.add_test_dir_repo('rpm', self.cli.base.conf) self._stdout = dnf.pycomp.StringIO() self.addCleanup(mock.patch.stopall) mock.patch( 'dnf.cli.commands.updateinfo._', dnf.pycomp.NullTranslations().ugettext).start() mock.patch( 'dnf.cli.commands.updateinfo.print', self._stub_print, create=True).start()
def test_configure_badargs(self): """Test whether the command fail in case of wrong args.""" with self.assertRaises(SystemExit) as exit, \ support.patch_std_streams() as (stdout, stderr), \ mock.patch('logging.Logger.critical') as clog: support.command_configure(self.cmd, []) self.assertEqual(exit.exception.code, 1)
def test_diff_output(self): self._create_conf() self._create_rpmnew() self._create_rpmsave() with self.rpmconf_plugin as rpmconf, mock.patch("sys.stdout", new_callable=StringIO) as stdout: rpmconf.diff = True rpmconf.run() lines = stdout.getvalue().splitlines() expected_lines = [ "--- {0}".format(*self.conf_file), "+++ {0}".format(*self.conf_file_rpmnew), "@@ -1,3 +1,2 @@", " package = good", " true = false", '-what = "tahw"', "--- {0}".format(*self.conf_file_rpmsave), "+++ {0}".format(*self.conf_file), "@@ -1,2 +1,3 @@", "-package = bad", "-true = true", "+package = good", "+true = false", '+what = "tahw"', ] msg_tmpl = "{0} does not start with {1}" for line, expected_line in zip_longest(lines, expected_lines, fillvalue=""): if not line.startswith(expected_line): self.fail(msg_tmpl.format(safe_repr(line), safe_repr(expected_line)))
def setUp(self): """Prepare the test fixture.""" super(RepoPkgsReinstallSubCommandTest, self).setUp() self.mock = mock.Mock() old_run_patcher = mock.patch( 'dnf.cli.commands.RepoPkgsCommand.ReinstallOldSubCommand.run_on_repo', self.mock.reinstall_old_run) move_run_patcher = mock.patch( 'dnf.cli.commands.RepoPkgsCommand.MoveToSubCommand.run_on_repo', self.mock.move_to_run) old_run_patcher.start() self.addCleanup(old_run_patcher.stop) move_run_patcher.start() self.addCleanup(move_run_patcher.stop)
def test_configure_verbose(self): with mock.patch('dnf.rpm.detect_releasever', return_value=69): self.cli.configure(['-v', 'update', '-c', self.conffile]) self.assertEqual(self.cli.cmdstring, "dnf -v update -c %s " % self.conffile) self.assertEqual(self.base.conf.debuglevel, 6) self.assertEqual(self.base.conf.errorlevel, 6)
def test_macro(self): with mock.patch('builddep.BuildDepCommand.base', MockBase()) as base: self.cmd.configure(('--define', 'enable_optional_module 1', SPEC,)) self.cmd.run(('--define', 'enable_optional_module 1', SPEC,)) self.assertEqual(base.marked, ['emacs-extras', 'emacs-goodies >= 100', 'emacs-module'])
def test_header(self): args = [] self.cmd.configure(args) with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: self.cmd.run(args) expected_graph = ["digraph packages {", repograph.DOT_HEADER, "}\n"] self.assertEqual(stdout.getvalue(), "\n".join(expected_graph))
def test_configure_user(self): """ Test Cli.configure as user.""" self.base._conf = dnf.conf.Conf() with mock.patch('dnf.rpm.detect_releasever', return_value=69): self.cli.configure(['update', '-c', self.conffile]) reg = re.compile('^/var/tmp/dnf-[a-zA-Z0-9_-]+$') self.assertIsNotNone(reg.match(self.base.conf.cachedir)) self.assertEqual(self.cli.cmdstring, "dnf update -c %s " % self.conffile)
def test_space_option(self): args = ["--new", "--space", self.path] with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: support.command_run(self.cmd, args) expected_list = ["foo-4-8.src.rpm", "noarch/foo-4-8.noarch.rpm"] self.assertEqual(stdout.getvalue()[:-1], " ".join(self._path_join_in_list(expected_list, self.path)))
def test_configure_verbose(self): with mock.patch('dnf.rpm.detect_releasever', return_value=69): self.cli.configure(['-v', 'update', '-c', self.conffile]) parser = argparse.ArgumentParser() expected = "%s -v update -c %s " % (parser.prog, self.conffile) self.assertEqual(self.cli.cmdstring, expected) self.assertEqual(self.base.conf.debuglevel, 6) self.assertEqual(self.base.conf.errorlevel, 6)
def test_base(self): args = [] self.cmd.base.add_remote_rpm(os.path.join(self.path, "noarch/foo-4-6.noarch.rpm")) self.cmd.configure(args) with mock.patch("sys.stdout", new_callable=dnf.pycomp.StringIO) as stdout: self.cmd.run(args) expected_out = ["package: foo-4-6.noarch from @commandline", " unresolved deps:", " bar = 4-6"] self.assertEqual(stdout.getvalue()[:-1], "\n".join(expected_out))
def test_setup_stdout(self): # No stdout output can be seen when sys.stdout is patched, debug msgs, # etc. included. with mock.patch('sys.stdout', spec=('write',)): retval = dnf.i18n.setup_stdout() self.assertFalse(retval) with mock.patch('sys.stdout') as mock_stdout: mock_stdout.encoding = None retval = dnf.i18n.setup_stdout() self.assertFalse(retval) with mock.patch('sys.stdout') as mock_stdout: mock_stdout.encoding = 'UTF-8' retval = dnf.i18n.setup_stdout() self.assertTrue(retval) with mock.patch('sys.stdout') as mock_stdout: mock_stdout.encoding = 'ISO-8859-2' retval = dnf.i18n.setup_stdout() self.assertFalse(retval)
def test_throttle(self): self.repo.throttle = '50%' self.repo.bandwidth = '10M' self.assertEqual(self.repo.throttle, 0.5) self.assertEqual(self.repo.bandwidth, 10 << 20) opts = {} with mock.patch('librepo.Handle.setopt', opts.__setitem__): self.repo._get_handle() self.assertEqual(opts[librepo.LRO_MAXSPEED], 5 << 20)
def test_drpm_error(self): def wait(self): self.err['step'] = ['right'] drpm = dnf.drpm.DeltaInfo(None, None) with mock.patch('dnf.drpm.DeltaInfo.wait', wait): errs = dnf.repo._download_payloads([], drpm) self.assertEqual(errs._recoverable, {'step' : ['right']}) self.assertEmpty(errs._irrecoverable)
def test_reviving_lame_hashes(self, new_remote_m, _): self.repo._md_expire_cache() self.repo.metalink = 'http://meh' new_remote_m().metalink = \ {'hashes': [('md5', 'fcf04ce803b3e15cbef6ea6f12ed4533'), ('sha1', '3731498f6b7b96316590205a4d7a2add484471e0')]} with mock.patch('dnf.repo.Repo._cachedir', REPOS + "/rpm"): self.repo._try_cache() self.assertFalse(self.repo._try_revive())
def test_fatal_error(self): def raiser(_, failfast): raise librepo.LibrepoException(10, 'hit', 'before') drpm = dnf.drpm.DeltaInfo(None, None) with mock.patch('librepo.download_packages', side_effect=raiser): errs = dnf.repo._download_payloads([], drpm) self.assertEqual(errs._irrecoverable, {'' : ['hit']}) self.assertEmpty(errs._recoverable)
def test_setup_stdout(self): # No stdout output can be seen when sys.stdout is patched, debug msgs, # etc. included. with mock.patch("sys.stdout", spec=("write", "isatty")): retval = dnf.i18n.setup_stdout() self.assertFalse(retval) with mock.patch("sys.stdout") as mock_stdout: mock_stdout.encoding = None retval = dnf.i18n.setup_stdout() self.assertFalse(retval) with mock.patch("sys.stdout") as mock_stdout: mock_stdout.encoding = "UTF-8" retval = dnf.i18n.setup_stdout() self.assertTrue(retval) with mock.patch("sys.stdout") as mock_stdout: mock_stdout.encoding = "ISO-8859-2" retval = dnf.i18n.setup_stdout() self.assertFalse(retval)
def _run_os_grains_tests(self, os_release_filename, os_release_map, expectation): path_isfile_mock = MagicMock( side_effect=lambda x: x in os_release_map.get('files', [])) empty_mock = MagicMock(return_value={}) osarch_mock = MagicMock(return_value="amd64") if os_release_filename: os_release_data = core._parse_os_release( os.path.join(OS_RELEASE_DIR, os_release_filename)) else: os_release_data = os_release_map.get('os_release_file', {}) os_release_mock = MagicMock(return_value=os_release_data) orig_import = __import__ if six.PY2: built_in = '__builtin__' else: built_in = 'builtins' def _import_mock(name, *args): if name == 'lsb_release': raise ImportError('No module named lsb_release') return orig_import(name, *args) suse_release_file = os_release_map.get('suse_release_file') file_contents = {'/proc/1/cmdline': ''} if suse_release_file: file_contents['/etc/SuSE-release'] = suse_release_file # - Skip the first if statement # - Skip the selinux/systemd stuff (not pertinent) # - Skip the init grain compilation (not pertinent) # - Ensure that lsb_release fails to import # - Skip all the /etc/*-release stuff (not pertinent) # - Mock linux_distribution to give us the OS name that we want # - Mock the osarch distro_mock = MagicMock( return_value=os_release_map['linux_distribution']) with patch.object(salt.utils.platform, 'is_proxy', MagicMock(return_value=False)), \ patch.object(core, '_linux_bin_exists', MagicMock(return_value=False)), \ patch.object(os.path, 'exists', path_isfile_mock), \ patch('{0}.__import__'.format(built_in), side_effect=_import_mock), \ patch.object(os.path, 'isfile', path_isfile_mock), \ patch.object(core, '_parse_os_release', os_release_mock), \ patch.object(core, '_parse_lsb_release', empty_mock), \ patch('salt.utils.files.fopen', mock_open(read_data=file_contents)), \ patch.object(core, 'linux_distribution', distro_mock), \ patch.object(core, '_linux_gpu_data', empty_mock), \ patch.object(core, '_linux_cpudata', empty_mock), \ patch.object(core, '_virtual', empty_mock), \ patch.dict(core.__salt__, {'cmd.run': osarch_mock}): os_grains = core.os_data() grains = { k: v for k, v in os_grains.items() if k in set([ "os", "os_family", "osfullname", "oscodename", "osfinger", "osrelease", "osrelease_info", "osmajorrelease" ]) } self.assertEqual(grains, expectation)
def test_cert_info(self): ''' Test cert info ''' self.maxDiff = None with patch('os.path.exists', MagicMock(return_value=True)), \ patch('salt.modules.tls.maybe_fix_ssl_version', MagicMock(return_value=True)): ca_path = '/tmp/test_tls' ca_name = 'test_ca' certp = '{0}/{1}/{2}_ca_cert.crt'.format( ca_path, ca_name, ca_name) ret = { 'not_after': 1462379961, 'signature_algorithm': 'sha256WithRSAEncryption', 'extensions': None, 'fingerprint': ('96:72:B3:0A:1D:34:37:05:75:57:44:7E:08:81:A7:09:' '0C:E1:8F:5F:4D:0C:49:CE:5B:D2:6B:45:D3:4D:FF:31'), 'serial_number': 284092004844685647925744086791559203700, 'subject': { 'C': 'US', 'CN': 'localhost', 'L': 'Salt Lake City', 'O': 'SaltStack', 'ST': 'Utah', 'emailAddress': '*****@*****.**'}, 'not_before': 1430843961, 'issuer': { 'C': 'US', 'CN': 'localhost', 'L': 'Salt Lake City', 'O': 'SaltStack', 'ST': 'Utah', 'emailAddress': '*****@*****.**'} } def ignore_extensions(data): ''' Ignore extensions pending a resolution of issue 24338 ''' if 'extensions' in data.keys(): data['extensions'] = None return data # older pyopenssl versions don't have extensions or # signature_algorithms def remove_not_in_result(source, reference): if 'signature_algorithm' not in reference: del source['signature_algorithm'] if 'extensions' not in reference: del source['extensions'] with patch('salt.utils.files.fopen', mock_open(read_data=_TLS_TEST_DATA['ca_cert'])): try: result = ignore_extensions(tls.cert_info(certp)) except AttributeError as err: # PyOpenSSL version 16.0.0 has an upstream bug in it where a call is made # in OpenSSL/crypto.py in the get_signature_algorithm function referencing # the cert_info attribute, which doesn't exist. This was fixed in subsequent # releases of PyOpenSSL with https://github.com/pyca/pyopenssl/pull/476 if '\'_cffi_backend.CDataGCP\' object has no attribute \'cert_info\'' == six.text_type(err): log.exception(err) self.skipTest( 'Encountered an upstream error with PyOpenSSL: {0}'.format( err ) ) if '\'_cffi_backend.CDataGCP\' object has no attribute \'object\'' == str(err): log.exception(err) self.skipTest( 'Encountered an upstream error with PyOpenSSL: {0}'.format( err ) ) # python-openssl version 0.14, when installed with the "junos-eznc" pip # package, causes an error on this test. Newer versions of PyOpenSSL do not have # this issue. If 0.14 is installed and we hit this error, skip the test. if LooseVersion(OpenSSL.__version__) == LooseVersion('0.14'): log.exception(err) self.skipTest( 'Encountered a package conflict. OpenSSL version 0.14 cannot be used with ' 'the "junos-eznc" pip package on this test. Skipping.' ) result = {} remove_not_in_result(ret, result) self.assertEqual(result, ret)
def setUp(self): patcher = patch("os.makedirs", MagicMock()) patcher.start() self.addCleanup(patcher.stop)
def test_write(self): with patch('etcd.Client', autospec=True) as mock: client = etcd_util.EtcdClient({}) etcd_client = mock.return_value etcd_client.write.return_value = MagicMock(value='salt') self.assertEqual(client.write('/some-key', 'salt'), 'salt') etcd_client.write.assert_called_with('/some-key', 'salt', ttl=None, dir=False) self.assertEqual(client.write('/some-key', 'salt', ttl=5), 'salt') etcd_client.write.assert_called_with('/some-key', 'salt', ttl=5, dir=False) etcd_client.write.return_value = MagicMock(dir=True) self.assertEqual( client.write('/some-dir', 'salt', ttl=0, directory=True), True) etcd_client.write.assert_called_with('/some-dir', None, ttl=0, dir=True) # Check when a file is attempted to be written to a read-only root etcd_client.write.side_effect = etcd.EtcdRootReadOnly() self.assertEqual(client.write('/', 'some-val', directory=False), None) # Check when a directory is attempted to be written to a read-only root etcd_client.write.side_effect = etcd.EtcdRootReadOnly() self.assertEqual(client.write('/', None, directory=True), None) # Check when a file is attempted to be written when unable to connect to the service etcd_client.write.side_effect = MaxRetryError(None, None) self.assertEqual( client.write('/some-key', 'some-val', directory=False), None) # Check when a directory is attempted to be written when unable to connect to the service etcd_client.write.side_effect = MaxRetryError(None, None) self.assertEqual(client.write('/some-dir', None, directory=True), None) # Check when a file is attempted to be written to a directory that already exists (name-collision) etcd_client.write.side_effect = etcd.EtcdNotFile() self.assertEqual( client.write('/some-dir', 'some-val', directory=False), None) # Check when a directory is attempted to be written to a file that already exists (name-collision) etcd_client.write.side_effect = etcd.EtcdNotDir() self.assertEqual(client.write('/some-key', None, directory=True), None) # Check when a directory is attempted to be written to a directory that already exists (update-ttl) etcd_client.write.side_effect = etcd.EtcdNotFile() self.assertEqual(client.write('/some-dir', None, directory=True), True) etcd_client.write.side_effect = ValueError self.assertEqual(client.write('/some-key', 'some-val'), None) etcd_client.write.side_effect = Exception self.assertRaises(Exception, client.set, 'some-key', 'some-val')
def tearDown(self): with patch('salt.transport.zeromq.AsyncReqMessageClient.destroy', MagicMock(return_value=None)): del self.original_message_clients super(AsyncReqMessageClientPoolTest, self).tearDown()
def setup_loader_modules(self): patcher = patch("salt.engines.sqs_events.boto.sqs") self.mock_sqs = patcher.start() self.addCleanup(patcher.stop) self.addCleanup(delattr, self, "mock_sqs") return {sqs_events: {}}
def test_mounted(self): ''' Test to verify that a device is mounted. ''' name = os.path.realpath('/mnt/sdb') device = os.path.realpath('/dev/sdb5') fstype = 'xfs' name2 = os.path.realpath('/mnt/cifs') device2 = '//SERVER/SHARE/' fstype2 = 'cifs' opts2 = ['noowners'] superopts2 = ['uid=510', 'gid=100', 'username=cifsuser', 'domain=cifsdomain'] ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} mock = MagicMock(side_effect=['new', 'present', 'new', 'change', 'bad config', 'salt', 'present']) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_ret = MagicMock(return_value={'retcode': 1}) mock_mnt = MagicMock(return_value={name: {'device': device, 'opts': [], 'superopts': []}, name2: {'device': device2, 'opts': opts2, 'superopts': superopts2}}) mock_emt = MagicMock(return_value={}) mock_str = MagicMock(return_value='salt') mock_user = MagicMock(return_value={'uid': 510}) mock_group = MagicMock(return_value={'gid': 100}) mock_read_cache = MagicMock(return_value={}) mock_write_cache = MagicMock(return_value=True) with patch.dict(mount.__grains__, {'os': 'Darwin'}): with patch.dict(mount.__salt__, {'mount.active': mock_mnt, 'cmd.run_all': mock_ret, 'mount.umount': mock_f}), \ patch('os.path.exists', MagicMock(return_value=True)): comt = ('Unable to find device with label /dev/sdb5.') ret.update({'comment': comt}) self.assertDictEqual(mount.mounted(name, 'LABEL=/dev/sdb5', fstype), ret) with patch.dict(mount.__opts__, {'test': True}): comt = ('Remount would be forced because' ' options (noowners) changed') ret.update({'comment': comt, 'result': None}) self.assertDictEqual(mount.mounted(name, device, fstype), ret) with patch.dict(mount.__opts__, {'test': False}): comt = ('Unable to unmount {0}: False.'.format(name)) umount = ('Forced unmount and mount because' ' options (noowners) changed') ret.update({'comment': comt, 'result': False, 'changes': {'umount': umount}}) self.assertDictEqual(mount.mounted(name, device, 'nfs'), ret) umount1 = ("Forced unmount because devices don't match. " "Wanted: {0}, current: {1}, {1}".format(os.path.realpath('/dev/sdb6'), device)) comt = ('Unable to unmount') ret.update({'comment': comt, 'result': None, 'changes': {'umount': umount1}}) self.assertDictEqual(mount.mounted(name, os.path.realpath('/dev/sdb6'), fstype, opts=[]), ret) with patch.dict(mount.__salt__, {'mount.active': mock_emt, 'mount.mount': mock_str, 'mount.set_automaster': mock}): with patch.dict(mount.__opts__, {'test': True}), \ patch('os.path.exists', MagicMock(return_value=False)): comt = ('{0} does not exist and would not be created'.format(name)) ret.update({'comment': comt, 'changes': {}}) self.assertDictEqual(mount.mounted(name, device, fstype), ret) with patch.dict(mount.__opts__, {'test': False}): with patch.object(os.path, 'exists', mock_f): comt = ('Mount directory is not present') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(mount.mounted(name, device, fstype), ret) with patch.object(os.path, 'exists', mock_t): comt = ('Mount directory is not present') ret.update({'comment': 'salt', 'result': False}) self.assertDictEqual(mount.mounted(name, device, fstype), ret) with patch.dict(mount.__opts__, {'test': True}), \ patch('os.path.exists', MagicMock(return_value=False)): comt = ('{0} does not exist and would neither be created nor mounted. ' '{0} needs to be written to the fstab in order to be made persistent.'.format(name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(mount.mounted(name, device, fstype, mount=False), ret) with patch.dict(mount.__opts__, {'test': False}), \ patch('os.path.exists', MagicMock(return_value=False)): comt = ('{0} not present and not mounted. ' 'Entry already exists in the fstab.'.format(name)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(mount.mounted(name, device, fstype, mount=False), ret) comt = ('{0} not present and not mounted. ' 'Added new entry to the fstab.'.format(name)) ret.update({'comment': comt, 'result': True, 'changes': {'persist': 'new'}}) self.assertDictEqual(mount.mounted(name, device, fstype, mount=False), ret) comt = ('{0} not present and not mounted. ' 'Updated the entry in the fstab.'.format(name)) ret.update({'comment': comt, 'result': True, 'changes': {'persist': 'update'}}) self.assertDictEqual(mount.mounted(name, device, fstype, mount=False), ret) comt = ('{0} not present and not mounted. ' 'However, the fstab was not found.'.format(name)) ret.update({'comment': comt, 'result': False, 'changes': {}}) self.assertDictEqual(mount.mounted(name, device, fstype, mount=False), ret) comt = ('{0} not present and not mounted'.format(name)) ret.update({'comment': comt, 'result': True, 'changes': {}}) self.assertDictEqual(mount.mounted(name, device, fstype, mount=False), ret) # Test no change for uid provided as a name #25293 with patch.dict(mount.__grains__, {'os': 'CentOS'}): with patch.dict(mount.__salt__, {'mount.active': mock_mnt, 'mount.mount': mock_str, 'mount.umount': mock_f, 'mount.read_mount_cache': mock_read_cache, 'mount.write_mount_cache': mock_write_cache, 'mount.set_fstab': mock, 'user.info': mock_user, 'group.info': mock_group}): with patch.dict(mount.__opts__, {'test': True}): with patch.object(os.path, 'exists', mock_t): comt = 'Target was already mounted. Entry already exists in the fstab.' ret.update({'name': name2, 'result': True}) ret.update({'comment': comt, 'changes': {}}) self.assertDictEqual(mount.mounted(name2, device2, fstype2, opts=['uid=user1', 'gid=group1']), ret)
def test_delete_group_exists(self): ''' Tests if the group to be deleted exists or not ''' with patch('salt.modules.mac_group.info', MagicMock(return_value={})): self.assertTrue(mac_group.delete('test'))
def test_add_underscore(self): ''' Tests if the group name starts with an underscore or not ''' with patch('salt.modules.mac_group.info', MagicMock(return_value={})): self.assertRaises(SaltInvocationError, mac_group.add, '_Test')
def test_output_false(self): with patch('salt.utils.vmware.is_connection_to_a_vcenter', MagicMock(return_value=False)): res = vsphere.test_vcenter_connection() self.assertEqual(res, False)
def test_is_connection_to_a_vcenter_raises_vmware_salt_error(self): exc = VMwareSaltError('VMwareSaltError') with patch('salt.utils.vmware.is_connection_to_a_vcenter', MagicMock(side_effect=exc)): res = vsphere.test_vcenter_connection() self.assertEqual(res, False)
def test_is_connection_to_a_vcenter_call_default_service_instance(self): mock_is_connection_to_a_vcenter = MagicMock() with patch('salt.utils.vmware.is_connection_to_a_vcenter', mock_is_connection_to_a_vcenter): vsphere.test_vcenter_connection() mock_is_connection_to_a_vcenter.assert_called_once_with(mock_si)
def test_suse_os_from_cpe_data(self): ''' Test if 'os' grain is parsed from CPE_NAME of /etc/os-release ''' _path_exists_map = {'/proc/1/cmdline': False} _os_release_map = { 'NAME': 'SLES', 'VERSION': '12-SP1', 'VERSION_ID': '12.1', 'PRETTY_NAME': 'SUSE Linux Enterprise Server 12 SP1', 'ID': 'sles', 'ANSI_COLOR': '0;32', 'CPE_NAME': 'cpe:/o:suse:sles:12:sp1' } path_exists_mock = MagicMock(side_effect=lambda x: _path_exists_map[x]) empty_mock = MagicMock(return_value={}) osarch_mock = MagicMock(return_value="amd64") os_release_mock = MagicMock(return_value=_os_release_map) orig_import = __import__ if six.PY2: built_in = '__builtin__' else: built_in = 'builtins' def _import_mock(name, *args): if name == 'lsb_release': raise ImportError('No module named lsb_release') return orig_import(name, *args) distro_mock = MagicMock(return_value=('SUSE Linux Enterprise Server ', '12', 'x86_64')) # - Skip the first if statement # - Skip the selinux/systemd stuff (not pertinent) # - Skip the init grain compilation (not pertinent) # - Ensure that lsb_release fails to import # - Skip all the /etc/*-release stuff (not pertinent) # - Mock linux_distribution to give us the OS name that we want # - Mock the osarch with patch.object(salt.utils.platform, 'is_proxy', MagicMock(return_value=False)), \ patch.object(core, '_linux_bin_exists', MagicMock(return_value=False)), \ patch.object(os.path, 'exists', path_exists_mock), \ patch('{0}.__import__'.format(built_in), side_effect=_import_mock), \ patch.object(os.path, 'isfile', MagicMock(return_value=False)), \ patch.object(core, '_parse_os_release', os_release_mock), \ patch.object(core, '_parse_lsb_release', empty_mock), \ patch.object(core, 'linux_distribution', distro_mock), \ patch.object(core, '_linux_gpu_data', empty_mock), \ patch.object(core, '_hw_data', empty_mock), \ patch.object(core, '_linux_cpudata', empty_mock), \ patch.object(core, '_virtual', empty_mock), \ patch.dict(core.__salt__, {'cmd.run': osarch_mock}): os_grains = core.os_data() self.assertEqual(os_grains.get('os_family'), 'Suse') self.assertEqual(os_grains.get('os'), 'SUSE')
def test_output(self): mock_si = MagicMock() with patch('salt.utils.vmware.get_service_instance', MagicMock(return_value=mock_si)): res = vsphere.get_service_instance_via_proxy() self.assertEqual(res, mock_si)
def setUp(self): with patch('salt.state.State._gather_pillar'): minion_opts = self.get_temp_config('minion') self.state_obj = salt.state.State(minion_opts)
def test_disconnect_call(self): mock_disconnect = MagicMock() with patch('salt.utils.vmware.disconnect', mock_disconnect): vsphere.disconnect(mock_si) mock_disconnect.assert_called_once_with(mock_si)
def test_add_gid_int(self): ''' Tests if the gid is an int or not ''' with patch('salt.modules.mac_group.info', MagicMock(return_value={})): self.assertRaises(SaltInvocationError, mac_group.add, 'foo', 'foo')
def test_supported_proxes(self): supported_proxies = ['esxi'] for proxy_type in supported_proxies: with patch('salt.modules.vsphere.get_proxy_type', MagicMock(return_value=proxy_type)): vsphere.get_service_instance_via_proxy()
def test_malformed_pillar_sls(self): with patch('salt.pillar.compile_template') as compile_template: opts = { 'renderer': 'json', 'renderer_blacklist': [], 'renderer_whitelist': [], 'state_top': '', 'pillar_roots': [], 'file_roots': [], 'extension_modules': '' } grains = { 'os': 'Ubuntu', 'os_family': 'Debian', 'oscodename': 'raring', 'osfullname': 'Ubuntu', 'osrelease': '13.04', 'kernel': 'Linux' } pillar = salt.pillar.Pillar(opts, grains, 'mocked-minion', 'base') # Mock getting the proper template files pillar.client.get_state = MagicMock( return_value={ 'dest': '/path/to/pillar/files/foo.sls', 'source': 'salt://foo.sls' }) # Template compilation returned a string compile_template.return_value = 'BAHHH' self.assertEqual( pillar.render_pillar({'base': ['foo.sls']}), ({}, ['SLS \'foo.sls\' does not render to a dictionary'])) # Template compilation returned a list compile_template.return_value = ['BAHHH'] self.assertEqual( pillar.render_pillar({'base': ['foo.sls']}), ({}, ['SLS \'foo.sls\' does not render to a dictionary'])) # Template compilation returned a dictionary, which is what's expected compile_template.return_value = {'foo': 'bar'} self.assertEqual(pillar.render_pillar({'base': ['foo.sls']}), ({ 'foo': 'bar' }, [])) # Test improper includes compile_template.side_effect = [{ 'foo': 'bar', 'include': 'blah' }, { 'foo2': 'bar2' }] self.assertEqual(pillar.render_pillar({ 'base': ['foo.sls'] }), ({ 'foo': 'bar', 'include': 'blah' }, [ "Include Declaration in SLS 'foo.sls' is not formed as a list" ])) # Test includes as a list, which is what's expected compile_template.side_effect = [{ 'foo': 'bar', 'include': ['blah'] }, { 'foo2': 'bar2' }] self.assertEqual(pillar.render_pillar({'base': ['foo.sls']}), ({ 'foo': 'bar', 'foo2': 'bar2' }, [])) # Test includes as a list overriding data compile_template.side_effect = [{ 'foo': 'bar', 'include': ['blah'] }, { 'foo': 'bar2' }] self.assertEqual(pillar.render_pillar({'base': ['foo.sls']}), ({ 'foo': 'bar2' }, [])) # Test includes using empty key directive compile_template.side_effect = [{ 'foo': 'bar', 'include': [{ 'blah': { 'key': '' } }] }, { 'foo': 'bar2' }] self.assertEqual(pillar.render_pillar({'base': ['foo.sls']}), ({ 'foo': 'bar2' }, [])) # Test includes using simple non-nested key compile_template.side_effect = [{ 'foo': 'bar', 'include': [{ 'blah': { 'key': 'nested' } }] }, { 'foo': 'bar2' }] self.assertEqual(pillar.render_pillar({'base': ['foo.sls']}), ({ 'foo': 'bar', 'nested': { 'foo': 'bar2' } }, [])) # Test includes using nested key compile_template.side_effect = [{ 'foo': 'bar', 'include': [{ 'blah': { 'key': 'nested:level' } }] }, { 'foo': 'bar2' }] self.assertEqual(pillar.render_pillar({'base': ['foo.sls']}), ({ 'foo': 'bar', 'nested': { 'level': { 'foo': 'bar2' } } }, []))
def test_parse_zone(self): with patch("salt.utils.files.fopen", mock_open(read_data=mock_soa_zone)): log.debug(mock_soa_zone) log.debug(dnsutil.parse_zone("/var/lib/named/example.com.zone"))
def setUp(self): self.patch_check = patch("salt.modules.file.check_perms", file_.check_perms) if salt.utils.platform.is_windows(): self.patch_check = patch( "salt.modules.file.check_perms", win_file.check_perms )
def has_not_shadow_file(): with patch("os.path.isfile", return_value=False): yield
def tearDown(self): with patch('salt.transport.tcp.SaltMessageClient.close', MagicMock(return_value=None)): del self.original_message_clients super(SaltMessageClientPoolTest, self).tearDown()
def fake_spnam(): with patch( "spwd.getspnam", autospec=True, ) as fake_spnam: yield fake_spnam
def test_watch(self): with patch('etcd.Client', autospec=True) as client_mock: client = etcd_util.EtcdClient({}) with patch.object(client, 'read', autospec=True) as mock: mock.return_value = MagicMock(value='stack', key='/some-key', modifiedIndex=1, dir=False) self.assertDictEqual( client.watch('/some-key'), { 'value': 'stack', 'key': '/some-key', 'mIndex': 1, 'changed': True, 'dir': False }) mock.assert_called_with('/some-key', wait=True, recursive=False, timeout=0, waitIndex=None) mock.side_effect = iter( [etcd_util.EtcdUtilWatchTimeout, mock.return_value]) self.assertDictEqual( client.watch('/some-key'), { 'value': 'stack', 'changed': False, 'mIndex': 1, 'key': '/some-key', 'dir': False }) mock.side_effect = iter( [etcd_util.EtcdUtilWatchTimeout, etcd.EtcdKeyNotFound]) self.assertEqual( client.watch('/some-key'), { 'value': None, 'changed': False, 'mIndex': 0, 'key': '/some-key', 'dir': False }) mock.side_effect = iter( [etcd_util.EtcdUtilWatchTimeout, ValueError]) self.assertEqual(client.watch('/some-key'), {}) mock.side_effect = None mock.return_value = MagicMock(value='stack', key='/some-key', modifiedIndex=1, dir=True) self.assertDictEqual( client.watch('/some-dir', recurse=True, timeout=5, index=10), { 'value': 'stack', 'key': '/some-key', 'mIndex': 1, 'changed': True, 'dir': True }) mock.assert_called_with('/some-dir', wait=True, recursive=True, timeout=5, waitIndex=10) # iter(list(Exception)) works correctly with both mock<1.1 and mock>=1.1 mock.side_effect = iter([MaxRetryError(None, None)]) self.assertEqual(client.watch('/some-key'), {}) mock.side_effect = iter([etcd.EtcdConnectionFailed()]) self.assertEqual(client.watch('/some-key'), {}) mock.side_effect = None mock.return_value = None self.assertEqual(client.watch('/some-key'), {})
def test_pip_purge_method_without_pip(self): mock_modules = sys.modules.copy() mock_modules.pop("pip", None) with patch("sys.modules", mock_modules): pip_state.purge_pip()
def test_replace_auth_key(self): """ Test the _replace_auth_key with some different authorized_keys examples """ # First test a known working example, gathered from the authorized_keys file # in the integration test files. enc = "ssh-rsa" key = ( "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+" "PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNl" "GEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWp" "XLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal" "72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi" "/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==") options = 'command="/usr/local/lib/ssh-helper"' email = "github.com" empty_line = "\n" comment_line = "# this is a comment\n" # Write out the authorized key to a temporary file temp_file = tempfile.NamedTemporaryFile(delete=False, mode="w+") temp_file.close() with salt.utils.files.fopen(temp_file.name, "w") as _fh: # Add comment _fh.write(comment_line) # Add empty line for #41335 _fh.write(empty_line) _fh.write("{} {} {} {}".format(options, enc, key, email)) with patch.dict(ssh.__salt__, {"user.info": MagicMock(return_value={})}): with patch( "salt.modules.ssh._get_config_file", MagicMock(return_value=temp_file.name), ): ssh._replace_auth_key("foo", key, config=temp_file.name) # The previous authorized key should have been replaced by the simpler one with salt.utils.files.fopen(temp_file.name) as _fh: file_txt = salt.utils.stringutils.to_unicode(_fh.read()) self.assertIn(enc, file_txt) self.assertIn(key, file_txt) self.assertNotIn(options, file_txt) self.assertNotIn(email, file_txt) # Now test a very simple key using ecdsa instead of ssh-rsa and with multiple options enc = "ecdsa-sha2-nistp256" key = "abcxyz" with salt.utils.files.fopen(temp_file.name, "a") as _fh: _fh.write(salt.utils.stringutils.to_str("{} {}".format(enc, key))) # Replace the simple key from before with the more complicated options + new email # Option example is taken from Pull Request #39855 options = [ "no-port-forwarding", "no-agent-forwarding", "no-X11-forwarding", 'command="echo \'Please login as the user "ubuntu" rather than the user' ' "root".\'', ] email = "*****@*****.**" with patch.dict(ssh.__salt__, {"user.info": MagicMock(return_value={})}): with patch( "salt.modules.ssh._get_config_file", MagicMock(return_value=temp_file.name), ): ssh._replace_auth_key( "foo", key, enc=enc, comment=email, options=options, config=temp_file.name, ) # Assert that the new line was added as-is to the file with salt.utils.files.fopen(temp_file.name) as _fh: file_txt = salt.utils.stringutils.to_unicode(_fh.read()) self.assertIn(enc, file_txt) self.assertIn(key, file_txt) self.assertIn("{} ".format(",".join(options)), file_txt) self.assertIn(email, file_txt) self.assertIn(empty_line, file_txt) self.assertIn(comment_line, file_txt) # Now test a another very simple key using sk-ed25519 instead of ssh-rsa and with # multiple options enc = "*****@*****.**" key = "abcxyz" with salt.utils.files.fopen(temp_file.name, "a") as _fh: _fh.write(salt.utils.stringutils.to_str("{} {}".format(enc, key))) # Replace the simple key from before with the more complicated options + new email # Option example is taken from Pull Request #39855 options = [ "no-agent-forwarding", 'command="echo \'Please login as the user "debian" rather than the user' ' "root".\'', ] email = "*****@*****.**" with patch.dict(ssh.__salt__, {"user.info": MagicMock(return_value={})}): with patch( "salt.modules.ssh._get_config_file", MagicMock(return_value=temp_file.name), ): ssh._replace_auth_key( "foo", key, enc=enc, comment=email, options=options, config=temp_file.name, ) with salt.utils.files.fopen(temp_file.name) as _fh: file_txt = salt.utils.stringutils.to_unicode(_fh.read()) # the initial key must have been replaced and no longer present self.assertNotIn("\n{} {}\n".format(enc, key), file_txt) # the new key must be present self.assertIn( "{} {} {} {}".format(",".join(options), enc, key, email), file_txt) self.assertIn(empty_line, file_txt) self.assertIn(comment_line, file_txt)
def test_missing_os_release(self): with patch('salt.utils.files.fopen', mock_open(read_data={})): os_release = core._parse_os_release('/etc/os-release', '/usr/lib/os-release') self.assertEqual(os_release, {})
def test_supported_proxes(self): supported_proxies = ['esxi'] for proxy_type in supported_proxies: with patch('salt.modules.vsphere.get_proxy_type', MagicMock(return_value=proxy_type)): vsphere.test_vcenter_connection()
def test_services_need_restart_checkrestart_missing(): """Test that the user is informed about the required dependency.""" with patch("salt.utils.path.which_bin", Mock(return_value=None)): with pytest.raises(CommandNotFoundError): aptpkg.services_need_restart()