Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4.3 kB)

1
#
2
#
3

    
4
# Copyright (C) 2013 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Support for mocking the opcode processor"""
23

    
24

    
25
import re
26

    
27
from ganeti import constants
28
from ganeti import mcpu
29

    
30

    
31
class LogRecordingCallback(mcpu.OpExecCbBase):
32
  """Helper class for log output recording.
33

34
  """
35
  def __init__(self, processor):
36
    self.processor = processor
37

    
38
  def Feedback(self, *args):
39
    assert len(args) < 3
40

    
41
    if len(args) == 1:
42
      log_type = constants.ELOG_MESSAGE
43
      log_msg = args[0]
44
    else:
45
      (log_type, log_msg) = args
46

    
47
    self.processor.log_entries.append((log_type, log_msg))
48

    
49
  def SubmitManyJobs(self, jobs):
50
    return mcpu.OpExecCbBase.SubmitManyJobs(self, jobs)
51

    
52

    
53
class ProcessorMock(mcpu.Processor):
54
  """Mocked opcode processor for tests.
55

56
  This class actually performs much more than a mock, as it drives the
57
  execution of LU's. But it also provides access to the log output of the LU
58
  the result of the execution.
59

60
  See L{ExecOpCodeAndRecordOutput} for the main method of this class.
61

62
  """
63

    
64
  def __init__(self, context):
65
    super(ProcessorMock, self).__init__(context, 0, True)
66
    self.log_entries = []
67

    
68
  def ExecOpCodeAndRecordOutput(self, op):
69
    """Executes the given opcode and records the output for further inspection.
70

71
    @param op: the opcode to execute.
72
    @return: see L{mcpu.Processor.ExecOpCode}
73

74
    """
75
    return self.ExecOpCode(op, LogRecordingCallback(self))
76

    
77
  def GetLogEntries(self):
78
    """Return the list of recorded log entries.
79

80
    @rtype: list of (string, string) tuples
81
    @return: the list of recorded log entries
82

83
    """
84
    return self.log_entries
85

    
86
  def GetLogMessages(self):
87
    """Return the list of recorded log messages.
88

89
    @rtype: list of string
90
    @return: the list of recorded log messages
91

92
    """
93
    return [msg for _, msg in self.log_entries]
94

    
95
  def GetLogEntriesString(self):
96
    """Return a string with all log entries separated by a newline.
97

98
    """
99
    return "\n".join("%s: %s" % (log_type, msg)
100
                     for log_type, msg in self.GetLogEntries())
101

    
102
  def GetLogMessagesString(self):
103
    """Return a string with all log messages separated by a newline.
104

105
    """
106
    return "\n".join("%s" % msg for _, msg in self.GetLogEntries())
107

    
108
  def assertLogContainsEntry(self, expected_type, expected_msg):
109
    """Asserts that the log contains the exact given entry.
110

111
    @type expected_type: string
112
    @param expected_type: the expected type
113
    @type expected_msg: string
114
    @param expected_msg: the expected message
115

116
    """
117
    for log_type, msg in self.log_entries:
118
      if log_type == expected_type and msg == expected_msg:
119
        return
120

    
121
    raise AssertionError(
122
      "Could not find '%s' (type '%s') in LU log messages. Log is:\n%s" %
123
      (expected_msg, expected_type, self.GetLogEntriesString()))
124

    
125
  def assertLogContainsMessage(self, expected_msg):
126
    """Asserts that the log contains the exact given message.
127

128
    @type expected_msg: string
129
    @param expected_msg: the expected message
130

131
    """
132
    for msg in self.GetLogMessages():
133
      if msg == expected_msg:
134
        return
135

    
136
    raise AssertionError(
137
      "Could not find '%s' in LU log messages. Log is:\n%s" %
138
      (expected_msg, self.GetLogMessagesString()))
139

    
140
  def assertLogContainsRegex(self, expected_regex):
141
    """Asserts that the log contains a message which matches the regex.
142

143
    @type expected_regex: string
144
    @param expected_regex: regular expression to match messages with.
145

146
    """
147
    for msg in self.GetLogMessages():
148
      if re.search(expected_regex, msg) is not None:
149
        return
150

    
151
    raise AssertionError(
152
      "Could not find '%s' in LU log messages. Log is:\n%s" %
153
      (expected_regex, self.GetLogMessagesString())
154
    )