Statistics
| Branch: | Tag: | Revision:

root / test / py / cmdlib / testsupport / processor_mock.py @ f3cb57d5

History | View | Annotate | Download (6.4 kB)

1 3efa7659 Thomas Thrainer
#
2 3efa7659 Thomas Thrainer
#
3 3efa7659 Thomas Thrainer
4 3efa7659 Thomas Thrainer
# Copyright (C) 2013 Google Inc.
5 3efa7659 Thomas Thrainer
#
6 3efa7659 Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 3efa7659 Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 3efa7659 Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 3efa7659 Thomas Thrainer
# (at your option) any later version.
10 3efa7659 Thomas Thrainer
#
11 3efa7659 Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 3efa7659 Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 3efa7659 Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3efa7659 Thomas Thrainer
# General Public License for more details.
15 3efa7659 Thomas Thrainer
#
16 3efa7659 Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 3efa7659 Thomas Thrainer
# along with this program; if not, write to the Free Software
18 3efa7659 Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 3efa7659 Thomas Thrainer
# 02110-1301, USA.
20 3efa7659 Thomas Thrainer
21 bd39b6bb Thomas Thrainer
22 bd39b6bb Thomas Thrainer
"""Support for mocking the opcode processor"""
23 bd39b6bb Thomas Thrainer
24 bd39b6bb Thomas Thrainer
25 3efa7659 Thomas Thrainer
import re
26 3efa7659 Thomas Thrainer
27 3efa7659 Thomas Thrainer
from ganeti import constants
28 3efa7659 Thomas Thrainer
from ganeti import mcpu
29 3efa7659 Thomas Thrainer
30 3efa7659 Thomas Thrainer
31 3efa7659 Thomas Thrainer
class LogRecordingCallback(mcpu.OpExecCbBase):
32 3efa7659 Thomas Thrainer
  """Helper class for log output recording.
33 3efa7659 Thomas Thrainer

34 3efa7659 Thomas Thrainer
  """
35 3efa7659 Thomas Thrainer
  def __init__(self, processor):
36 3efa7659 Thomas Thrainer
    self.processor = processor
37 3efa7659 Thomas Thrainer
38 3efa7659 Thomas Thrainer
  def Feedback(self, *args):
39 3efa7659 Thomas Thrainer
    assert len(args) < 3
40 3efa7659 Thomas Thrainer
41 3efa7659 Thomas Thrainer
    if len(args) == 1:
42 3efa7659 Thomas Thrainer
      log_type = constants.ELOG_MESSAGE
43 3efa7659 Thomas Thrainer
      log_msg = args[0]
44 3efa7659 Thomas Thrainer
    else:
45 3efa7659 Thomas Thrainer
      (log_type, log_msg) = args
46 3efa7659 Thomas Thrainer
47 3efa7659 Thomas Thrainer
    self.processor.log_entries.append((log_type, log_msg))
48 3efa7659 Thomas Thrainer
49 bd39b6bb Thomas Thrainer
  def SubmitManyJobs(self, jobs):
50 c60f7675 Thomas Thrainer
    results = []
51 c60f7675 Thomas Thrainer
    for idx, _ in enumerate(jobs):
52 c60f7675 Thomas Thrainer
      results.append((True, idx))
53 c60f7675 Thomas Thrainer
    return results
54 bd39b6bb Thomas Thrainer
55 3efa7659 Thomas Thrainer
56 3efa7659 Thomas Thrainer
class ProcessorMock(mcpu.Processor):
57 3efa7659 Thomas Thrainer
  """Mocked opcode processor for tests.
58 3efa7659 Thomas Thrainer

59 3efa7659 Thomas Thrainer
  This class actually performs much more than a mock, as it drives the
60 3efa7659 Thomas Thrainer
  execution of LU's. But it also provides access to the log output of the LU
61 3efa7659 Thomas Thrainer
  the result of the execution.
62 3efa7659 Thomas Thrainer

63 3efa7659 Thomas Thrainer
  See L{ExecOpCodeAndRecordOutput} for the main method of this class.
64 3efa7659 Thomas Thrainer

65 3efa7659 Thomas Thrainer
  """
