Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.serializer_unittest.py @ 560ef132

History | View | Annotate | Download (7.4 kB)

1 501c95a2 Michael Hanselmann
#!/usr/bin/python
2 501c95a2 Michael Hanselmann
#
3 501c95a2 Michael Hanselmann
4 501c95a2 Michael Hanselmann
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 501c95a2 Michael Hanselmann
#
6 501c95a2 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 501c95a2 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 501c95a2 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 501c95a2 Michael Hanselmann
# (at your option) any later version.
10 501c95a2 Michael Hanselmann
#
11 501c95a2 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 501c95a2 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 501c95a2 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 501c95a2 Michael Hanselmann
# General Public License for more details.
15 501c95a2 Michael Hanselmann
#
16 501c95a2 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 501c95a2 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 501c95a2 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 fd7b69c0 Michael Hanselmann
# 02110-1301, USA.
20 501c95a2 Michael Hanselmann
21 501c95a2 Michael Hanselmann
22 501c95a2 Michael Hanselmann
"""Script for unittesting the serializer module"""
23 501c95a2 Michael Hanselmann
24 501c95a2 Michael Hanselmann
25 560ef132 Santi Raffa
import doctest
26 501c95a2 Michael Hanselmann
import unittest
27 501c95a2 Michael Hanselmann
28 f4a2f532 Guido Trotter
from ganeti import errors
29 5d630c22 Michael Hanselmann
from ganeti import ht
30 560ef132 Santi Raffa
from ganeti import objects
31 560ef132 Santi Raffa
from ganeti import serializer
32 501c95a2 Michael Hanselmann
33 d357f531 Michael Hanselmann
import testutils
34 501c95a2 Michael Hanselmann
35 501c95a2 Michael Hanselmann
36 d357f531 Michael Hanselmann
class TestSerializer(testutils.GanetiTestCase):
37 501c95a2 Michael Hanselmann
  """Serializer tests"""
38 501c95a2 Michael Hanselmann
39 501c95a2 Michael Hanselmann
  _TESTDATA = [
40 501c95a2 Michael Hanselmann
    "test",
41 501c95a2 Michael Hanselmann
    255,
42 501c95a2 Michael Hanselmann
    [1, 2, 3],
43 501c95a2 Michael Hanselmann
    (1, 2, 3),
44 560ef132 Santi Raffa
    {"1": 2,
45 560ef132 Santi Raffa
     "foo": "bar"},
46 d357f531 Michael Hanselmann
    ["abc", 1, 2, 3, 999,
47 d357f531 Michael Hanselmann
      {
48 d357f531 Michael Hanselmann
        "a1": ("Hello", "World"),
49 d357f531 Michael Hanselmann
        "a2": "This is only a test",
50 d357f531 Michael Hanselmann
        "a3": None,
51 560ef132 Santi Raffa
        "osparams:": serializer.PrivateDict({
52 560ef132 Santi Raffa
                      "foo": 5,
53 560ef132 Santi Raffa
                     })
54 560ef132 Santi Raffa
      }
55 501c95a2 Michael Hanselmann
    ]
56 560ef132 Santi Raffa
  ]
57 501c95a2 Michael Hanselmann
58 d357f531 Michael Hanselmann
  def _TestSerializer(self, dump_fn, load_fn):
59 560ef132 Santi Raffa
    _dump_fn = lambda data: dump_fn(
60 560ef132 Santi Raffa
      data,
61 560ef132 Santi Raffa
      private_encoder=serializer.EncodeWithPrivateFields
62 560ef132 Santi Raffa
    )
63 a182a3ed Michael Hanselmann
    for data in self._TESTDATA:
64 560ef132 Santi Raffa
      self.failUnless(_dump_fn(data).endswith("\n"))
65 560ef132 Santi Raffa
      self.assertEqualValues(load_fn(_dump_fn(data)), data)
66 501c95a2 Michael Hanselmann
67 501c95a2 Michael Hanselmann
  def testGeneric(self):
68 02141fb1 Michael Hanselmann
    self._TestSerializer(serializer.Dump, serializer.Load)
