From: Nir Soffer <nsoffer(a)redhat.com>
All the helper functions and constants moved to new util module.
This module provides:
- util.start_daemon() - starts a sanlock daemon process.
- util.wait_for_daemon() - wait until sanlock daemon is ready.
- util.sanlock() - run sanlock and return the output. Useful for running
"sanlock client ..." or "sanlock direct ..." commands.
- util.wait_for_termination - wait until a process terminates within a
timeout.
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
tests/__init__.py | 0
tests/daemon_test.py | 89 ++++++++--------------------------------------------
tests/direct_test.py | 11 ++-----
tests/util.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 96 insertions(+), 85 deletions(-)
create mode 100644 tests/__init__.py
create mode 100644 tests/util.py
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/daemon_test.py b/tests/daemon_test.py
index af1e890..d84b838 100644
--- a/tests/daemon_test.py
+++ b/tests/daemon_test.py
@@ -2,83 +2,24 @@
Test sanlock client operations.
"""
-import errno
import io
-import os
import signal
-import socket
import struct
import subprocess
-import time
import pytest
-tests_dir = os.path.dirname(__file__)
-SANLOCK = os.path.join(tests_dir, os.pardir, "src", "sanlock")
-
-ENV = dict(os.environ)
-ENV["SANLOCK_RUN_DIR"] = "/tmp/sanlock"
-ENV["SANLOCK_PRIVILEGED"] = "0"
-
-
-class TimeoutExpired(Exception):
- """ Raised when timeout expired """
-
-
-def start_sanlock_daemon():
- cmd = [SANLOCK, "daemon",
- # no fork and print all logging to stderr
- "-D",
- # don't use watchdog through wdmd
- "-w", "0",
- # don't use mlockall
- "-l", "0",
- # don't use high priority (RR) scheduling
- "-h", "0",
- # run as current user instead of "sanlock"
- "-U", ENV["USER"],
- "-G", ENV["USER"]]
- return subprocess.Popen(cmd, env=ENV)
-
-
-def wait_for_socket(timeout):
- """ Wait until deamon is accepting connections """
- deadline = time.time() + timeout
- path = os.path.join(ENV["SANLOCK_RUN_DIR"], "sanlock.sock")
- s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- while True:
- try:
- s.connect(path)
- return
- except socket.error as e:
- if e[0] not in (errno.ECONNREFUSED, errno.ENOENT):
- raise # Unexpected error
- if time.time() > deadline:
- raise TimeoutExpired
- time.sleep(0.05)
- finally:
- s.close()
-
-
-def wait_for_termination(p, timeout):
- """
- Wait until process terminates, or timeout expires.
- """
- deadline = time.time() + timeout
- while True:
- if p.poll() is not None:
- return
- if time.time() > deadline:
- raise TimeoutExpired
- time.sleep(0.05)
+from . import util
@pytest.fixture
def sanlock_daemon():
- p = start_sanlock_daemon()
+ """
+ Run sanlock daemon during a test.
+ """
+ p = util.start_daemon()
try:
- wait_for_socket(0.5)
+ util.wait_for_daemon(0.5)
yield
finally:
p.terminate()
@@ -87,10 +28,10 @@ def sanlock_daemon():
def test_single_instance(sanlock_daemon):
# Starting another instance while the daemon must fail.
- p = start_sanlock_daemon()
+ p = util.start_daemon()
try:
- wait_for_termination(p, 1.0)
- except TimeoutExpired:
+ util.wait_for_termination(p, 1.0)
+ except util.TimeoutExpired:
p.kill()
p.wait()
assert p.returncode == 1
@@ -99,9 +40,9 @@ def test_single_instance(sanlock_daemon):
def test_start_after_kill():
# After killing the daemon, next instance should be able to start.
for i in range(5):
- p = start_sanlock_daemon()
+ p = util.start_daemon()
try:
- wait_for_socket(0.5)
+ util.wait_for_daemon(0.5)
finally:
p.kill()
p.wait()
@@ -111,7 +52,7 @@ def test_start_after_kill():
def test_client_failure():
# No daemon is running, client must fail
with pytest.raises(subprocess.CalledProcessError) as e:
- run(SANLOCK, "client", "status")
+ util.sanlock("client", "status")
assert e.value.returncode == 1
@@ -122,7 +63,7 @@ def test_init_lockspace(tmpdir, sanlock_daemon):
f.write(b"x" * 1024**2 + b"X" * 512)
lockspace = "name:1:%s:0" % path
- run(SANLOCK, "client", "init", "-s", lockspace)
+ util.sanlock("client", "init", "-s", lockspace)
with io.open(str(path), "rb") as f:
magic, = struct.unpack("< I", f.read(4))
@@ -133,7 +74,3 @@ def test_init_lockspace(tmpdir, sanlock_daemon):
# Do not modify data after the lockspace area.
f.seek(1024**2, io.SEEK_SET)
assert f.read(512) == b"X" * 512
-
-
-def run(*args):
- return subprocess.check_output(args, env=ENV)
diff --git a/tests/direct_test.py b/tests/direct_test.py
index 3536f5e..fa7c572 100644
--- a/tests/direct_test.py
+++ b/tests/direct_test.py
@@ -3,12 +3,9 @@ Test sanlock direct options.
"""
import io
-import os
import struct
-import subprocess
-tests_dir = os.path.dirname(__file__)
-SANLOCK = os.path.join(tests_dir, os.pardir, "src", "sanlock")
+from . import util
def test_init_lockspace(tmpdir):
@@ -18,7 +15,7 @@ def test_init_lockspace(tmpdir):
f.write(b"x" * 1024**2 + b"X" * 512)
lockspace = "name:1:%s:0" % path
- run(SANLOCK, "direct", "init", "-s", lockspace)
+ util.sanlock("direct", "init", "-s", lockspace)
with io.open(str(path), "rb") as f:
magic, = struct.unpack("< I", f.read(4))
@@ -29,7 +26,3 @@ def test_init_lockspace(tmpdir):
# Do not modify data after the lockspace area.
f.seek(1024**2, io.SEEK_SET)
assert f.read(512) == b"X" * 512
-
-
-def run(*args):
- return subprocess.check_output(args)
diff --git a/tests/util.py b/tests/util.py
new file mode 100644
index 0000000..002425b
--- /dev/null
+++ b/tests/util.py
@@ -0,0 +1,81 @@
+"""
+Testing utilities
+"""
+
+import errno
+import os
+import socket
+import subprocess
+import time
+
+TESTDIR = os.path.dirname(__file__)
+SANLOCK = os.path.join(TESTDIR, os.pardir, "src", "sanlock")
+
+ENV = dict(os.environ)
+ENV["SANLOCK_RUN_DIR"] = "/tmp/sanlock"
+ENV["SANLOCK_PRIVILEGED"] = "0"
+
+
+class TimeoutExpired(Exception):
+ """ Raised when timeout expired """
+
+
+def start_daemon():
+ cmd = [SANLOCK, "daemon",
+ # no fork and print all logging to stderr
+ "-D",
+ # don't use watchdog through wdmd
+ "-w", "0",
+ # don't use mlockall
+ "-l", "0",
+ # don't use high priority (RR) scheduling
+ "-h", "0",
+ # run as current user instead of "sanlock"
+ "-U", ENV["USER"],
+ "-G", ENV["USER"]]
+ return subprocess.Popen(cmd, env=ENV)
+
+
+def wait_for_daemon(timeout):
+ """
+ Wait until deamon is accepting connections
+ """
+ deadline = time.time() + timeout
+ path = os.path.join(ENV["SANLOCK_RUN_DIR"], "sanlock.sock")
+ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ try:
+ while True:
+ try:
+ s.connect(path)
+ return
+ except socket.error as e:
+ if e[0] not in (errno.ECONNREFUSED, errno.ENOENT):
+ raise # Unexpected error
+ if time.time() > deadline:
+ raise TimeoutExpired
+ time.sleep(0.05)
+ finally:
+ s.close()
+
+
+def sanlock(*args):
+ """
+ Run sanlock returning the process stdout, or raising
+ subprocess.CalledProcessError on failures.
+ """
+ cmd = [SANLOCK]
+ cmd.extend(args)
+ return subprocess.check_output(cmd, env=ENV)
+
+
+def wait_for_termination(p, timeout):
+ """
+ Wait until process terminates, or timeout expires.
+ """
+ deadline = time.time() + timeout
+ while True:
+ if p.poll() is not None:
+ return
+ if time.time() > deadline:
+ raise TimeoutExpired
+ time.sleep(0.05)
--
2.9.5