Revision a85f23fa

b/Makefile.am
252 252
	lib/rapi/client.py \
253 253
	lib/rapi/client_utils.py \
254 254
	lib/rapi/connector.py \
255
	lib/rapi/rlib2.py
255
	lib/rapi/rlib2.py \
256
	lib/rapi/testutils.py
256 257

  
257 258
http_PYTHON = \
258 259
	lib/http/__init__.py \
......
750 751
	test/ganeti.rapi.client_unittest.py \
751 752
	test/ganeti.rapi.resources_unittest.py \
752 753
	test/ganeti.rapi.rlib2_unittest.py \
754
	test/ganeti.rapi.testutils_unittest.py \
753 755
	test/ganeti.rpc_unittest.py \
754 756
	test/ganeti.runtime_unittest.py \
755 757
	test/ganeti.serializer_unittest.py \
b/lib/rapi/testutils.py
1
#
2
#
3

  
4
# Copyright (C) 2012 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
"""Remote API test utilities.
23

  
24
"""
25

  
26
import logging
27

  
28
from ganeti import errors
29
from ganeti import opcodes
30

  
31

  
32
class VerificationError(Exception):
33
  """Dedicated error class for test utilities.
34

  
35
  This class is used to hide all of Ganeti's internal exception, so that
36
  external users of these utilities don't have to integrate Ganeti's exception
37
  hierarchy.
38

  
39
  """
40

  
41

  
42
def _GetOpById(op_id):
43
  """Tries to get an opcode class based on its C{OP_ID}.
44

  
45
  """
46
  try:
47
    return opcodes.OP_MAPPING[op_id]
48
  except KeyError:
49
    raise VerificationError("Unknown opcode ID '%s'" % op_id)
50

  
51

  
52
def _HideInternalErrors(fn):
53
  """Hides Ganeti-internal exceptions, see L{VerificationError}.
54

  
55
  """
56
  def wrapper(*args, **kwargs):
57
    try:
58
      return fn(*args, **kwargs)
59
    except errors.GenericError, err:
60
      raise VerificationError("Unhandled Ganeti error: %s" % err)
61

  
62
  return wrapper
63

  
64

  
65
@_HideInternalErrors
66
def VerifyOpInput(op_id, data):
67
  """Verifies opcode parameters according to their definition.
68

  
69
  @type op_id: string
70
  @param op_id: Opcode ID (C{OP_ID} attribute), e.g. C{OP_CLUSTER_VERIFY}
71
  @type data: dict
72
  @param data: Opcode parameter values
73
  @raise VerificationError: Parameter verification failed
74

  
75
  """
76
  op_cls = _GetOpById(op_id)
77

  
78
  try:
79
    op = op_cls(**data) # pylint: disable=W0142
80
  except TypeError, err:
81
    raise VerificationError("Unable to create opcode instance: %s" % err)
82

  
83
  try:
84
    op.Validate(False)
85
  except errors.OpPrereqError, err:
86
    raise VerificationError("Parameter validation for opcode '%s' failed: %s" %
87
                            (op_id, err))
88

  
89

  
90
@_HideInternalErrors
91
def VerifyOpResult(op_id, result):
92
  """Verifies opcode results used in tests (e.g. in a mock).
93

  
94
  @type op_id: string
95
  @param op_id: Opcode ID (C{OP_ID} attribute), e.g. C{OP_CLUSTER_VERIFY}
96
  @param result: Mocked opcode result
97
  @raise VerificationError: Return value verification failed
98

  
99
  """
100
  resultcheck_fn = _GetOpById(op_id).OP_RESULT
101

  
102
  if not resultcheck_fn:
103
    logging.warning("Opcode '%s' has no result type definition", op_id)
104
  elif not resultcheck_fn(result):
105
    raise VerificationError("Given result does not match result description"
106
                            " for opcode '%s': %s" % (op_id, resultcheck_fn))
b/test/ganeti.rapi.testutils_unittest.py
1
#!/usr/bin/python
2
#
3

  
4
# Copyright (C) 2012 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
"""Script for testing ganeti.rapi.testutils"""
23

  
24
import unittest
25

  
26
from ganeti import compat
27
from ganeti import constants
28
from ganeti import errors
29
from ganeti import opcodes
30
from ganeti import rapi
31

  
32
import ganeti.rapi.testutils
33

  
34
import testutils
35

  
36

  
37
class TestHideInternalErrors(unittest.TestCase):
38
  def test(self):
39
    def inner():
40
      raise errors.GenericError("error")
41

  
42
    fn = rapi.testutils._HideInternalErrors(inner)
43

  
44
    self.assertRaises(rapi.testutils.VerificationError, fn)
45

  
46

  
47
class TestVerifyOpInput(unittest.TestCase):
48
  def testUnknownOpId(self):
49
    voi = rapi.testutils.VerifyOpInput
50

  
51
    self.assertRaises(rapi.testutils.VerificationError, voi, "UNK_OP_ID", None)
52

  
53
  def testUnknownParameter(self):
54
    voi = rapi.testutils.VerifyOpInput
55

  
56
    self.assertRaises(rapi.testutils.VerificationError, voi,
57
      opcodes.OpClusterRename.OP_ID, {
58
      "unk": "unk",
59
      })
60

  
61
  def testWrongParameterValue(self):
62
    voi = rapi.testutils.VerifyOpInput
63
    self.assertRaises(rapi.testutils.VerificationError, voi,
64
      opcodes.OpClusterRename.OP_ID, {
65
      "name": object(),
66
      })
67

  
68
  def testSuccess(self):
69
    voi = rapi.testutils.VerifyOpInput
70
    voi(opcodes.OpClusterRename.OP_ID, {
71
      "name": "new-name.example.com",
72
      })
73

  
74

  
75
class TestVerifyOpResult(unittest.TestCase):
76
  def testSuccess(self):
77
    vor = rapi.testutils.VerifyOpResult
78

  
79
    vor(opcodes.OpClusterVerify.OP_ID, {
80
      constants.JOB_IDS_KEY: [
81
        (False, "error message"),
82
        ],
83
      })
84

  
85
  def testWrongResult(self):
86
    vor = rapi.testutils.VerifyOpResult
87

  
88
    self.assertRaises(rapi.testutils.VerificationError, vor,
89
      opcodes.OpClusterVerify.OP_ID, [])
90

  
91
  def testNoResultCheck(self):
92
    vor = rapi.testutils.VerifyOpResult
93

  
94
    assert opcodes.OpTestDummy.OP_RESULT is None
95

  
96
    vor(opcodes.OpTestDummy.OP_ID, None)
97

  
98

  
99
if __name__ == "__main__":
100
  testutils.GanetiTestProgram()

Also available in: Unified diff