69 501c95a2 Michael Hanselmann
70 dd999b06 Michael Hanselmann
  def testSignedGeneric(self):
71 dd999b06 Michael Hanselmann
    self._TestSigned(serializer.DumpSigned, serializer.LoadSigned)
72 dd999b06 Michael Hanselmann
73 501c95a2 Michael Hanselmann
  def testJson(self):
74 02141fb1 Michael Hanselmann
    self._TestSerializer(serializer.DumpJson, serializer.LoadJson)
75 02141fb1 Michael Hanselmann
76 dd999b06 Michael Hanselmann
  def testSignedJson(self):
77 dd999b06 Michael Hanselmann
    self._TestSigned(serializer.DumpSignedJson, serializer.LoadSignedJson)
78 f4a2f532 Guido Trotter
79 dd999b06 Michael Hanselmann
  def _TestSigned(self, dump_fn, load_fn):
80 560ef132 Santi Raffa
    _dump_fn = lambda *args, **kwargs: dump_fn(
81 560ef132 Santi Raffa
      *args,
82 560ef132 Santi Raffa
      private_encoder=serializer.EncodeWithPrivateFields,
83 560ef132 Santi Raffa
      **kwargs
84 560ef132 Santi Raffa
    )
85 f4a2f532 Guido Trotter
    for data in self._TESTDATA:
86 560ef132 Santi Raffa
      self.assertEqualValues(load_fn(_dump_fn(data, "mykey"), "mykey"),
87 8c114acd Michael Hanselmann
                             (data, ""))
88 560ef132 Santi Raffa
      self.assertEqualValues(load_fn(_dump_fn(data, "myprivatekey",
89 560ef132 Santi Raffa
                                              salt="mysalt"),
90 dd999b06 Michael Hanselmann
                                     "myprivatekey"),
91 d357f531 Michael Hanselmann
                             (data, "mysalt"))
92 d357f531 Michael Hanselmann
93 dd999b06 Michael Hanselmann
      keydict = {
94 dd999b06 Michael Hanselmann
        "mykey_id": "myprivatekey",
95 dd999b06 Michael Hanselmann
        }
96 560ef132 Santi Raffa
      self.assertEqualValues(load_fn(_dump_fn(data, "myprivatekey",
97 560ef132 Santi Raffa
                                              salt="mysalt",
98 560ef132 Santi Raffa
                                              key_selector="mykey_id"),
99 dd999b06 Michael Hanselmann
                                     keydict.get),
100 72ca1dcb Balazs Lecz
                             (data, "mysalt"))
101 dd999b06 Michael Hanselmann
      self.assertRaises(errors.SignatureError, load_fn,
102 560ef132 Santi Raffa
                        _dump_fn(data, "myprivatekey",
103 560ef132 Santi Raffa
                                 salt="mysalt",
104 560ef132 Santi Raffa
                                 key_selector="mykey_id"),
105 dd999b06 Michael Hanselmann
                        {}.get)
106 dd999b06 Michael Hanselmann
107 dd999b06 Michael Hanselmann
    self.assertRaises(errors.SignatureError, load_fn,
108 560ef132 Santi Raffa
                      _dump_fn("test", "myprivatekey"),
109 f4a2f532 Guido Trotter
                      "myotherkey")
110 f4a2f532 Guido Trotter
111 dd999b06 Michael Hanselmann
    self.assertRaises(errors.SignatureError, load_fn,
112 dd999b06 Michael Hanselmann
                      serializer.DumpJson("This is a test"), "mykey")
113 dd999b06 Michael Hanselmann
    self.assertRaises(errors.SignatureError, load_fn,
114 dd999b06 Michael Hanselmann
                      serializer.DumpJson({}), "mykey")
115 dd999b06 Michael Hanselmann
116 dd999b06 Michael Hanselmann
    # Message missing salt and HMAC
117 dd999b06 Michael Hanselmann
    tdata = { "msg": "Foo", }
118 dd999b06 Michael Hanselmann
    self.assertRaises(errors.SignatureError, load_fn,
119 dd999b06 Michael Hanselmann
                      serializer.DumpJson(tdata), "mykey")
