
We subclass the yaml.SafeDumper class to adjust its behavior with an override of the ignore_aliases method. It is possible to subclass the cyaml.CSafeDumper class as well. The "C" part is actually the Parser and Emitter, not the Dumper/Representer, so our override is still effective whether we use the C or Python versions. This can produce a significant performance increase when exchanging large amounts of data with Ansible. The C emitter is more aggressive about not using unecessary quotes, so the ansible dumper test assertions need to change. To add some extra assurance, that test is also updated to check that the round-trip load is as expected as well. Change-Id: I30fd82c0b9472120d010f3f4a65e17fb426b0f7e
119 lines
3.8 KiB
Python
119 lines
3.8 KiB
Python
# Copyright 2021 Acme Gating, LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from zuul.lib import yamlutil
|
|
from tests.base import BaseTestCase
|
|
|
|
import testtools
|
|
|
|
|
|
class TestYamlDumper(BaseTestCase):
|
|
def test_load_normal_data(self):
|
|
expected = {'foo': 'bar'}
|
|
data = 'foo: bar\n'
|
|
out = yamlutil.safe_load(data)
|
|
self.assertEqual(out, expected)
|
|
|
|
out = yamlutil.encrypted_load(data)
|
|
self.assertEqual(out, expected)
|
|
|
|
def test_load_encrypted_data(self):
|
|
expected = {'foo': yamlutil.EncryptedPKCS1_OAEP('YmFy')}
|
|
self.assertEqual(expected['foo'].ciphertext, b'bar')
|
|
data = "foo: !encrypted/pkcs1-oaep YmFy\n"
|
|
|
|
out = yamlutil.encrypted_load(data)
|
|
self.assertEqual(out, expected)
|
|
|
|
with testtools.ExpectedException(
|
|
yamlutil.yaml.constructor.ConstructorError):
|
|
out = yamlutil.safe_load(data)
|
|
|
|
def test_dump_normal_data(self):
|
|
data = {'foo': 'bar'}
|
|
expected = 'foo: bar\n'
|
|
out = yamlutil.safe_dump(data, default_flow_style=False)
|
|
self.assertEqual(out, expected)
|
|
|
|
out = yamlutil.encrypted_dump(data, default_flow_style=False)
|
|
self.assertEqual(out, expected)
|
|
|
|
def test_dump_encrypted_data(self):
|
|
data = {'foo': yamlutil.EncryptedPKCS1_OAEP('YmFy')}
|
|
self.assertEqual(data['foo'].ciphertext, b'bar')
|
|
expected = "foo: !encrypted/pkcs1-oaep YmFy\n"
|
|
|
|
out = yamlutil.encrypted_dump(data, default_flow_style=False)
|
|
self.assertEqual(out, expected)
|
|
|
|
with testtools.ExpectedException(
|
|
yamlutil.yaml.representer.RepresenterError):
|
|
out = yamlutil.safe_dump(data, default_flow_style=False)
|
|
|
|
def test_ansible_dumper(self):
|
|
data = {'foo': 'bar'}
|
|
data = yamlutil.mark_strings_unsafe(data)
|
|
expected = "foo: !unsafe bar\n"
|
|
yaml_out = yamlutil.ansible_unsafe_dump(data, default_flow_style=False)
|
|
# Assert the serialized string looks good
|
|
self.assertEqual(yaml_out, expected)
|
|
# Check the round trip
|
|
data_in = yamlutil.ansible_unsafe_load(yaml_out)
|
|
self.assertEqual(data, data_in)
|
|
|
|
data = {'foo': {'bar': 'baz'}, 'list': ['bar', 1, 3.0, True, None]}
|
|
data = yamlutil.mark_strings_unsafe(data)
|
|
expected = """\
|
|
foo:
|
|
bar: !unsafe baz
|
|
list:
|
|
- !unsafe bar
|
|
- 1
|
|
- 3.0
|
|
- true
|
|
- null
|
|
"""
|
|
yaml_out = yamlutil.ansible_unsafe_dump(data, default_flow_style=False)
|
|
# Assert the serialized string looks good
|
|
self.assertEqual(yaml_out, expected)
|
|
data_in = yamlutil.ansible_unsafe_load(yaml_out)
|
|
# Check the round trip
|
|
self.assertEqual(data, data_in)
|
|
|
|
def test_ansible_dumper_with_aliases(self):
|
|
foo = {'bar': 'baz'}
|
|
data = {'foo1': foo, 'foo2': foo}
|
|
expected = """\
|
|
foo1: &id001
|
|
bar: baz
|
|
foo2: *id001
|
|
"""
|
|
yaml_out = yamlutil.ansible_unsafe_dump(data, default_flow_style=False)
|
|
self.assertEqual(yaml_out, expected)
|
|
|
|
def test_ansible_dumper_ignore_aliases(self):
|
|
foo = {'bar': 'baz'}
|
|
data = {'foo1': foo, 'foo2': foo}
|
|
expected = """\
|
|
foo1:
|
|
bar: baz
|
|
foo2:
|
|
bar: baz
|
|
"""
|
|
yaml_out = yamlutil.ansible_unsafe_dump(
|
|
data,
|
|
ignore_aliases=True,
|
|
default_flow_style=False)
|
|
self.assertEqual(yaml_out, expected)
|