66 3efa7659 Thomas Thrainer
67 3efa7659 Thomas Thrainer
  def __init__(self, context):
68 9051a390 Thomas Thrainer
    super(ProcessorMock, self).__init__(context, 1, True)
69 3efa7659 Thomas Thrainer
    self.log_entries = []
70 b8f45292 Thomas Thrainer
    self._lu_test_func = None
71 3efa7659 Thomas Thrainer
72 3efa7659 Thomas Thrainer
  def ExecOpCodeAndRecordOutput(self, op):
73 3efa7659 Thomas Thrainer
    """Executes the given opcode and records the output for further inspection.
74 3efa7659 Thomas Thrainer

75 3efa7659 Thomas Thrainer
    @param op: the opcode to execute.
76 3efa7659 Thomas Thrainer
    @return: see L{mcpu.Processor.ExecOpCode}
77 3efa7659 Thomas Thrainer

78 3efa7659 Thomas Thrainer
    """
79 3efa7659 Thomas Thrainer
    return self.ExecOpCode(op, LogRecordingCallback(self))
80 3efa7659 Thomas Thrainer
81 b8f45292 Thomas Thrainer
  def _ExecLU(self, lu):
82 f3cb57d5 Michele Tartara
    # pylint: disable=W0212
83 b8f45292 Thomas Thrainer
    if not self._lu_test_func:
84 b8f45292 Thomas Thrainer
      return super(ProcessorMock, self)._ExecLU(lu)
85 b8f45292 Thomas Thrainer
    else:
86 b8f45292 Thomas Thrainer
      # required by a lot LU's, and usually passed in Exec
87 b8f45292 Thomas Thrainer
      lu._feedback_fn = self.Log
88 b8f45292 Thomas Thrainer
      return self._lu_test_func(lu)
89 b8f45292 Thomas Thrainer
90 b8f45292 Thomas Thrainer
  def _CheckLUResult(self, op, result):
91 f3cb57d5 Michele Tartara
    # pylint: disable=W0212
92 b8f45292 Thomas Thrainer
    if not self._lu_test_func:
93 b8f45292 Thomas Thrainer
      return super(ProcessorMock, self)._CheckLUResult(op, result)
94 b8f45292 Thomas Thrainer
    else:
95 b8f45292 Thomas Thrainer
      pass
96 b8f45292 Thomas Thrainer
97 b8f45292 Thomas Thrainer
  def RunWithLockedLU(self, op, func):
98 b8f45292 Thomas Thrainer
    """Takes the given opcode, creates a LU and runs func with it.
99 b8f45292 Thomas Thrainer

100 b8f45292 Thomas Thrainer
    @param op: the opcode to get the LU for.
101 b8f45292 Thomas Thrainer
    @param func: the function to run with the created and locked LU.
102 b8f45292 Thomas Thrainer
    @return: the result of func.
103 b8f45292 Thomas Thrainer

104 b8f45292 Thomas Thrainer
    """
105 b8f45292 Thomas Thrainer
    self._lu_test_func = func
106 b8f45292 Thomas Thrainer
    try:
107 b8f45292 Thomas Thrainer
      return self.ExecOpCodeAndRecordOutput(op)
108 b8f45292 Thomas Thrainer
    finally:
109 b8f45292 Thomas Thrainer
      self._lu_test_func = None
110 b8f45292 Thomas Thrainer
111 3efa7659 Thomas Thrainer
  def GetLogEntries(self):
112 3efa7659 Thomas Thrainer
    """Return the list of recorded log entries.
113 3efa7659 Thomas Thrainer

114 3efa7659 Thomas Thrainer
    @rtype: list of (string, string) tuples
115 3efa7659 Thomas Thrainer
    @return: the list of recorded log entries
116 3efa7659 Thomas Thrainer

117 3efa7659 Thomas Thrainer
    """
118 3efa7659 Thomas Thrainer
    return self.log_entries
