[Python-modules-commits] [systemfixtures] 02/04: New upstream version 0.6.0

Free Ekanayaka freee at moszumanska.debian.org
Sun Nov 20 21:21:35 UTC 2016


This is an automated email from the git hooks/post-receive script.

freee pushed a commit to branch master
in repository systemfixtures.

commit 3d2d605161b724764e0a4b7013cc758e304dc22c
Author: Free Ekanayaka <freee at debian.org>
Date:   Sun Nov 20 21:20:43 2016 +0000

    New upstream version 0.6.0
---
 ChangeLog                                |  5 +++
 PKG-INFO                                 |  2 +-
 docs/index.rst                           | 23 +++++++++++
 systemfixtures.egg-info/PKG-INFO         |  2 +-
 systemfixtures.egg-info/SOURCES.txt      |  2 +
 systemfixtures.egg-info/pbr.json         |  2 +-
 systemfixtures/__init__.py               |  2 +
 systemfixtures/executable.py             | 69 ++++++++++++++++++++++++++++++++
 systemfixtures/tests/test_executables.py | 51 +++++++++++++++++++++++
 9 files changed, 155 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 199ac5e..4228466 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,11 @@
 CHANGES
 =======
 
+0.6.0
+-----
+
+* Add FakeExecutable fixture for creating a Python script that behaves like some real executable
+
 0.5.1
 -----
 
diff --git a/PKG-INFO b/PKG-INFO
index 31dcc3c..148acba 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: systemfixtures
-Version: 0.5.1
+Version: 0.6.0
 Summary: Test fixtures for providing fake versions of various system resources (processes, users, groups, etc.)
 Home-page: https://github.com/freeekanayaka/systemfixtures
 Author: Free Ekanayaka
diff --git a/docs/index.rst b/docs/index.rst
index d11b6b7..038229a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -352,3 +352,26 @@ It's also possible to simulate a hung thread:
    >>> thread.join(timeout=60)  # This returns immediately
    >>> thread.isAlive()
    True
+
+
+Executables
++++++++++++
+
+The :class:`FakeExecutable` fixture lets you create temporary Python scripts
+that can be configured to mimic the behavior of some real executable (for
+instance listening to a port or emitting certain output):
+
+.. doctest::
+
+   >>> import stat
+   >>> from systemfixtures import FakeExecutable
+
+   >>> executable = FakeExecutable()
+   >>> executable.setUp()
+
+   >>> bool(os.stat(executable.path).st_mode & stat.S_IXUSR)
+   True
+
+   >>> executable.out('hello')
+   >>> subprocess.check_output([executable.path])
+   b'hello\n'
diff --git a/systemfixtures.egg-info/PKG-INFO b/systemfixtures.egg-info/PKG-INFO
index 31dcc3c..148acba 100644
--- a/systemfixtures.egg-info/PKG-INFO
+++ b/systemfixtures.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: systemfixtures
-Version: 0.5.1
+Version: 0.6.0
 Summary: Test fixtures for providing fake versions of various system resources (processes, users, groups, etc.)
 Home-page: https://github.com/freeekanayaka/systemfixtures
 Author: Free Ekanayaka
diff --git a/systemfixtures.egg-info/SOURCES.txt b/systemfixtures.egg-info/SOURCES.txt
index 0d10b5c..694aee9 100644
--- a/systemfixtures.egg-info/SOURCES.txt
+++ b/systemfixtures.egg-info/SOURCES.txt
@@ -17,6 +17,7 @@ docs/index.rst
 docs/_static/.placeholder
 systemfixtures/__init__.py
 systemfixtures/_overlay.py
+systemfixtures/executable.py
 systemfixtures/filesystem.py
 systemfixtures/groups.py
 systemfixtures/matchers.py
@@ -42,6 +43,7 @@ systemfixtures/processes/tests/test_fixture.py
 systemfixtures/processes/tests/test_systemctl.py
 systemfixtures/processes/tests/test_wget.py
 systemfixtures/tests/__init__.py
+systemfixtures/tests/test_executables.py
 systemfixtures/tests/test_filesystem.py
 systemfixtures/tests/test_groups.py
 systemfixtures/tests/test_network.py
diff --git a/systemfixtures.egg-info/pbr.json b/systemfixtures.egg-info/pbr.json
index 7419fe8..e6400fb 100644
--- a/systemfixtures.egg-info/pbr.json
+++ b/systemfixtures.egg-info/pbr.json
@@ -1 +1 @@
-{"is_release": true, "git_version": "71dc265"}
\ No newline at end of file
+{"is_release": true, "git_version": "32efb5c"}
\ No newline at end of file
diff --git a/systemfixtures/__init__.py b/systemfixtures/__init__.py
index bf99340..bb5da7f 100644
--- a/systemfixtures/__init__.py
+++ b/systemfixtures/__init__.py
@@ -9,6 +9,7 @@ from .processes import FakeProcesses
 from .network import FakeNetwork
 from .time import FakeTime
 from .threads import FakeThreads
