Statistics
| Branch: | Tag: | Revision:

root / test / py / cmdlib / testsupport / rpc_runner_mock.py @ 3efa7659

History | View | Annotate | Download (4.7 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
import mock
22

    
23
from ganeti import objects
24
from ganeti import rpc
25

    
26

    
27
def CreateRpcRunnerMock():
28
  """Creates a new L{mock.MagicMock} tailored for L{rpc.RpcRunner}
29

30
  """
31
  ret = mock.MagicMock(spec=rpc.RpcRunner)
32
  return ret
33

    
34

    
35
class RpcResultsBuilder(object):
36
  """Helper class which assists in constructing L{rpc.RpcResult} objects.
37

38
  This class provides some convenience methods for constructing L{rpc.RpcResult}
39
  objects. It is possible to create single results with the C{Create*} methods
40
  or to create multi-node results by repeatedly calling the C{Add*} methods and
41
  then obtaining the final result with C{Build}.
42

43
  The C{node} parameter of all the methods can either be a L{objects.Node}
44
  object, a node UUID or a node name. You have to provide the cluster config
45
  in the constructor if you want to use node UUID's/names.
46

47
  A typical usage of this class is as follows::
48

49
    self.rpc.call_some_rpc.return_value = \
50
      RpcResultsBuilder(cfg=self.cfg) \
51
        .AddSuccessfulNode(node1,
52
                           {
53
                             "result_key": "result_data",
54
                             "another_key": "other_data",
55
                           }) \
56
        .AddErrorNode(node2) \
57
        .Build()
58

59
  """
60

    
61
  def __init__(self, cfg=None, use_node_names=False):
62
    """Constructor.
63

64
    @type cfg: L{ganeti.config.ConfigWriter}
65
    @param cfg: used to resolve nodes if not C{None}
66
    @type use_node_names: bool
67
    @param use_node_names: if set to C{True}, the node field in the RPC results
68
          will contain the node name instead of the node UUID.
69
    """
70
    self._cfg = cfg
71
    self._use_node_names = use_node_names
72
    self._results = []
73

    
74
  def _GetNode(self, node_id):
75
    if isinstance(node_id, objects.Node):
76
      return node_id
77

    
78
    node = None
79
    if self._cfg is not None:
80
      node = self._cfg.GetNodeInfo(node_id)
81
      if node is None:
82
        node = self._cfg.GetNodeInfoByName(node_id)
83

    
84
    assert node is not None, "Failed to find '%s' in configuration" % node_id
85
    return node
86

    
87
  def _GetNodeId(self, node_id):
88
    node = self._GetNode(node_id)
89
    if self._use_node_names:
90
      return node.name
91
    else:
92
      return node.uuid
93

    
94
  def CreateSuccessfulNodeResult(self, node, data={}):
95
    """@see L{RpcResultsBuilder}
96

97
    @param node: @see L{RpcResultsBuilder}.
98
    @type data: dict
99
    @param data: the data as returned by the RPC
100
    @rtype: L{rpc.RpcResult}
101
    """
102
    return rpc.RpcResult(data=(True, data), node=self._GetNodeId(node))
103

    
104
  def CreateFailedNodeResult(self, node):
105
    """@see L{RpcResultsBuilder}
106

107
    @param node: @see L{RpcResultsBuilder}.
108
    @rtype: L{rpc.RpcResult}
109
    """
110
    return rpc.RpcResult(failed=True, node=self._GetNodeId(node))
111

    
112
  def CreateOfflineNodeResult(self, node):
113
    """@see L{RpcResultsBuilder}
114

115
    @param node: @see L{RpcResultsBuilder}.
116
    @rtype: L{rpc.RpcResult}
117
    """
118
    return rpc.RpcResult(failed=True, node=self._GetNodeId(node))
119

    
120
  def CreateErrorNodeResult(self, node, error_msg=None):
121
    """@see L{RpcResultsBuilder}
122

123
    @param node: @see L{RpcResultsBuilder}.
124
    @type error_msg: string
125
    @param error_msg: the error message as returned by the RPC
126
    @rtype: L{rpc.RpcResult}
127
    """
128
    return rpc.RpcResult(data=(False, error_msg), node=self._GetNodeId(node))
129

    
130
  def AddSuccessfulNode(self, node, data={}):
131
    """@see L{CreateSuccessfulNode}"""
132
    self._results.append(self.CreateSuccessfulNodeResult(node, data))
133
    return self
134

    
135
  def AddFailedNode(self, node):
136
    """@see L{CreateFailedNode}"""
137
    self._results.append(self.CreateFailedNodeResult(node))
138
    return self
139

    
140
  def AddOfflineNode(self, node):
141
    """@see L{CreateOfflineNode}"""
142
    self._results.append(self.CreateOfflineNodeResult(node))
143

    
144
  def AddErrorNode(self, node, error_msg=None):
145
    """@see L{CreateErrorNode}"""
146
    self._results.append(self.CreateErrorNodeResult(node, error_msg=error_msg))
147

    
148
  def Build(self):
149
    """Creates a dictionary holding multi-node results
150

151
    @rtype: dict
152
    """
153
    return dict((result.node, result) for result in self._results)