zuul/tests/unit/test_yamlutil.py
James E. Blair 1d07a097ee Use cyaml when reading/writing Ansible
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
2023-08-22 16:15:19 -07:00

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)