120 dd999b06 Michael Hanselmann
121 501c95a2 Michael Hanselmann
122 5d630c22 Michael Hanselmann
class TestLoadAndVerifyJson(unittest.TestCase):
123 5d630c22 Michael Hanselmann
  def testNoJson(self):
124 5d630c22 Michael Hanselmann
    self.assertRaises(errors.ParseError, serializer.LoadAndVerifyJson,
125 5d630c22 Michael Hanselmann
                      "", NotImplemented)
126 5d630c22 Michael Hanselmann
    self.assertRaises(errors.ParseError, serializer.LoadAndVerifyJson,
127 5d630c22 Michael Hanselmann
                      "}", NotImplemented)
128 5d630c22 Michael Hanselmann
129 5d630c22 Michael Hanselmann
  def testVerificationFails(self):
130 5d630c22 Michael Hanselmann
    self.assertRaises(errors.ParseError, serializer.LoadAndVerifyJson,
131 5d630c22 Michael Hanselmann
                      "{}", lambda _: False)
132 5d630c22 Michael Hanselmann
133 5d630c22 Michael Hanselmann
    verify_fn = ht.TListOf(ht.TNonEmptyString)
134 5d630c22 Michael Hanselmann
    try:
135 5d630c22 Michael Hanselmann
      serializer.LoadAndVerifyJson("{}", verify_fn)
136 5d630c22 Michael Hanselmann
    except errors.ParseError, err:
137 5d630c22 Michael Hanselmann
      self.assertTrue(str(err).endswith(str(verify_fn)))
138 5d630c22 Michael Hanselmann
    else:
139 5d630c22 Michael Hanselmann
      self.fail("Exception not raised")
140 5d630c22 Michael Hanselmann
141 5d630c22 Michael Hanselmann
  def testSuccess(self):
142 5d630c22 Michael Hanselmann
    self.assertEqual(serializer.LoadAndVerifyJson("{}", ht.TAny), {})
143 5d630c22 Michael Hanselmann
    self.assertEqual(serializer.LoadAndVerifyJson("\"Foo\"", ht.TAny), "Foo")
144 5d630c22 Michael Hanselmann
145 5d630c22 Michael Hanselmann
146 560ef132 Santi Raffa
class TestPrivate(unittest.TestCase):
147 560ef132 Santi Raffa
148 560ef132 Santi Raffa
  def testEquality(self):
149 560ef132 Santi Raffa
    pDict = serializer.PrivateDict()
150 560ef132 Santi Raffa
    pDict["bar"] = "egg"
151 560ef132 Santi Raffa
    nDict = {"bar": "egg"}
152 560ef132 Santi Raffa
    self.assertEqual(pDict, nDict, "PrivateDict-dict equality failure")
153 560ef132 Santi Raffa
154 560ef132 Santi Raffa
  def testPrivateDictUnprivate(self):
155 560ef132 Santi Raffa
    pDict = serializer.PrivateDict()
156 560ef132 Santi Raffa
    pDict["bar"] = "egg"
157 560ef132 Santi Raffa
    uDict = pDict.Unprivate()
158 560ef132 Santi Raffa
    nDict = {"bar": "egg"}
159 560ef132 Santi Raffa
    self.assertEquals(type(uDict), dict,
160 560ef132 Santi Raffa
                      "PrivateDict.Unprivate() did not return a dict")
161 560ef132 Santi Raffa
    self.assertEqual(pDict, uDict, "PrivateDict.Unprivate() equality failure")
162 560ef132 Santi Raffa
    self.assertEqual(nDict, uDict, "PrivateDict.Unprivate() failed to return")
163 560ef132 Santi Raffa
164 560ef132 Santi Raffa
  def testAttributeTransparency(self):
165 560ef132 Santi Raffa
    class Dummy(object):
166 560ef132 Santi Raffa
      pass
167 560ef132 Santi Raffa
168 560ef132 Santi Raffa
    dummy = Dummy()
169 560ef132 Santi Raffa
    dummy.bar = "egg"
170 560ef132 Santi Raffa
    pDummy = serializer.Private(dummy)
171 560ef132 Santi Raffa
    self.assertEqual(pDummy.bar, "egg", "Failed to access attribute of Private")
