annotate python-daemon-2.0.5/test/test_pidfile.py @ 47:b19e848f9886

update xena to v16
author jingchunzhu
date Fri, 07 Aug 2015 17:01:10 -0700
parents 7ceb967147c3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
2 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
3 # test/test_pidfile.py
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
4 # Part of ‘python-daemon’, an implementation of PEP 3143.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
5 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
6 # Copyright © 2008–2015 Ben Finney <ben+python@benfinney.id.au>
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
7 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
8 # This is free software: you may copy, modify, and/or distribute this work
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
9 # under the terms of the Apache License, version 2.0 as published by the
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
10 # Apache Software Foundation.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
11 # No warranty expressed or implied. See the file ‘LICENSE.ASF-2’ for details.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
12
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
13 """ Unit test for ‘pidfile’ module.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
14 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
15
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
16 from __future__ import (absolute_import, unicode_literals)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
17
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
18 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
19 # Python 3 standard library.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
20 import builtins
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
21 except ImportError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
22 # Python 2 standard library.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
23 import __builtin__ as builtins
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
24 import os
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
25 import itertools
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
26 import tempfile
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
27 import errno
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
28 import functools
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
29 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
30 # Standard library of Python 2.7 and later.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
31 from io import StringIO
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
32 except ImportError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
33 # Standard library of Python 2.6 and earlier.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
34 from StringIO import StringIO
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
35
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
36 import mock
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
37 import lockfile
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
38
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
39 from . import scaffold
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
40
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
41 import daemon.pidfile
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
42
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
43
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
44 class FakeFileDescriptorStringIO(StringIO, object):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
45 """ A StringIO class that fakes a file descriptor. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
46
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
47 _fileno_generator = itertools.count()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
48
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
49 def __init__(self, *args, **kwargs):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
50 self._fileno = next(self._fileno_generator)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
51 super(FakeFileDescriptorStringIO, self).__init__(*args, **kwargs)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
52
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
53 def fileno(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
54 return self._fileno
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
55
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
56 def __enter__(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
57 return self
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
58
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
59 def __exit__(self, exc_type, exc_val, exc_tb):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
60 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
61
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
62
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
63 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
64 FileNotFoundError
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
65 PermissionError
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
66 except NameError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
67 # Python 2 uses IOError.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
68 FileNotFoundError = functools.partial(IOError, errno.ENOENT)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
69 PermissionError = functools.partial(IOError, errno.EPERM)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
70
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
71
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
72 def make_pidlockfile_scenarios():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
73 """ Make a collection of scenarios for testing `PIDLockFile` instances.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
74
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
75 :return: A collection of scenarios for tests involving
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
76 `PIDLockfFile` instances.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
77
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
78 The collection is a mapping from scenario name to a dictionary of
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
79 scenario attributes.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
80
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
81 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
82
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
83 fake_current_pid = 235
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
84 fake_other_pid = 8642
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
85 fake_pidfile_path = tempfile.mktemp()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
86
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
87 fake_pidfile_empty = FakeFileDescriptorStringIO()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
88 fake_pidfile_current_pid = FakeFileDescriptorStringIO(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
89 "{pid:d}\n".format(pid=fake_current_pid))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
90 fake_pidfile_other_pid = FakeFileDescriptorStringIO(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
91 "{pid:d}\n".format(pid=fake_other_pid))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
92 fake_pidfile_bogus = FakeFileDescriptorStringIO(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
93 "b0gUs")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
94
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
95 scenarios = {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
96 'simple': {},
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
97 'not-exist': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
98 'open_func_name': 'fake_open_nonexist',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
99 'os_open_func_name': 'fake_os_open_nonexist',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
100 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
101 'not-exist-write-denied': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
102 'open_func_name': 'fake_open_nonexist',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
103 'os_open_func_name': 'fake_os_open_nonexist',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
104 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
105 'not-exist-write-busy': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
106 'open_func_name': 'fake_open_nonexist',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
107 'os_open_func_name': 'fake_os_open_nonexist',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
108 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
109 'exist-read-denied': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
110 'open_func_name': 'fake_open_read_denied',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
111 'os_open_func_name': 'fake_os_open_read_denied',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
112 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
113 'exist-locked-read-denied': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
114 'locking_pid': fake_other_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
115 'open_func_name': 'fake_open_read_denied',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
116 'os_open_func_name': 'fake_os_open_read_denied',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
117 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
118 'exist-empty': {},
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
119 'exist-invalid': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
120 'pidfile': fake_pidfile_bogus,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
121 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
122 'exist-current-pid': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
123 'pidfile': fake_pidfile_current_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
124 'pidfile_pid': fake_current_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
125 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
126 'exist-current-pid-locked': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
127 'pidfile': fake_pidfile_current_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
128 'pidfile_pid': fake_current_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
129 'locking_pid': fake_current_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
130 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
131 'exist-other-pid': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
132 'pidfile': fake_pidfile_other_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
133 'pidfile_pid': fake_other_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
134 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
135 'exist-other-pid-locked': {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
136 'pidfile': fake_pidfile_other_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
137 'pidfile_pid': fake_other_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
138 'locking_pid': fake_other_pid,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
139 },
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
140 }
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
141
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
142 for scenario in scenarios.values():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
143 scenario['pid'] = fake_current_pid
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
144 scenario['pidfile_path'] = fake_pidfile_path
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
145 if 'pidfile' not in scenario:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
146 scenario['pidfile'] = fake_pidfile_empty
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
147 if 'pidfile_pid' not in scenario:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
148 scenario['pidfile_pid'] = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
149 if 'locking_pid' not in scenario:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
150 scenario['locking_pid'] = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
151 if 'open_func_name' not in scenario:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
152 scenario['open_func_name'] = 'fake_open_okay'
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
153 if 'os_open_func_name' not in scenario:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
154 scenario['os_open_func_name'] = 'fake_os_open_okay'
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
155
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
156 return scenarios
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
157
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
158
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
159 def setup_pidfile_fixtures(testcase):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
160 """ Set up common fixtures for PID file test cases.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
161
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
162 :param testcase: A `TestCase` instance to decorate.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
163
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
164 Decorate the `testcase` with attributes to be fixtures for tests
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
165 involving `PIDLockFile` instances.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
166
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
167 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
168 scenarios = make_pidlockfile_scenarios()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
169 testcase.pidlockfile_scenarios = scenarios
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
170
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
171 def get_scenario_option(testcase, key, default=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
172 value = default
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
173 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
174 value = testcase.scenario[key]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
175 except (NameError, TypeError, AttributeError, KeyError):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
176 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
177 return value
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
178
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
179 func_patcher_os_getpid = mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
180 os, "getpid",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
181 return_value=scenarios['simple']['pid'])
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
182 func_patcher_os_getpid.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
183 testcase.addCleanup(func_patcher_os_getpid.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
184
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
185 def make_fake_open_funcs(testcase):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
186
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
187 def fake_open_nonexist(filename, mode, buffering):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
188 if mode.startswith('r'):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
189 error = FileNotFoundError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
190 "No such file {filename!r}".format(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
191 filename=filename))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
192 raise error
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
193 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
194 result = testcase.scenario['pidfile']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
195 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
196
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
197 def fake_open_read_denied(filename, mode, buffering):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
198 if mode.startswith('r'):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
199 error = PermissionError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
200 "Read denied on {filename!r}".format(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
201 filename=filename))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
202 raise error
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
203 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
204 result = testcase.scenario['pidfile']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
205 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
206
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
207 def fake_open_okay(filename, mode, buffering):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
208 result = testcase.scenario['pidfile']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
209 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
210
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
211 def fake_os_open_nonexist(filename, flags, mode):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
212 if (flags & os.O_CREAT):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
213 result = testcase.scenario['pidfile'].fileno()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
214 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
215 error = FileNotFoundError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
216 "No such file {filename!r}".format(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
217 filename=filename))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
218 raise error
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
219 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
220
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
221 def fake_os_open_read_denied(filename, flags, mode):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
222 if (flags & os.O_CREAT):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
223 result = testcase.scenario['pidfile'].fileno()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
224 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
225 error = PermissionError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
226 "Read denied on {filename!r}".format(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
227 filename=filename))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
228 raise error
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
229 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
230
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
231 def fake_os_open_okay(filename, flags, mode):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
232 result = testcase.scenario['pidfile'].fileno()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
233 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
234
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
235 funcs = dict(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
236 (name, obj) for (name, obj) in vars().items()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
237 if callable(obj))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
238
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
239 return funcs
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
240
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
241 testcase.fake_pidfile_open_funcs = make_fake_open_funcs(testcase)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
242
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
243 def fake_open(filename, mode='rt', buffering=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
244 scenario_path = get_scenario_option(testcase, 'pidfile_path')
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
245 if filename == scenario_path:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
246 func_name = testcase.scenario['open_func_name']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
247 fake_open_func = testcase.fake_pidfile_open_funcs[func_name]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
248 result = fake_open_func(filename, mode, buffering)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
249 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
250 result = FakeFileDescriptorStringIO()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
251 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
252
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
253 mock_open = mock.mock_open()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
254 mock_open.side_effect = fake_open
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
255
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
256 func_patcher_builtin_open = mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
257 builtins, "open",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
258 new=mock_open)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
259 func_patcher_builtin_open.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
260 testcase.addCleanup(func_patcher_builtin_open.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
261
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
262 def fake_os_open(filename, flags, mode=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
263 scenario_path = get_scenario_option(testcase, 'pidfile_path')
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
264 if filename == scenario_path:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
265 func_name = testcase.scenario['os_open_func_name']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
266 fake_os_open_func = testcase.fake_pidfile_open_funcs[func_name]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
267 result = fake_os_open_func(filename, flags, mode)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
268 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
269 result = FakeFileDescriptorStringIO().fileno()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
270 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
271
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
272 mock_os_open = mock.MagicMock(side_effect=fake_os_open)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
273
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
274 func_patcher_os_open = mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
275 os, "open",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
276 new=mock_os_open)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
277 func_patcher_os_open.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
278 testcase.addCleanup(func_patcher_os_open.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
279
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
280 def fake_os_fdopen(fd, mode='rt', buffering=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
281 scenario_pidfile = get_scenario_option(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
282 testcase, 'pidfile', FakeFileDescriptorStringIO())
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
283 if fd == testcase.scenario['pidfile'].fileno():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
284 result = testcase.scenario['pidfile']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
285 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
286 raise OSError(errno.EBADF, "Bad file descriptor")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
287 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
288
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
289 mock_os_fdopen = mock.MagicMock(side_effect=fake_os_fdopen)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
290
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
291 func_patcher_os_fdopen = mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
292 os, "fdopen",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
293 new=mock_os_fdopen)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
294 func_patcher_os_fdopen.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
295 testcase.addCleanup(func_patcher_os_fdopen.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
296
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
297
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
298 def make_lockfile_method_fakes(scenario):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
299 """ Make common fake methods for lockfile class.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
300
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
301 :param scenario: A scenario for testing with PIDLockFile.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
302 :return: A mapping from normal function name to the corresponding
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
303 fake function.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
304
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
305 Each fake function behaves appropriately for the specified `scenario`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
306
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
307 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
308
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
309 def fake_func_read_pid():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
310 return scenario['pidfile_pid']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
311 def fake_func_is_locked():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
312 return (scenario['locking_pid'] is not None)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
313 def fake_func_i_am_locking():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
314 return (
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
315 scenario['locking_pid'] == scenario['pid'])
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
316 def fake_func_acquire(timeout=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
317 if scenario['locking_pid'] is not None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
318 raise lockfile.AlreadyLocked()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
319 scenario['locking_pid'] = scenario['pid']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
320 def fake_func_release():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
321 if scenario['locking_pid'] is None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
322 raise lockfile.NotLocked()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
323 if scenario['locking_pid'] != scenario['pid']:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
324 raise lockfile.NotMyLock()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
325 scenario['locking_pid'] = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
326 def fake_func_break_lock():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
327 scenario['locking_pid'] = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
328
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
329 fake_methods = dict(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
330 (
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
331 func_name.replace('fake_func_', ''),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
332 mock.MagicMock(side_effect=fake_func))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
333 for (func_name, fake_func) in vars().items()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
334 if func_name.startswith('fake_func_'))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
335
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
336 return fake_methods
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
337
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
338
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
339 def apply_lockfile_method_mocks(mock_lockfile, testcase, scenario):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
340 """ Apply common fake methods to mock lockfile class.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
341
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
342 :param mock_lockfile: An object providing the `LockFile` interface.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
343 :param testcase: The `TestCase` instance providing the context for
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
344 the patch.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
345 :param scenario: The `PIDLockFile` test scenario to use.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
346
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
347 Mock the `LockFile` methods of `mock_lockfile`, by applying fake
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
348 methods customised for `scenario`. The mock is does by a patch
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
349 within the context of `testcase`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
350
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
351 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
352 fake_methods = dict(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
353 (func_name, fake_func)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
354 for (func_name, fake_func) in
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
355 make_lockfile_method_fakes(scenario).items()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
356 if func_name not in ['read_pid'])
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
357
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
358 for (func_name, fake_func) in fake_methods.items():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
359 func_patcher = mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
360 mock_lockfile, func_name,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
361 new=fake_func)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
362 func_patcher.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
363 testcase.addCleanup(func_patcher.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
364
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
365
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
366 def setup_pidlockfile_fixtures(testcase, scenario_name=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
367 """ Set up common fixtures for PIDLockFile test cases.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
368
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
369 :param testcase: The `TestCase` instance to decorate.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
370 :param scenario_name: The name of the `PIDLockFile` scenario to use.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
371
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
372 Decorate the `testcase` with attributes that are fixtures for test
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
373 cases involving `PIDLockFile` instances.`
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
374
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
375 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
376
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
377 setup_pidfile_fixtures(testcase)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
378
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
379 for func_name in [
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
380 'write_pid_to_pidfile',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
381 'remove_existing_pidfile',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
382 ]:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
383 func_patcher = mock.patch.object(lockfile.pidlockfile, func_name)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
384 func_patcher.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
385 testcase.addCleanup(func_patcher.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
386
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
387
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
388 class TimeoutPIDLockFile_TestCase(scaffold.TestCase):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
389 """ Test cases for ‘TimeoutPIDLockFile’ class. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
390
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
391 def setUp(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
392 """ Set up test fixtures. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
393 super(TimeoutPIDLockFile_TestCase, self).setUp()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
394
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
395 pidlockfile_scenarios = make_pidlockfile_scenarios()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
396 self.pidlockfile_scenario = pidlockfile_scenarios['simple']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
397 pidfile_path = self.pidlockfile_scenario['pidfile_path']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
398
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
399 for func_name in ['__init__', 'acquire']:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
400 func_patcher = mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
401 lockfile.pidlockfile.PIDLockFile, func_name)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
402 func_patcher.start()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
403 self.addCleanup(func_patcher.stop)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
404
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
405 self.scenario = {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
406 'pidfile_path': self.pidlockfile_scenario['pidfile_path'],
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
407 'acquire_timeout': self.getUniqueInteger(),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
408 }
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
409
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
410 self.test_kwargs = dict(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
411 path=self.scenario['pidfile_path'],
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
412 acquire_timeout=self.scenario['acquire_timeout'],
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
413 )
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
414 self.test_instance = daemon.pidfile.TimeoutPIDLockFile(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
415 **self.test_kwargs)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
416
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
417 def test_inherits_from_pidlockfile(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
418 """ Should inherit from PIDLockFile. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
419 instance = self.test_instance
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
420 self.assertIsInstance(instance, lockfile.pidlockfile.PIDLockFile)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
421
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
422 def test_init_has_expected_signature(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
423 """ Should have expected signature for ‘__init__’. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
424 def test_func(self, path, acquire_timeout=None, *args, **kwargs): pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
425 test_func.__name__ = str('__init__')
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
426 self.assertFunctionSignatureMatch(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
427 test_func,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
428 daemon.pidfile.TimeoutPIDLockFile.__init__)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
429
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
430 def test_has_specified_acquire_timeout(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
431 """ Should have specified ‘acquire_timeout’ value. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
432 instance = self.test_instance
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
433 expected_timeout = self.test_kwargs['acquire_timeout']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
434 self.assertEqual(expected_timeout, instance.acquire_timeout)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
435
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
436 @mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
437 lockfile.pidlockfile.PIDLockFile, "__init__",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
438 autospec=True)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
439 def test_calls_superclass_init(self, mock_init):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
440 """ Should call the superclass ‘__init__’. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
441 expected_path = self.test_kwargs['path']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
442 instance = daemon.pidfile.TimeoutPIDLockFile(**self.test_kwargs)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
443 mock_init.assert_called_with(instance, expected_path)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
444
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
445 @mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
446 lockfile.pidlockfile.PIDLockFile, "acquire",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
447 autospec=True)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
448 def test_acquire_uses_specified_timeout(self, mock_func_acquire):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
449 """ Should call the superclass ‘acquire’ with specified timeout. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
450 instance = self.test_instance
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
451 test_timeout = self.getUniqueInteger()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
452 expected_timeout = test_timeout
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
453 instance.acquire(test_timeout)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
454 mock_func_acquire.assert_called_with(instance, expected_timeout)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
455
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
456 @mock.patch.object(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
457 lockfile.pidlockfile.PIDLockFile, "acquire",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
458 autospec=True)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
459 def test_acquire_uses_stored_timeout_by_default(self, mock_func_acquire):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
460 """ Should call superclass ‘acquire’ with stored timeout by default. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
461 instance = self.test_instance
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
462 test_timeout = self.test_kwargs['acquire_timeout']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
463 expected_timeout = test_timeout
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
464 instance.acquire()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
465 mock_func_acquire.assert_called_with(instance, expected_timeout)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
466
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
467
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
468 # Local variables:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
469 # coding: utf-8
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
470 # mode: python
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
471 # End:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
472 # vim: fileencoding=utf-8 filetype=python :