From 9c1109e69171db19eea9a126b1faa0dd6175c8cd Mon Sep 17 00:00:00 2001 From: "Schreiner, Henry F" Date: Wed, 2 Sep 2015 16:16:49 -0500 Subject: [PATCH 1/9] Adding some fixes for MacOS tests, test_local now passes on Yosemite The output of ls --bla is different, usage is lowercase, and printenv only will return one environment variable --- tests/test_local.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_local.py b/tests/test_local.py index 1fd76c915..071fddedb 100644 --- a/tests/test_local.py +++ b/tests/test_local.py @@ -207,12 +207,12 @@ def test_redirection(self): rc, _, err = (grep["-Zq5"] >= "tmp2.txt").run(["-Zq5"], retcode = None) self.assertEqual(rc, 2) self.assertFalse(err) - self.assertTrue("Usage" in (cat < "tmp2.txt")()) + self.assertTrue("usage" in (cat < "tmp2.txt")().lower()) rm("tmp2.txt") rc, out, _ = (grep["-Zq5"] >= ERROUT).run(["-Zq5"], retcode = None) self.assertEqual(rc, 2) - self.assertTrue("Usage" in out) + self.assertTrue("usage" in out.lower()) def test_popen(self): from plumbum.cmd import ls @@ -236,7 +236,8 @@ def test_iter_lines_timeout(self): from plumbum.cmd import ping try: - for i, (out, err) in enumerate(ping["127.0.0.1", "-i", 0.5].popen().iter_lines(timeout=2)): + # Order is important on mac + for i, (out, err) in enumerate(ping["-i", 0.5, "127.0.0.1"].popen().iter_lines(timeout=2)): print("out:", out) print("err:", err) except ProcessTimedOut: @@ -253,7 +254,8 @@ def test_iter_lines_error(self): self.assertEqual(i, 1) except ProcessExecutionError: ex = sys.exc_info()[1] - self.assertTrue(ex.stderr.startswith("/bin/ls: unrecognized option '--bla'")) + self.assertTrue(ex.stderr.startswith("/bin/ls: unrecognized option '--bla'") + or ex.stderr.startswith("/bin/ls: illegal option -- -")) else: self.fail("Expected an execution error") @@ -483,8 +485,10 @@ def test_bound_env(self): except CommandNotFound: self.skipTest("printenv is missing") with local.env(FOO = "hello"): - self.assertEqual(printenv.with_env(BAR = "world")("FOO", "BAR"), "hello\nworld\n") - self.assertEqual(printenv.with_env(FOO = "sea", BAR = "world")("FOO", "BAR"), "sea\nworld\n") + self.assertEqual(printenv.with_env(BAR = "world")("FOO"), "hello\n") + self.assertEqual(printenv.with_env(BAR = "world")("BAR"), "world\n") + self.assertEqual(printenv.with_env(FOO = "sea", BAR = "world")("FOO"), "sea\n") + self.assertEqual(printenv("FOO"), "hello\n") def test_nesting_lists_as_argv(self): from plumbum.cmd import ls From ca890e9d489e0fe5f710c86d35d9ff3cbe18ddd7 Mon Sep 17 00:00:00 2001 From: "Schreiner, Henry F" Date: Wed, 2 Sep 2015 16:34:14 -0500 Subject: [PATCH 2/9] More mac test fixes, this time for remote --- tests/test_remote.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_remote.py b/tests/test_remote.py index 8ba8de302..f815b432a 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -101,7 +101,8 @@ def test_basic(self): r_ls = rem["ls"] r_grep = rem["grep"] - self.assertTrue(".bashrc" in r_ls("-a").splitlines()) + lines = r_ls("-a").splitlines() + self.assertTrue(".bashrc" in lines or ".bash_profile" in lines) with rem.cwd(os.path.dirname(os.path.abspath(__file__))): cmd = r_ssh["localhost", "cd", rem.cwd, "&&", r_ls, "|", r_grep["\\.py"]] self.assertTrue("'|'" in str(cmd)) @@ -123,7 +124,7 @@ def test_session(self): sh = rem.session() for _ in range(4): _, out, _ = sh.run("ls -a") - self.assertTrue(".bashrc" in out) + self.assertTrue(".bashrc" in out or ".bash_profile" in out) def test_env(self): with self._connect() as rem: @@ -160,7 +161,7 @@ def test_contains(self): def test_iter_lines_timeout(self): with self._connect() as rem: try: - for i, (out, err) in enumerate(rem["ping"]["127.0.0.1", "-i", 0.5].popen().iter_lines(timeout=2)): + for i, (out, err) in enumerate(rem["ping"]["-i", 0.5, "127.0.0.1"].popen().iter_lines(timeout=2)): print("out:", out) print("err:", err) except NotImplementedError: @@ -182,7 +183,7 @@ def test_iter_lines_error(self): self.assertEqual(i, 1) except ProcessExecutionError: ex = sys.exc_info()[1] - self.assertTrue(ex.stderr.startswith("/bin/ls: unrecognized option '--bla'")) + self.assertTrue(ex.stderr.startswith("/bin/ls: ")) else: self.fail("Expected an execution error") @@ -237,9 +238,12 @@ def test_bound_env(self): with self._connect() as rem: printenv = rem["printenv"] with rem.env(FOO = "hello"): - self.assertEqual(printenv.with_env(BAR = "world")("FOO", "BAR"), "hello\nworld\n") - self.assertEqual(printenv.with_env(FOO = "sea", BAR = "world")("FOO", "BAR"), "sea\nworld\n") + self.assertEqual(printenv.with_env(BAR = "world")("FOO"), "hello\n") + self.assertEqual(printenv.with_env(BAR = "world")("BAR"), "world\n") + self.assertEqual(printenv.with_env(FOO = "sea", BAR = "world")("FOO"), "sea\n") + self.assertEqual(printenv.with_env(FOO = "sea", BAR = "world")("BAR"), "world\n") + @unittest.skipIf('useradd' not in local, "System does not have useradd (Mac?)") def test_sshpass(self): with local.as_root(): local["useradd"]("-m", "-b", "/tmp", "testuser") From 832b44f3ddc241a38bbd9b1587caecc618cb071d Mon Sep 17 00:00:00 2001 From: "Schreiner, Henry F" Date: Wed, 2 Sep 2015 17:04:48 -0500 Subject: [PATCH 3/9] Moving a few test utilities to lib --- plumbum/lib.py | 48 +++++++++++++++++++++++++++++++++++++++++++- tests/test_cli.py | 22 ++------------------ tests/test_local.py | 18 ++--------------- tests/test_remote.py | 17 ++-------------- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/plumbum/lib.py b/plumbum/lib.py index 8d84727d5..f120fbf74 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -1,4 +1,5 @@ import sys +import from contextlib import contextmanager from abc import ABCMeta IS_WIN32 = (sys.platform == "win32") @@ -24,7 +25,6 @@ class six(object): """ PY3 = sys.version_info[0] >= 3 ABC = ABCMeta('ABC', (object,), {'__module__':__name__}) - if PY3: integer_types = (int,) string_types = (str,) @@ -42,6 +42,7 @@ def u(s): @staticmethod def get_method_function(m): return m.__func__ + from io import StringIO else: integer_types = (int, long) string_types = (str, unicode) @@ -60,6 +61,51 @@ def u(s): def get_method_function(m): return m.im_func + This is a useful import, but is different from real six (six.moves) + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + + +def ensure_skipIf(unittest): + """ + This will ensure that unittest has skipIf. Call like:: + + import unittest + ensure_skipIf(unittest) + """ + + if not hasattr(unittest, "skipIf"): + import logging + import functools + def skipIf(condition, reason): + def deco(func): + if cond: + return func + else: + @functools.wraps(func) + def wrapper(*args, **kwargs): + logging.warn("skipping test") + return wrapper + return deco + unittest.skipIf = skipIf + +@contextmanager +def captured_stdout(stdin = ""): + """ + Captures stdout (similar to the redirect_stdout in Python 3.4+, but with slightly different arguments) + """ + prevstdin = sys.stdin + prevstdout = sys.stdout + sys.stdin = StringIO(six.u(stdin)) + sys.stdout = StringIO() + try: + yield sys.stdout + finally: + sys.stdin = prevstdin + sys.stdout = prevstdout + class StaticProperty(object): """This acts like a static property, allowing access via class or object. This is a non-data descriptor.""" diff --git a/tests/test_cli.py b/tests/test_cli.py index 877a02c8f..b7eeaa7f9 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,30 +1,12 @@ import sys import unittest -from contextlib import contextmanager from plumbum import cli, local from plumbum.cli.terminal import ask, choose, hexdump -from plumbum.lib import six +from plumbum.lib import six, captured_stdout # string/unicode issues -if six.PY3: - from io import StringIO -else: - from StringIO import StringIO - - -@contextmanager -def captured_stdout(stdin = ""): - prevstdin = sys.stdin - prevstdout = sys.stdout - sys.stdin = StringIO(six.u(stdin)) - sys.stdout = StringIO() - try: - yield sys.stdout - finally: - sys.stdin = prevstdin - sys.stdout = prevstdout - +StringIO = six.StringIO class TestApp(cli.Application): @cli.switch(["a"]) diff --git a/tests/test_local.py b/tests/test_local.py index 071fddedb..d99178b9e 100644 --- a/tests/test_local.py +++ b/tests/test_local.py @@ -4,27 +4,13 @@ import signal import time from plumbum import local, LocalPath, FG, BG, TF, RETCODE, ERROUT -from plumbum.lib import six +from plumbum.lib import six, ensure_skipIf from plumbum import CommandNotFound, ProcessExecutionError, ProcessTimedOut from plumbum.fs.atomic import AtomicFile, AtomicCounterFile, PidFile from plumbum.path import RelativePath import plumbum - -if not hasattr(unittest, "skipIf"): - import logging - import functools - def skipIf(cond, msg = None): - def deco(func): - if cond: - return func - else: - @functools.wraps(func) - def wrapper(*args, **kwargs): - logging.warn("skipping test") - return wrapper - return deco - unittest.skipIf = skipIf +ensure_skipIf(unittest) class LocalPathTest(unittest.TestCase): def test_basename(self): diff --git a/tests/test_remote.py b/tests/test_remote.py index f815b432a..c1df61920 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -6,8 +6,9 @@ import logging from plumbum import RemotePath, SshMachine, ProcessExecutionError, local, ProcessTimedOut from plumbum import CommandNotFound -from plumbum.lib import six +from plumbum.lib import six, ensure_skipIf +ensure_skipIf(unittest) #TEST_HOST = "192.168.1.143" TEST_HOST = "127.0.0.1" @@ -15,20 +16,6 @@ import plumbum plumbum.local.env.path.append("c:\\Program Files\\Git\\bin") -if not hasattr(unittest, "skipIf"): - import functools - def skipIf(cond, msg = None): - def deco(func): - if cond: - return func - else: - @functools.wraps(func) - def wrapper(*args, **kwargs): - logging.warn("skipping test") - return wrapper - return deco - unittest.skipIf = skipIf - class RemotePathTest(unittest.TestCase): def _connect(self): return SshMachine(TEST_HOST) From 00d22870378788e6ea962b5f36c46a771dd44fcf Mon Sep 17 00:00:00 2001 From: "Schreiner, Henry F" Date: Wed, 2 Sep 2015 17:13:04 -0500 Subject: [PATCH 4/9] Fix a few typos --- plumbum/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plumbum/lib.py b/plumbum/lib.py index f120fbf74..13b35dd6c 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -1,5 +1,5 @@ import sys -import from contextlib import contextmanager +from contextlib import contextmanager from abc import ABCMeta IS_WIN32 = (sys.platform == "win32") @@ -61,7 +61,7 @@ def u(s): def get_method_function(m): return m.im_func - This is a useful import, but is different from real six (six.moves) + # This is a useful import, but is different from real six (six.moves) try: from cStringIO import StringIO except ImportError: From 90a4276e3f31c53777894fea0ef3f00ae03b3ea3 Mon Sep 17 00:00:00 2001 From: Henry's desktop Ubuntu Date: Wed, 2 Sep 2015 18:12:29 -0500 Subject: [PATCH 5/9] Fixed import of StringIO --- plumbum/lib.py | 15 ++++++++------- tests/test_cli.py | 5 +---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/plumbum/lib.py b/plumbum/lib.py index 13b35dd6c..73e68bad5 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -2,6 +2,14 @@ from contextlib import contextmanager from abc import ABCMeta +try: + from io import StringIO +except ImportError: + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + IS_WIN32 = (sys.platform == "win32") def _setdoc(super): # @ReservedAssignment @@ -42,7 +50,6 @@ def u(s): @staticmethod def get_method_function(m): return m.__func__ - from io import StringIO else: integer_types = (int, long) string_types = (str, unicode) @@ -61,12 +68,6 @@ def u(s): def get_method_function(m): return m.im_func - # This is a useful import, but is different from real six (six.moves) - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - def ensure_skipIf(unittest): """ diff --git a/tests/test_cli.py b/tests/test_cli.py index b7eeaa7f9..df0ffae77 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -3,10 +3,7 @@ from plumbum import cli, local from plumbum.cli.terminal import ask, choose, hexdump -from plumbum.lib import six, captured_stdout - -# string/unicode issues -StringIO = six.StringIO +from plumbum.lib import six, captured_stdout, StringIO class TestApp(cli.Application): @cli.switch(["a"]) From e039ad82540284742a3ed9ec4774fd10494cfd21 Mon Sep 17 00:00:00 2001 From: Henry's desktop Ubuntu Date: Wed, 2 Sep 2015 18:18:49 -0500 Subject: [PATCH 6/9] Revert to StringIO on Python 2.7 --- plumbum/lib.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plumbum/lib.py b/plumbum/lib.py index 73e68bad5..a5c9fe927 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -5,10 +5,7 @@ try: from io import StringIO except ImportError: - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO + from StringIO import StringIO IS_WIN32 = (sys.platform == "win32") From f2db31fa12f192de0741448fa35dfc068581a998 Mon Sep 17 00:00:00 2001 From: Henry's desktop Ubuntu Date: Wed, 2 Sep 2015 18:43:19 -0500 Subject: [PATCH 7/9] String/unicode StringIO reverted to correct Python2 import --- plumbum/lib.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plumbum/lib.py b/plumbum/lib.py index a5c9fe927..e1a1bbd8e 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -2,11 +2,6 @@ from contextlib import contextmanager from abc import ABCMeta -try: - from io import StringIO -except ImportError: - from StringIO import StringIO - IS_WIN32 = (sys.platform == "win32") def _setdoc(super): # @ReservedAssignment @@ -65,6 +60,12 @@ def u(s): def get_method_function(m): return m.im_func +# Try/except fails because io has the wrong StringIO in Python2 +# You'll get str/unicode errors +if six.PY3: + from io import StringIO +else: + from StringIO import StringIO def ensure_skipIf(unittest): """ From af138db9af3160e50327607d80288290a357c61c Mon Sep 17 00:00:00 2001 From: henryiii Date: Wed, 2 Sep 2015 21:24:32 -0500 Subject: [PATCH 8/9] Fixing skipIf params for python2.6 --- plumbum/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plumbum/lib.py b/plumbum/lib.py index e1a1bbd8e..2961aaf93 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -80,12 +80,12 @@ def ensure_skipIf(unittest): import functools def skipIf(condition, reason): def deco(func): - if cond: + if condition: return func else: @functools.wraps(func) def wrapper(*args, **kwargs): - logging.warn("skipping test") + logging.warn("skipping test: "+reason) return wrapper return deco unittest.skipIf = skipIf From 5a644f989ec64f27cbbf317751d07ae2b0af3882 Mon Sep 17 00:00:00 2001 From: Henry's desktop Ubuntu Date: Tue, 15 Sep 2015 09:34:16 -0500 Subject: [PATCH 9/9] Added missing `Progress` from merge --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index ed2576e2e..22d2f015a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,7 +4,7 @@ import time from plumbum import cli, local -from plumbum.cli.terminal import ask, choose, hexdump +from plumbum.cli.terminal import ask, choose, hexdump, Progress from plumbum.lib import six, captured_stdout, StringIO class TestApp(cli.Application):