172 560ef132 Santi Raffa
173 560ef132 Santi Raffa
  def testCallTransparency(self):
174 560ef132 Santi Raffa
    foo = serializer.Private("egg")
175 560ef132 Santi Raffa
    self.assertEqual(foo.upper(), "EGG", "Failed to call Private instance")
176 560ef132 Santi Raffa
177 560ef132 Santi Raffa
  def testFillDict(self):
178 560ef132 Santi Raffa
    pDict = serializer.PrivateDict()
179 560ef132 Santi Raffa
    pDict["bar"] = "egg"
180 560ef132 Santi Raffa
    self.assertEqual(pDict, objects.FillDict({}, pDict))
181 560ef132 Santi Raffa
182 560ef132 Santi Raffa
  def testLeak(self):
183 560ef132 Santi Raffa
    pDict = serializer.PrivateDict()
184 560ef132 Santi Raffa
    pDict["bar"] = "egg"
185 560ef132 Santi Raffa
    self.assertNotIn("egg", str(pDict), "Value leaked in str(PrivateDict)")
186 560ef132 Santi Raffa
    self.assertNotIn("egg", repr(pDict), "Value leaked in repr(PrivateDict)")
187 560ef132 Santi Raffa
    self.assertNotIn("egg", "{0}".format(pDict),
188 560ef132 Santi Raffa
                     "Value leaked in PrivateDict.__format__")
189 560ef132 Santi Raffa
    self.assertNotIn("egg", serializer.Dump(pDict),
190 560ef132 Santi Raffa
                     "Value leaked in serializer.Dump(PrivateDict)")
191 560ef132 Santi Raffa
192 560ef132 Santi Raffa
  def testProperAccess(self):
193 560ef132 Santi Raffa
    pDict = serializer.PrivateDict()
194 560ef132 Santi Raffa
    pDict["bar"] = "egg"
195 560ef132 Santi Raffa
196 560ef132 Santi Raffa
    self.assertIs("egg", pDict["bar"].Get(),
197 560ef132 Santi Raffa
                  "Value not returned by Private.Get()")
198 560ef132 Santi Raffa
    self.assertIs("egg", pDict.GetPrivate("bar"),
199 560ef132 Santi Raffa
                  "Value not returned by Private.GetPrivate()")
200 560ef132 Santi Raffa
    self.assertIs("egg", pDict.Unprivate()["bar"],
201 560ef132 Santi Raffa
                  "Value not returned by PrivateDict.Unprivate()")
202 560ef132 Santi Raffa
    self.assertIn(
203 560ef132 Santi Raffa
      "egg",
204 560ef132 Santi Raffa
      serializer.Dump(pDict,
205 560ef132 Santi Raffa
                      private_encoder=serializer.EncodeWithPrivateFields)
206 560ef132 Santi Raffa
    )
207 560ef132 Santi Raffa
208 560ef132 Santi Raffa
  def testDictGet(self):
209 560ef132 Santi Raffa
    self.assertIs("tar", serializer.PrivateDict().GetPrivate("bar", "tar"),
210 560ef132 Santi Raffa
                  "Private.GetPrivate() did not handle the default case")
211 560ef132 Santi Raffa
212 560ef132 Santi Raffa
  def testZeronessPrivate(self):
213 560ef132 Santi Raffa
    self.assertTrue(serializer.Private("foo"),
214 560ef132 Santi Raffa
                    "Private of non-empty string is false")
215 560ef132 Santi Raffa
    self.assertFalse(serializer.Private(""), "Private empty string is true")
216 560ef132 Santi Raffa
217 560ef132 Santi Raffa
218 560ef132 Santi Raffa
class TestCheckDoctests(unittest.TestCase):
219 560ef132 Santi Raffa
220 560ef132 Santi Raffa
  def testCheckSerializer(self):
221 560ef132 Santi Raffa
    results = doctest.testmod(serializer)
222 560ef132 Santi Raffa
    self.assertEquals(results.failed, 0, "Doctest failures detected")
223 560ef132 Santi Raffa
224 2f96c43c Michael Hanselmann
if __name__ == "__main__":
225 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()