119 3efa7659 Thomas Thrainer
120 3efa7659 Thomas Thrainer
  def GetLogMessages(self):
121 3efa7659 Thomas Thrainer
    """Return the list of recorded log messages.
122 3efa7659 Thomas Thrainer

123 3efa7659 Thomas Thrainer
    @rtype: list of string
124 3efa7659 Thomas Thrainer
    @return: the list of recorded log messages
125 3efa7659 Thomas Thrainer

126 3efa7659 Thomas Thrainer
    """
127 3efa7659 Thomas Thrainer
    return [msg for _, msg in self.log_entries]
128 3efa7659 Thomas Thrainer
129 3efa7659 Thomas Thrainer
  def GetLogEntriesString(self):
130 3efa7659 Thomas Thrainer
    """Return a string with all log entries separated by a newline.
131 3efa7659 Thomas Thrainer

132 3efa7659 Thomas Thrainer
    """
133 bd39b6bb Thomas Thrainer
    return "\n".join("%s: %s" % (log_type, msg)
134 bd39b6bb Thomas Thrainer
                     for log_type, msg in self.GetLogEntries())
135 3efa7659 Thomas Thrainer
136 3efa7659 Thomas Thrainer
  def GetLogMessagesString(self):
137 3efa7659 Thomas Thrainer
    """Return a string with all log messages separated by a newline.
138 3efa7659 Thomas Thrainer

139 3efa7659 Thomas Thrainer
    """
140 3efa7659 Thomas Thrainer
    return "\n".join("%s" % msg for _, msg in self.GetLogEntries())
141 3efa7659 Thomas Thrainer
142 3efa7659 Thomas Thrainer
  def assertLogContainsEntry(self, expected_type, expected_msg):
143 3efa7659 Thomas Thrainer
    """Asserts that the log contains the exact given entry.
144 3efa7659 Thomas Thrainer

145 3efa7659 Thomas Thrainer
    @type expected_type: string
146 3efa7659 Thomas Thrainer
    @param expected_type: the expected type
147 3efa7659 Thomas Thrainer
    @type expected_msg: string
148 3efa7659 Thomas Thrainer
    @param expected_msg: the expected message
149 3efa7659 Thomas Thrainer

150 3efa7659 Thomas Thrainer
    """
151 bd39b6bb Thomas Thrainer
    for log_type, msg in self.log_entries:
152 bd39b6bb Thomas Thrainer
      if log_type == expected_type and msg == expected_msg:
153 3efa7659 Thomas Thrainer
        return
154 3efa7659 Thomas Thrainer
155 3efa7659 Thomas Thrainer
    raise AssertionError(
156 3efa7659 Thomas Thrainer
      "Could not find '%s' (type '%s') in LU log messages. Log is:\n%s" %
157 3efa7659 Thomas Thrainer
      (expected_msg, expected_type, self.GetLogEntriesString()))
158 3efa7659 Thomas Thrainer
159 3efa7659 Thomas Thrainer
  def assertLogContainsMessage(self, expected_msg):
160 3efa7659 Thomas Thrainer
    """Asserts that the log contains the exact given message.
161 3efa7659 Thomas Thrainer

162 3efa7659 Thomas Thrainer
    @type expected_msg: string
163 3efa7659 Thomas Thrainer
    @param expected_msg: the expected message
164 3efa7659 Thomas Thrainer

165 3efa7659 Thomas Thrainer
    """
166 3efa7659 Thomas Thrainer
    for msg in self.GetLogMessages():
167 3efa7659 Thomas Thrainer
      if msg == expected_msg:
168 3efa7659 Thomas Thrainer
        return
169 3efa7659 Thomas Thrainer
170 3efa7659 Thomas Thrainer
    raise AssertionError(
171 3efa7659 Thomas Thrainer
      "Could not find '%s' in LU log messages. Log is:\n%s" %
172 3efa7659 Thomas Thrainer
      (expected_msg, self.GetLogMessagesString()))
173 3efa7659 Thomas Thrainer
174 3efa7659 Thomas Thrainer
  def assertLogContainsRegex(self, expected_regex):
