~ubuntu-cloud-archive/ubuntu/precise/cinder/trunk

« back to all changes in this revision

Viewing changes to cinder/tests/api/openstack/test_xmlutil.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-11-23 08:39:28 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20121123083928-xvzet603cjfj9p1t
Tags: 2013.1~g1-0ubuntu1
* New upstream release.
* debian/patches/avoid_setuptools_git_dependency.patch:
  Avoid git installation. (LP: #1075948) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2011 OpenStack LLC.
4
 
# All Rights Reserved.
5
 
#
6
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
7
 
#    not use this file except in compliance with the License. You may obtain
8
 
#    a copy of the License at
9
 
#
10
 
#         http://www.apache.org/licenses/LICENSE-2.0
11
 
#
12
 
#    Unless required by applicable law or agreed to in writing, software
13
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 
#    License for the specific language governing permissions and limitations
16
 
#    under the License.
17
 
 
18
 
from lxml import etree
19
 
 
20
 
from cinder import test
21
 
from cinder.api.openstack import xmlutil
22
 
 
23
 
 
24
 
class SelectorTest(test.TestCase):
25
 
    obj_for_test = {
26
 
        'test': {
27
 
            'name': 'test',
28
 
            'values': [1, 2, 3],
29
 
            'attrs': {
30
 
                'foo': 1,
31
 
                'bar': 2,
32
 
                'baz': 3,
33
 
                },
34
 
            },
35
 
        }
36
 
 
37
 
    def test_empty_selector(self):
38
 
        sel = xmlutil.Selector()
39
 
        self.assertEqual(len(sel.chain), 0)
40
 
        self.assertEqual(sel(self.obj_for_test), self.obj_for_test)
41
 
 
42
 
    def test_dict_selector(self):
43
 
        sel = xmlutil.Selector('test')
44
 
        self.assertEqual(len(sel.chain), 1)
45
 
        self.assertEqual(sel.chain[0], 'test')
46
 
        self.assertEqual(sel(self.obj_for_test),
47
 
                         self.obj_for_test['test'])
48
 
 
49
 
    def test_datum_selector(self):
50
 
        sel = xmlutil.Selector('test', 'name')
51
 
        self.assertEqual(len(sel.chain), 2)
52
 
        self.assertEqual(sel.chain[0], 'test')
53
 
        self.assertEqual(sel.chain[1], 'name')
54
 
        self.assertEqual(sel(self.obj_for_test), 'test')
55
 
 
56
 
    def test_list_selector(self):
57
 
        sel = xmlutil.Selector('test', 'values', 0)
58
 
        self.assertEqual(len(sel.chain), 3)
59
 
        self.assertEqual(sel.chain[0], 'test')
60
 
        self.assertEqual(sel.chain[1], 'values')
61
 
        self.assertEqual(sel.chain[2], 0)
62
 
        self.assertEqual(sel(self.obj_for_test), 1)
63
 
 
64
 
    def test_items_selector(self):
65
 
        sel = xmlutil.Selector('test', 'attrs', xmlutil.get_items)
66
 
        self.assertEqual(len(sel.chain), 3)
67
 
        self.assertEqual(sel.chain[2], xmlutil.get_items)
68
 
        for key, val in sel(self.obj_for_test):
69
 
            self.assertEqual(self.obj_for_test['test']['attrs'][key], val)
70
 
 
71
 
    def test_missing_key_selector(self):
72
 
        sel = xmlutil.Selector('test2', 'attrs')
73
 
        self.assertEqual(sel(self.obj_for_test), None)
74
 
        self.assertRaises(KeyError, sel, self.obj_for_test, True)
75
 
 
76
 
    def test_constant_selector(self):
77
 
        sel = xmlutil.ConstantSelector('Foobar')
78
 
        self.assertEqual(sel.value, 'Foobar')
79
 
        self.assertEqual(sel(self.obj_for_test), 'Foobar')
80
 
 
81
 
 
82
 
class TemplateElementTest(test.TestCase):
83
 
    def test_element_initial_attributes(self):
84
 
        # Create a template element with some attributes
85
 
        elem = xmlutil.TemplateElement('test', attrib=dict(a=1, b=2, c=3),
86
 
                                       c=4, d=5, e=6)
87
 
 
88
 
        # Verify all the attributes are as expected
89
 
        expected = dict(a=1, b=2, c=4, d=5, e=6)
90
 
        for k, v in expected.items():
91
 
            self.assertEqual(elem.attrib[k].chain[0], v)
92
 
 
93
 
    def test_element_get_attributes(self):
94
 
        expected = dict(a=1, b=2, c=3)
95
 
 
96
 
        # Create a template element with some attributes
97
 
        elem = xmlutil.TemplateElement('test', attrib=expected)
98
 
 
99
 
        # Verify that get() retrieves the attributes
100
 
        for k, v in expected.items():
101
 
            self.assertEqual(elem.get(k).chain[0], v)
102
 
 
103
 
    def test_element_set_attributes(self):
104
 
        attrs = dict(a=None, b='foo', c=xmlutil.Selector('foo', 'bar'))
105
 
 
106
 
        # Create a bare template element with no attributes
107
 
        elem = xmlutil.TemplateElement('test')
108
 
 
109
 
        # Set the attribute values
110
 
        for k, v in attrs.items():
111
 
            elem.set(k, v)
112
 
 
113
 
        # Now verify what got set
114
 
        self.assertEqual(len(elem.attrib['a'].chain), 1)
115
 
        self.assertEqual(elem.attrib['a'].chain[0], 'a')
116
 
        self.assertEqual(len(elem.attrib['b'].chain), 1)
117
 
        self.assertEqual(elem.attrib['b'].chain[0], 'foo')
118
 
        self.assertEqual(elem.attrib['c'], attrs['c'])
119
 
 
120
 
    def test_element_attribute_keys(self):
121
 
        attrs = dict(a=1, b=2, c=3, d=4)
122
 
        expected = set(attrs.keys())
123
 
 
124
 
        # Create a template element with some attributes
125
 
        elem = xmlutil.TemplateElement('test', attrib=attrs)
126
 
 
127
 
        # Now verify keys
128
 
        self.assertEqual(set(elem.keys()), expected)
129
 
 
130
 
    def test_element_attribute_items(self):
131
 
        expected = dict(a=xmlutil.Selector(1),
132
 
                        b=xmlutil.Selector(2),
133
 
                        c=xmlutil.Selector(3))
134
 
        keys = set(expected.keys())
135
 
 
136
 
        # Create a template element with some attributes
137
 
        elem = xmlutil.TemplateElement('test', attrib=expected)
138
 
 
139
 
        # Now verify items
140
 
        for k, v in elem.items():
141
 
            self.assertEqual(expected[k], v)
142
 
            keys.remove(k)
143
 
 
144
 
        # Did we visit all keys?
145
 
        self.assertEqual(len(keys), 0)
146
 
 
147
 
    def test_element_selector_none(self):
148
 
        # Create a template element with no selector
149
 
        elem = xmlutil.TemplateElement('test')
150
 
 
151
 
        self.assertEqual(len(elem.selector.chain), 0)
152
 
 
153
 
    def test_element_selector_string(self):
154
 
        # Create a template element with a string selector
155
 
        elem = xmlutil.TemplateElement('test', selector='test')
156
 
 
157
 
        self.assertEqual(len(elem.selector.chain), 1)
158
 
        self.assertEqual(elem.selector.chain[0], 'test')
159
 
 
160
 
    def test_element_selector(self):
161
 
        sel = xmlutil.Selector('a', 'b')
162
 
 
163
 
        # Create a template element with an explicit selector
164
 
        elem = xmlutil.TemplateElement('test', selector=sel)
165
 
 
166
 
        self.assertEqual(elem.selector, sel)
167
 
 
168
 
    def test_element_subselector_none(self):
169
 
        # Create a template element with no subselector
170
 
        elem = xmlutil.TemplateElement('test')
171
 
 
172
 
        self.assertEqual(elem.subselector, None)
173
 
 
174
 
    def test_element_subselector_string(self):
175
 
        # Create a template element with a string subselector
176
 
        elem = xmlutil.TemplateElement('test', subselector='test')
177
 
 
178
 
        self.assertEqual(len(elem.subselector.chain), 1)
179
 
        self.assertEqual(elem.subselector.chain[0], 'test')
180
 
 
181
 
    def test_element_subselector(self):
182
 
        sel = xmlutil.Selector('a', 'b')
183
 
 
184
 
        # Create a template element with an explicit subselector
185
 
        elem = xmlutil.TemplateElement('test', subselector=sel)
186
 
 
187
 
        self.assertEqual(elem.subselector, sel)
188
 
 
189
 
    def test_element_append_child(self):
190
 
        # Create an element
191
 
        elem = xmlutil.TemplateElement('test')
192
 
 
193
 
        # Make sure the element starts off empty
194
 
        self.assertEqual(len(elem), 0)
195
 
 
196
 
        # Create a child element
197
 
        child = xmlutil.TemplateElement('child')
198
 
 
199
 
        # Append the child to the parent
200
 
        elem.append(child)
201
 
 
202
 
        # Verify that the child was added
203
 
        self.assertEqual(len(elem), 1)
204
 
        self.assertEqual(elem[0], child)
205
 
        self.assertEqual('child' in elem, True)
206
 
        self.assertEqual(elem['child'], child)
207
 
 
208
 
        # Ensure that multiple children of the same name are rejected
209
 
        child2 = xmlutil.TemplateElement('child')
210
 
        self.assertRaises(KeyError, elem.append, child2)
211
 
 
212
 
    def test_element_extend_children(self):
213
 
        # Create an element
214
 
        elem = xmlutil.TemplateElement('test')
215
 
 
216
 
        # Make sure the element starts off empty
217
 
        self.assertEqual(len(elem), 0)
218
 
 
219
 
        # Create a few children
220
 
        children = [
221
 
            xmlutil.TemplateElement('child1'),
222
 
            xmlutil.TemplateElement('child2'),
223
 
            xmlutil.TemplateElement('child3'),
224
 
            ]
225
 
 
226
 
        # Extend the parent by those children
227
 
        elem.extend(children)
228
 
 
229
 
        # Verify that the children were added
230
 
        self.assertEqual(len(elem), 3)
231
 
        for idx in range(len(elem)):
232
 
            self.assertEqual(children[idx], elem[idx])
233
 
            self.assertEqual(children[idx].tag in elem, True)
234
 
            self.assertEqual(elem[children[idx].tag], children[idx])
235
 
 
236
 
        # Ensure that multiple children of the same name are rejected
237
 
        children2 = [
238
 
            xmlutil.TemplateElement('child4'),
239
 
            xmlutil.TemplateElement('child1'),
240
 
            ]
241
 
        self.assertRaises(KeyError, elem.extend, children2)
242
 
 
243
 
        # Also ensure that child4 was not added
244
 
        self.assertEqual(len(elem), 3)
245
 
        self.assertEqual(elem[-1].tag, 'child3')
246
 
 
247
 
    def test_element_insert_child(self):
248
 
        # Create an element
249
 
        elem = xmlutil.TemplateElement('test')
250
 
 
251
 
        # Make sure the element starts off empty
252
 
        self.assertEqual(len(elem), 0)
253
 
 
254
 
        # Create a few children
255
 
        children = [
256
 
            xmlutil.TemplateElement('child1'),
257
 
            xmlutil.TemplateElement('child2'),
258
 
            xmlutil.TemplateElement('child3'),
259
 
            ]
260
 
 
261
 
        # Extend the parent by those children
262
 
        elem.extend(children)
263
 
 
264
 
        # Create a child to insert
265
 
        child = xmlutil.TemplateElement('child4')
266
 
 
267
 
        # Insert it
268
 
        elem.insert(1, child)
269
 
 
270
 
        # Ensure the child was inserted in the right place
271
 
        self.assertEqual(len(elem), 4)
272
 
        children.insert(1, child)
273
 
        for idx in range(len(elem)):
274
 
            self.assertEqual(children[idx], elem[idx])
275
 
            self.assertEqual(children[idx].tag in elem, True)
276
 
            self.assertEqual(elem[children[idx].tag], children[idx])
277
 
 
278
 
        # Ensure that multiple children of the same name are rejected
279
 
        child2 = xmlutil.TemplateElement('child2')
280
 
        self.assertRaises(KeyError, elem.insert, 2, child2)
281
 
 
282
 
    def test_element_remove_child(self):
283
 
        # Create an element
284
 
        elem = xmlutil.TemplateElement('test')
285
 
 
286
 
        # Make sure the element starts off empty
287
 
        self.assertEqual(len(elem), 0)
288
 
 
289
 
        # Create a few children
290
 
        children = [
291
 
            xmlutil.TemplateElement('child1'),
292
 
            xmlutil.TemplateElement('child2'),
293
 
            xmlutil.TemplateElement('child3'),
294
 
            ]
295
 
 
296
 
        # Extend the parent by those children
297
 
        elem.extend(children)
298
 
 
299
 
        # Create a test child to remove
300
 
        child = xmlutil.TemplateElement('child2')
301
 
 
302
 
        # Try to remove it
303
 
        self.assertRaises(ValueError, elem.remove, child)
304
 
 
305
 
        # Ensure that no child was removed
306
 
        self.assertEqual(len(elem), 3)
307
 
 
308
 
        # Now remove a legitimate child
309
 
        elem.remove(children[1])
310
 
 
311
 
        # Ensure that the child was removed
312
 
        self.assertEqual(len(elem), 2)
313
 
        self.assertEqual(elem[0], children[0])
314
 
        self.assertEqual(elem[1], children[2])
315
 
        self.assertEqual('child2' in elem, False)
316
 
 
317
 
        # Ensure the child cannot be retrieved by name
318
 
        def get_key(elem, key):
319
 
            return elem[key]
320
 
        self.assertRaises(KeyError, get_key, elem, 'child2')
321
 
 
322
 
    def test_element_text(self):
323
 
        # Create an element
324
 
        elem = xmlutil.TemplateElement('test')
325
 
 
326
 
        # Ensure that it has no text
327
 
        self.assertEqual(elem.text, None)
328
 
 
329
 
        # Try setting it to a string and ensure it becomes a selector
330
 
        elem.text = 'test'
331
 
        self.assertEqual(hasattr(elem.text, 'chain'), True)
332
 
        self.assertEqual(len(elem.text.chain), 1)
333
 
        self.assertEqual(elem.text.chain[0], 'test')
334
 
 
335
 
        # Try resetting the text to None
336
 
        elem.text = None
337
 
        self.assertEqual(elem.text, None)
338
 
 
339
 
        # Now make up a selector and try setting the text to that
340
 
        sel = xmlutil.Selector()
341
 
        elem.text = sel
342
 
        self.assertEqual(elem.text, sel)
343
 
 
344
 
        # Finally, try deleting the text and see what happens
345
 
        del elem.text
346
 
        self.assertEqual(elem.text, None)
347
 
 
348
 
    def test_apply_attrs(self):
349
 
        # Create a template element
350
 
        attrs = dict(attr1=xmlutil.ConstantSelector(1),
351
 
                     attr2=xmlutil.ConstantSelector(2))
352
 
        tmpl_elem = xmlutil.TemplateElement('test', attrib=attrs)
353
 
 
354
 
        # Create an etree element
355
 
        elem = etree.Element('test')
356
 
 
357
 
        # Apply the template to the element
358
 
        tmpl_elem.apply(elem, None)
359
 
 
360
 
        # Now, verify the correct attributes were set
361
 
        for k, v in elem.items():
362
 
            self.assertEqual(str(attrs[k].value), v)
363
 
 
364
 
    def test_apply_text(self):
365
 
        # Create a template element
366
 
        tmpl_elem = xmlutil.TemplateElement('test')
367
 
        tmpl_elem.text = xmlutil.ConstantSelector(1)
368
 
 
369
 
        # Create an etree element
370
 
        elem = etree.Element('test')
371
 
 
372
 
        # Apply the template to the element
373
 
        tmpl_elem.apply(elem, None)
374
 
 
375
 
        # Now, verify the text was set
376
 
        self.assertEqual(str(tmpl_elem.text.value), elem.text)
377
 
 
378
 
    def test__render(self):
379
 
        attrs = dict(attr1=xmlutil.ConstantSelector(1),
380
 
                     attr2=xmlutil.ConstantSelector(2),
381
 
                     attr3=xmlutil.ConstantSelector(3))
382
 
 
383
 
        # Create a master template element
384
 
        master_elem = xmlutil.TemplateElement('test', attr1=attrs['attr1'])
385
 
 
386
 
        # Create a couple of slave template element
387
 
        slave_elems = [
388
 
            xmlutil.TemplateElement('test', attr2=attrs['attr2']),
389
 
            xmlutil.TemplateElement('test', attr3=attrs['attr3']),
390
 
            ]
391
 
 
392
 
        # Try the render
393
 
        elem = master_elem._render(None, None, slave_elems, None)
394
 
 
395
 
        # Verify the particulars of the render
396
 
        self.assertEqual(elem.tag, 'test')
397
 
        self.assertEqual(len(elem.nsmap), 0)
398
 
        for k, v in elem.items():
399
 
            self.assertEqual(str(attrs[k].value), v)
400
 
 
401
 
        # Create a parent for the element to be rendered
402
 
        parent = etree.Element('parent')
403
 
 
404
 
        # Try the render again...
405
 
        elem = master_elem._render(parent, None, slave_elems, dict(a='foo'))
406
 
 
407
 
        # Verify the particulars of the render
408
 
        self.assertEqual(len(parent), 1)
409
 
        self.assertEqual(parent[0], elem)
410
 
        self.assertEqual(len(elem.nsmap), 1)
411
 
        self.assertEqual(elem.nsmap['a'], 'foo')
412
 
 
413
 
    def test_render(self):
414
 
        # Create a template element
415
 
        tmpl_elem = xmlutil.TemplateElement('test')
416
 
        tmpl_elem.text = xmlutil.Selector()
417
 
 
418
 
        # Create the object we're going to render
419
 
        obj = ['elem1', 'elem2', 'elem3', 'elem4']
420
 
 
421
 
        # Try a render with no object
422
 
        elems = tmpl_elem.render(None, None)
423
 
        self.assertEqual(len(elems), 0)
424
 
 
425
 
        # Try a render with one object
426
 
        elems = tmpl_elem.render(None, 'foo')
427
 
        self.assertEqual(len(elems), 1)
428
 
        self.assertEqual(elems[0][0].text, 'foo')
429
 
        self.assertEqual(elems[0][1], 'foo')
430
 
 
431
 
        # Now, try rendering an object with multiple entries
432
 
        parent = etree.Element('parent')
433
 
        elems = tmpl_elem.render(parent, obj)
434
 
        self.assertEqual(len(elems), 4)
435
 
 
436
 
        # Check the results
437
 
        for idx in range(len(obj)):
438
 
            self.assertEqual(elems[idx][0].text, obj[idx])
439
 
            self.assertEqual(elems[idx][1], obj[idx])
440
 
 
441
 
    def test_subelement(self):
442
 
        # Try the SubTemplateElement constructor
443
 
        parent = xmlutil.SubTemplateElement(None, 'parent')
444
 
        self.assertEqual(parent.tag, 'parent')
445
 
        self.assertEqual(len(parent), 0)
446
 
 
447
 
        # Now try it with a parent element
448
 
        child = xmlutil.SubTemplateElement(parent, 'child')
449
 
        self.assertEqual(child.tag, 'child')
450
 
        self.assertEqual(len(parent), 1)
451
 
        self.assertEqual(parent[0], child)
452
 
 
453
 
    def test_wrap(self):
454
 
        # These are strange methods, but they make things easier
455
 
        elem = xmlutil.TemplateElement('test')
456
 
        self.assertEqual(elem.unwrap(), elem)
457
 
        self.assertEqual(elem.wrap().root, elem)
458
 
 
459
 
    def test_dyntag(self):
460
 
        obj = ['a', 'b', 'c']
461
 
 
462
 
        # Create a template element with a dynamic tag
463
 
        tmpl_elem = xmlutil.TemplateElement(xmlutil.Selector())
464
 
 
465
 
        # Try the render
466
 
        parent = etree.Element('parent')
467
 
        elems = tmpl_elem.render(parent, obj)
468
 
 
469
 
        # Verify the particulars of the render
470
 
        self.assertEqual(len(elems), len(obj))
471
 
        for idx in range(len(obj)):
472
 
            self.assertEqual(elems[idx][0].tag, obj[idx])
473
 
 
474
 
 
475
 
class TemplateTest(test.TestCase):
476
 
    def test_wrap(self):
477
 
        # These are strange methods, but they make things easier
478
 
        elem = xmlutil.TemplateElement('test')
479
 
        tmpl = xmlutil.Template(elem)
480
 
        self.assertEqual(tmpl.unwrap(), elem)
481
 
        self.assertEqual(tmpl.wrap(), tmpl)
482
 
 
483
 
    def test__siblings(self):
484
 
        # Set up a basic template
485
 
        elem = xmlutil.TemplateElement('test')
486
 
        tmpl = xmlutil.Template(elem)
487
 
 
488
 
        # Check that we get the right siblings
489
 
        siblings = tmpl._siblings()
490
 
        self.assertEqual(len(siblings), 1)
491
 
        self.assertEqual(siblings[0], elem)
492
 
 
493
 
    def test__nsmap(self):
494
 
        # Set up a basic template
495
 
        elem = xmlutil.TemplateElement('test')
496
 
        tmpl = xmlutil.Template(elem, nsmap=dict(a="foo"))
497
 
 
498
 
        # Check out that we get the right namespace dictionary
499
 
        nsmap = tmpl._nsmap()
500
 
        self.assertNotEqual(id(nsmap), id(tmpl.nsmap))
501
 
        self.assertEqual(len(nsmap), 1)
502
 
        self.assertEqual(nsmap['a'], 'foo')
503
 
 
504
 
    def test_master_attach(self):
505
 
        # Set up a master template
506
 
        elem = xmlutil.TemplateElement('test')
507
 
        tmpl = xmlutil.MasterTemplate(elem, 1)
508
 
 
509
 
        # Make sure it has a root but no slaves
510
 
        self.assertEqual(tmpl.root, elem)
511
 
        self.assertEqual(len(tmpl.slaves), 0)
512
 
 
513
 
        # Try to attach an invalid slave
514
 
        bad_elem = xmlutil.TemplateElement('test2')
515
 
        self.assertRaises(ValueError, tmpl.attach, bad_elem)
516
 
        self.assertEqual(len(tmpl.slaves), 0)
517
 
 
518
 
        # Try to attach an invalid and a valid slave
519
 
        good_elem = xmlutil.TemplateElement('test')
520
 
        self.assertRaises(ValueError, tmpl.attach, good_elem, bad_elem)
521
 
        self.assertEqual(len(tmpl.slaves), 0)
522
 
 
523
 
        # Try to attach an inapplicable template
524
 
        class InapplicableTemplate(xmlutil.Template):
525
 
            def apply(self, master):
526
 
                return False
527
 
        inapp_tmpl = InapplicableTemplate(good_elem)
528
 
        tmpl.attach(inapp_tmpl)
529
 
        self.assertEqual(len(tmpl.slaves), 0)
530
 
 
531
 
        # Now try attaching an applicable template
532
 
        tmpl.attach(good_elem)
533
 
        self.assertEqual(len(tmpl.slaves), 1)
534
 
        self.assertEqual(tmpl.slaves[0].root, good_elem)
535
 
 
536
 
    def test_master_copy(self):
537
 
        # Construct a master template
538
 
        elem = xmlutil.TemplateElement('test')
539
 
        tmpl = xmlutil.MasterTemplate(elem, 1, nsmap=dict(a='foo'))
540
 
 
541
 
        # Give it a slave
542
 
        slave = xmlutil.TemplateElement('test')
543
 
        tmpl.attach(slave)
544
 
 
545
 
        # Construct a copy
546
 
        copy = tmpl.copy()
547
 
 
548
 
        # Check to see if we actually managed a copy
549
 
        self.assertNotEqual(tmpl, copy)
550
 
        self.assertEqual(tmpl.root, copy.root)
551
 
        self.assertEqual(tmpl.version, copy.version)
552
 
        self.assertEqual(id(tmpl.nsmap), id(copy.nsmap))
553
 
        self.assertNotEqual(id(tmpl.slaves), id(copy.slaves))
554
 
        self.assertEqual(len(tmpl.slaves), len(copy.slaves))
555
 
        self.assertEqual(tmpl.slaves[0], copy.slaves[0])
556
 
 
557
 
    def test_slave_apply(self):
558
 
        # Construct a master template
559
 
        elem = xmlutil.TemplateElement('test')
560
 
        master = xmlutil.MasterTemplate(elem, 3)
561
 
 
562
 
        # Construct a slave template with applicable minimum version
563
 
        slave = xmlutil.SlaveTemplate(elem, 2)
564
 
        self.assertEqual(slave.apply(master), True)
565
 
 
566
 
        # Construct a slave template with equal minimum version
567
 
        slave = xmlutil.SlaveTemplate(elem, 3)
568
 
        self.assertEqual(slave.apply(master), True)
569
 
 
570
 
        # Construct a slave template with inapplicable minimum version
571
 
        slave = xmlutil.SlaveTemplate(elem, 4)
572
 
        self.assertEqual(slave.apply(master), False)
573
 
 
574
 
        # Construct a slave template with applicable version range
575
 
        slave = xmlutil.SlaveTemplate(elem, 2, 4)
576
 
        self.assertEqual(slave.apply(master), True)
577
 
 
578
 
        # Construct a slave template with low version range
579
 
        slave = xmlutil.SlaveTemplate(elem, 1, 2)
580
 
        self.assertEqual(slave.apply(master), False)
581
 
 
582
 
        # Construct a slave template with high version range
583
 
        slave = xmlutil.SlaveTemplate(elem, 4, 5)
584
 
        self.assertEqual(slave.apply(master), False)
585
 
 
586
 
        # Construct a slave template with matching version range
587
 
        slave = xmlutil.SlaveTemplate(elem, 3, 3)
588
 
        self.assertEqual(slave.apply(master), True)
589
 
 
590
 
    def test__serialize(self):
591
 
        # Our test object to serialize
592
 
        obj = {
593
 
            'test': {
594
 
                'name': 'foobar',
595
 
                'values': [1, 2, 3, 4],
596
 
                'attrs': {
597
 
                    'a': 1,
598
 
                    'b': 2,
599
 
                    'c': 3,
600
 
                    'd': 4,
601
 
                    },
602
 
                'image': {
603
 
                    'name': 'image_foobar',
604
 
                    'id': 42,
605
 
                    },
606
 
                },
607
 
            }
608
 
 
609
 
        # Set up our master template
610
 
        root = xmlutil.TemplateElement('test', selector='test',
611
 
                                       name='name')
612
 
        value = xmlutil.SubTemplateElement(root, 'value', selector='values')
613
 
        value.text = xmlutil.Selector()
614
 
        attrs = xmlutil.SubTemplateElement(root, 'attrs', selector='attrs')
615
 
        xmlutil.SubTemplateElement(attrs, 'attr', selector=xmlutil.get_items,
616
 
                                   key=0, value=1)
617
 
        master = xmlutil.MasterTemplate(root, 1, nsmap=dict(f='foo'))
618
 
 
619
 
        # Set up our slave template
620
 
        root_slave = xmlutil.TemplateElement('test', selector='test')
621
 
        image = xmlutil.SubTemplateElement(root_slave, 'image',
622
 
                                           selector='image', id='id')
623
 
        image.text = xmlutil.Selector('name')
624
 
        slave = xmlutil.SlaveTemplate(root_slave, 1, nsmap=dict(b='bar'))
625
 
 
626
 
        # Attach the slave to the master...
627
 
        master.attach(slave)
628
 
 
629
 
        # Try serializing our object
630
 
        siblings = master._siblings()
631
 
        nsmap = master._nsmap()
632
 
        result = master._serialize(None, obj, siblings, nsmap)
633
 
 
634
 
        # Now we get to manually walk the element tree...
635
 
        self.assertEqual(result.tag, 'test')
636
 
        self.assertEqual(len(result.nsmap), 2)
637
 
        self.assertEqual(result.nsmap['f'], 'foo')
638
 
        self.assertEqual(result.nsmap['b'], 'bar')
639
 
        self.assertEqual(result.get('name'), obj['test']['name'])
640
 
        for idx, val in enumerate(obj['test']['values']):
641
 
            self.assertEqual(result[idx].tag, 'value')
642
 
            self.assertEqual(result[idx].text, str(val))
643
 
        idx += 1
644
 
        self.assertEqual(result[idx].tag, 'attrs')
645
 
        for attr in result[idx]:
646
 
            self.assertEqual(attr.tag, 'attr')
647
 
            self.assertEqual(attr.get('value'),
648
 
                             str(obj['test']['attrs'][attr.get('key')]))
649
 
        idx += 1
650
 
        self.assertEqual(result[idx].tag, 'image')
651
 
        self.assertEqual(result[idx].get('id'),
652
 
                         str(obj['test']['image']['id']))
653
 
        self.assertEqual(result[idx].text, obj['test']['image']['name'])
654
 
 
655
 
 
656
 
class MasterTemplateBuilder(xmlutil.TemplateBuilder):
657
 
    def construct(self):
658
 
        elem = xmlutil.TemplateElement('test')
659
 
        return xmlutil.MasterTemplate(elem, 1)
660
 
 
661
 
 
662
 
class SlaveTemplateBuilder(xmlutil.TemplateBuilder):
663
 
    def construct(self):
664
 
        elem = xmlutil.TemplateElement('test')
665
 
        return xmlutil.SlaveTemplate(elem, 1)
666
 
 
667
 
 
668
 
class TemplateBuilderTest(test.TestCase):
669
 
    def test_master_template_builder(self):
670
 
        # Make sure the template hasn't been built yet
671
 
        self.assertEqual(MasterTemplateBuilder._tmpl, None)
672
 
 
673
 
        # Now, construct the template
674
 
        tmpl1 = MasterTemplateBuilder()
675
 
 
676
 
        # Make sure that there is a template cached...
677
 
        self.assertNotEqual(MasterTemplateBuilder._tmpl, None)
678
 
 
679
 
        # Make sure it wasn't what was returned...
680
 
        self.assertNotEqual(MasterTemplateBuilder._tmpl, tmpl1)
681
 
 
682
 
        # Make sure it doesn't get rebuilt
683
 
        cached = MasterTemplateBuilder._tmpl
684
 
        tmpl2 = MasterTemplateBuilder()
685
 
        self.assertEqual(MasterTemplateBuilder._tmpl, cached)
686
 
 
687
 
        # Make sure we're always getting fresh copies
688
 
        self.assertNotEqual(tmpl1, tmpl2)
689
 
 
690
 
        # Make sure we can override the copying behavior
691
 
        tmpl3 = MasterTemplateBuilder(False)
692
 
        self.assertEqual(MasterTemplateBuilder._tmpl, tmpl3)
693
 
 
694
 
    def test_slave_template_builder(self):
695
 
        # Make sure the template hasn't been built yet
696
 
        self.assertEqual(SlaveTemplateBuilder._tmpl, None)
697
 
 
698
 
        # Now, construct the template
699
 
        tmpl1 = SlaveTemplateBuilder()
700
 
 
701
 
        # Make sure there is a template cached...
702
 
        self.assertNotEqual(SlaveTemplateBuilder._tmpl, None)
703
 
 
704
 
        # Make sure it was what was returned...
705
 
        self.assertEqual(SlaveTemplateBuilder._tmpl, tmpl1)
706
 
 
707
 
        # Make sure it doesn't get rebuilt
708
 
        tmpl2 = SlaveTemplateBuilder()
709
 
        self.assertEqual(SlaveTemplateBuilder._tmpl, tmpl1)
710
 
 
711
 
        # Make sure we're always getting the cached copy
712
 
        self.assertEqual(tmpl1, tmpl2)
713
 
 
714
 
 
715
 
class MiscellaneousXMLUtilTests(test.TestCase):
716
 
    def test_make_flat_dict(self):
717
 
        expected_xml = ("<?xml version='1.0' encoding='UTF-8'?>\n"
718
 
                        '<wrapper><a>foo</a><b>bar</b></wrapper>')
719
 
        root = xmlutil.make_flat_dict('wrapper')
720
 
        tmpl = xmlutil.MasterTemplate(root, 1)
721
 
        result = tmpl.serialize(dict(wrapper=dict(a='foo', b='bar')))
722
 
        self.assertEqual(result, expected_xml)