+from .executable import FakeExecutable
 
 
 __all__ = [
@@ -19,6 +20,7 @@ __all__ = [
     "FakeNetwork",
     "FakeTime",
     "FakeThreads",
+    "FakeExecutable",
 ]
 
 
diff --git a/systemfixtures/executable.py b/systemfixtures/executable.py
new file mode 100644
index 0000000..38fee19
--- /dev/null
+++ b/systemfixtures/executable.py
@@ -0,0 +1,69 @@
+import os
+import socket
+
+from fixtures import (
+    Fixture,
+    TempDir,
+)
+
+
+SUBSTITUTIONS = {
+}
+
+
+class FakeExecutable(Fixture):
+    """Create Python scripts that mimic the behavior of real executables."""
+
+    def _setUp(self):
+        self.path = self.useFixture(TempDir()).join("executable")
+        self.line("#!/usr/bin/env python")
+        os.chmod(self.path, 0o0755)
+
+    def out(self, text):
+        self.line("import sys")
+        self.line("sys.stdout.write('{}\\n')".format(text))
+        self.line("sys.stdout.flush()")
+
+    def sleep(self, seconds):
+        self.line("import time")
+        self.line("time.sleep({})".format(seconds))
+
+    def hang(self):
+        self.line("import time")
+        self.line("import signal")
+        self.line("signal.signal(signal.SIGTERM, lambda *args: None)")
+        self.line("while True: time.sleep(1)")
+
+    def listen(self, port=None):
+        if port is None:
+            port = allocate_port()
+        self.port = port
+        self.line("import socket")
+        self.line("sock = socket.socket()")
+        self.line("sock.bind(('localhost', {}))".format(self.port))
+        self.line("sock.listen(0)")
+
+    def line(self, line):
+        with open(self.path, "a") as fd:
+            fd.write("{}\n".format(line))
+
+
+def get_port(socket):
+    """Return the port to which a socket is bound."""
+    addr, port = socket.getsockname()
+    return port
+
+
+def allocate_port():
+    """Allocate an unused port.
+
+    There is a small race condition here (between the time we allocate the
+    port, and the time it actually gets used), but for the purposes for which
+    this function gets used it isn't a problem in practice.
+    """
+    sock = socket.socket()
+    try:
+        sock.bind(("localhost", 0))
+        return get_port(sock)
+    finally:
+        sock.close()
diff --git a/systemfixtures/tests/test_executables.py b/systemfixtures/tests/test_executables.py
new file mode 100644
index 0000000..313c157
--- /dev/null
+++ b/systemfixtures/tests/test_executables.py
@@ -0,0 +1,51 @@
+import os
+import socket
+import subprocess
+
+from testtools import TestCase
+from testtools.matchers import (
+    Contains,
+    FileContains,
+)
+
+from ..executable import FakeExecutable
+
+
+class FakeGroupsTest(TestCase):
+
+    def setUp(self):
+        super(FakeGroupsTest, self).setUp()
+        self.executable = self.useFixture(FakeExecutable())
+
+    def test_out(self):
+        self.executable.out("hello")
+        self.assertEqual(
+            b"hello\n", subprocess.check_output([self.executable.path]))
+
+    def test_sleep(self):
+        self.executable.sleep(1)
+        self.assertThat(
+            self.executable.path,
+            FileContains(matcher=Contains("time.sleep(1)")))
+
+    def test_listen(self):
+        self.executable.listen()
+        self.executable.out("hello")
+        process = subprocess.Popen(
+            [self.executable.path], stdout=subprocess.PIPE)
+        self.addCleanup(process.wait)
+        self.addCleanup(process.kill)
+        # This ensure that the port will be open
+        self.assertEqual(b"hello\n", process.stdout.read(6))
+        sock = socket.socket()
+        sock.connect(("127.0.0.1", self.executable.port))
+        self.assertEqual("127.0.0.1", sock.getsockname()[0])
+
+    def test_hang(self):
+        self.executable.hang()
+        process = subprocess.Popen(
+            [self.executable.path], stdout=subprocess.PIPE)
+        process.terminate()
+        self.addCleanup(process.wait)
+        self.addCleanup(process.kill)
+        self.assertEqual((0, 0), os.waitpid(process.pid, os.WNOHANG))

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/systemfixtures.git



More information about the Python-modules-commits mailing list