175 3efa7659 Thomas Thrainer
    """Asserts that the log contains a message which matches the regex.
176 3efa7659 Thomas Thrainer

177 3efa7659 Thomas Thrainer
    @type expected_regex: string
178 3efa7659 Thomas Thrainer
    @param expected_regex: regular expression to match messages with.
179 3efa7659 Thomas Thrainer

180 3efa7659 Thomas Thrainer
    """
181 3efa7659 Thomas Thrainer
    for msg in self.GetLogMessages():
182 3efa7659 Thomas Thrainer
      if re.search(expected_regex, msg) is not None:
183 3efa7659 Thomas Thrainer
        return
184 3efa7659 Thomas Thrainer
185 3efa7659 Thomas Thrainer
    raise AssertionError(
186 3efa7659 Thomas Thrainer
      "Could not find '%s' in LU log messages. Log is:\n%s" %
187 3efa7659 Thomas Thrainer
      (expected_regex, self.GetLogMessagesString())
188 bd39b6bb Thomas Thrainer
    )
189 c487ae24 Thomas Thrainer
190 9fdb10be Thomas Thrainer
  def assertLogContainsInLine(self, expected):
191 9fdb10be Thomas Thrainer
    """Asserts that the log contains a message which contains a string.
192 9fdb10be Thomas Thrainer

193 9fdb10be Thomas Thrainer
    @type expected: string
194 9fdb10be Thomas Thrainer
    @param expected: string to search in messages.
195 9fdb10be Thomas Thrainer

196 9fdb10be Thomas Thrainer
    """
197 9fdb10be Thomas Thrainer
    self.assertLogContainsRegex(re.escape(expected))
198 9fdb10be Thomas Thrainer
199 9fdb10be Thomas Thrainer
  def assertLogDoesNotContainRegex(self, expected_regex):
200 9fdb10be Thomas Thrainer
    """Asserts that the log does not contain a message which matches the regex.
201 9fdb10be Thomas Thrainer

202 9fdb10be Thomas Thrainer
    @type expected_regex: string
203 9fdb10be Thomas Thrainer
    @param expected_regex: regular expression to match messages with.
204 9fdb10be Thomas Thrainer

205 9fdb10be Thomas Thrainer
    """
206 9fdb10be Thomas Thrainer
    for msg in self.GetLogMessages():
207 9fdb10be Thomas Thrainer
      if re.search(expected_regex, msg) is not None:
208 9fdb10be Thomas Thrainer
        raise AssertionError(
209 9fdb10be Thomas Thrainer
          "Found '%s' in LU log messages. Log is:\n%s" %
210 9fdb10be Thomas Thrainer
          (expected_regex, self.GetLogMessagesString())
211 9fdb10be Thomas Thrainer
        )
212 9fdb10be Thomas Thrainer
213 c487ae24 Thomas Thrainer
  def assertLogIsEmpty(self):
214 c487ae24 Thomas Thrainer
    """Asserts that the log does not contain any message.
215 c487ae24 Thomas Thrainer

216 c487ae24 Thomas Thrainer
    """
217 c487ae24 Thomas Thrainer
    if len(self.GetLogMessages()) > 0:
218 c487ae24 Thomas Thrainer
      raise AssertionError("Log is not empty. Log is:\n%s" %
219 c487ae24 Thomas Thrainer
                           self.GetLogMessagesString())
220 b8f45292 Thomas Thrainer
221 b8f45292 Thomas Thrainer
  def ClearLogMessages(self):
222 b8f45292 Thomas Thrainer
    """Clears all recorded log messages.
223 b8f45292 Thomas Thrainer

224 b8f45292 Thomas Thrainer
    This is useful if you use L{GetLockedLU} and want to test multiple calls
225 b8f45292 Thomas Thrainer
    on it.
226 b8f45292 Thomas Thrainer

227 b8f45292 Thomas Thrainer
    """
228 b8f45292 Thomas Thrainer
    self.log_entries = []