def test_serialize_yaml(self): data = {"foo": "bar"} serialized = yaml.serialize(data) assert serialized == '{foo: bar}', serialized deserialized = yaml.deserialize(serialized) assert deserialized == data, deserialized
def test_compare_sls_vs_yaml_with_jinja(self): tpl = '{{ data }}' env = jinja2.Environment() src = '{foo: 1, bar: 2, baz: {qux: true}}' sls_src = env.from_string(tpl).render(data=sls.deserialize(src)) yml_src = env.from_string(tpl).render(data=yaml.deserialize(src)) sls_data = sls.deserialize(sls_src) yml_data = yaml.deserialize(yml_src) # ensure that sls & yaml have the same base assert isinstance(sls_data, dict) assert isinstance(yml_data, dict) assert sls_data == yml_data # ensure that sls is ordered, while yaml not assert isinstance(sls_data, OrderedDict) assert not isinstance(yml_data, OrderedDict) # prove that yaml does not handle well with OrderedDict # while sls is jinja friendly. obj = OrderedDict([ ('foo', 1), ('bar', 2), ('baz', {'qux': True}) ]) sls_obj = sls.deserialize(sls.serialize(obj)) try: yml_obj = yaml.deserialize(yaml.serialize(obj)) except SerializationError: # BLAAM! yaml was unable to serialize OrderedDict, # but it's not the purpose of the current test. yml_obj = obj.copy() sls_src = env.from_string(tpl).render(data=sls_obj) yml_src = env.from_string(tpl).render(data=yml_obj) final_obj = yaml.deserialize(sls_src) assert obj == final_obj # BLAAM! yml_src is not valid ! final_obj = yaml.deserialize(yml_src) assert obj != final_obj
def test_serialize_yaml(self): data = { "foo": "bar" } serialized = yaml.serialize(data) assert serialized == '{foo: bar}', serialized deserialized = yaml.deserialize(serialized) assert deserialized == data, deserialized
def test_compare_sls_vs_yaml_with_jinja(self): tpl = '{{ data }}' env = jinja2.Environment() src = '{foo: 1, bar: 2, baz: {qux: true}}' sls_src = env.from_string(tpl).render(data=yamlex.deserialize(src)) yml_src = env.from_string(tpl).render(data=yaml.deserialize(src)) sls_data = yamlex.deserialize(sls_src) yml_data = yaml.deserialize(yml_src) # ensure that sls & yaml have the same base assert isinstance(sls_data, dict) assert isinstance(yml_data, dict) assert sls_data == yml_data # ensure that sls is ordered, while yaml not assert isinstance(sls_data, OrderedDict) assert not isinstance(yml_data, OrderedDict) # prove that yaml does not handle well with OrderedDict # while sls is jinja friendly. obj = OrderedDict([('foo', 1), ('bar', 2), ('baz', {'qux': True})]) sls_obj = yamlex.deserialize(yamlex.serialize(obj)) try: yml_obj = yaml.deserialize(yaml.serialize(obj)) except SerializationError: # BLAAM! yaml was unable to serialize OrderedDict, # but it's not the purpose of the current test. yml_obj = obj.copy() sls_src = env.from_string(tpl).render(data=sls_obj) yml_src = env.from_string(tpl).render(data=yml_obj) final_obj = yaml.deserialize(sls_src) assert obj == final_obj # BLAAM! yml_src is not valid ! final_obj = yaml.deserialize(yml_src) assert obj != final_obj
def test_compare_sls_vs_yaml(self): src = '{foo: 1, bar: 2, baz: {qux: true}}' sls_data = yamlex.deserialize(src) yml_data = yaml.deserialize(src) # ensure that sls & yaml have the same base assert isinstance(sls_data, dict) assert isinstance(yml_data, dict) assert sls_data == yml_data # ensure that sls is ordered, while yaml not assert isinstance(sls_data, OrderedDict) assert not isinstance(yml_data, OrderedDict)
def test_compare_sls_vs_yaml(self): src = '{foo: 1, bar: 2, baz: {qux: true}}' sls_data = sls.deserialize(src) yml_data = yaml.deserialize(src) # ensure that sls & yaml have the same base assert isinstance(sls_data, dict) assert isinstance(yml_data, dict) assert sls_data == yml_data # ensure that sls is ordered, while yaml not assert isinstance(sls_data, OrderedDict) assert not isinstance(yml_data, OrderedDict)
def deserialize_salt_file(self, template): return yaml_serializer.deserialize(self.get_salt_file(template))
def deserialize_yamlscript_file(template): template.seek(0) return yaml_serializer.deserialize(template.read(), **{'Loader': YamlScriptSafeLoader})
def test(salt_data, test_data, sls=''): ''' Runs a test to confirm state values provided in test file matched the generated salt_data values exactly as well as confirming the id's of the yaml represented states. :param OrderedDict salt_data: pyobjects generated state data :param YSOrderedDict test_data: De-serialized test data :return: number of errors in test1 and test2 :rtype: int, int The best way to run tests is to call the state you are running directly like: `salt-call --local --out=yaml state.show_sls users` test_data can be included in the state file and defined as a list like: .. code-block:: yaml $test_file: - salt://users/tests.mel - salt://users/tests.bobby And the test_data file should look something like this: .. code-block:: yaml local: mel_shadow_group: group: - addusers: null - delusers: null - gid: null - members: null - name: shadow - system: false - present mel_sudo_group: ... The test runs two ways, first confirming all expected salt_data is with test_data, then the other way around testing if there are extra values within the salt_data that are not in the test_data. ''' # Ignore these keys since they may differ on each run ignore = ['order', '__sls__', '__env__'] # Compile salt_data into a valid yamlscript structure salt_data = compile_state_data(salt_data) # Deserialize test state file if isinstance(test_data, str): test_data = yaml_serializer.deserialize(test_data) # Compile test_data into a valid yamlscript structure and allow test_data to # contain the parent 'local' key as shown 'state.show_sls users' or not test_data = compile_state_data(test_data.get('local', test_data)) def compare(test_data, data, text=None, mismatch='mismatch', key_error='key_error'): ''' Function that compares test_data to salt_data and generates a list of errors that will be displayed :param YSOrderedDict test_data: used as the base to test from :param YSOrderedDict data: data is compared to see if it matches test_data :param dict text: dictionary of all default text messages to use :param str mismatch: key to use to identify a data mismatch that refers to a message in text :param str key_error: key to use to identify a data key_error that refers to a message in text :return: a list of error messages :rtype: list ''' if not text: text = {} errors = [] for state_id, states in test_data.items(): for state_name, state_values in states.items(): for key, value in state_values.items(): if key in ignore: continue try: result_vars = dict(state_id=state_id, state_name=state_name, key=key, value=value) data_value = data[state_id][state_name][key] result_vars.update(data_value=data_value) if value != data_value: # MISMATCH if result_vars['value'] == '': result_vars['value'] = "\'\'" if result_vars['data_value'] == '': result_vars['data_value'] = "\'\'" errors.append(text[mismatch].format(result_vars)) except KeyError: # KEY ERROR if result_vars['value'] == '': result_vars['value'] = "\'\'" errors.append(text[key_error].format(result_vars)) return errors sls = ' ({0})'.format(sls) if sls else sls text = { 'mismatch': '<> MISMATCH: {{{0[state_id]}}}:{{{0[state_name]}}}:{{{0[key]}}} is {0[data_value]} but should ' 'be: {0[value]}', 'key_error': '-- MISSING : {{{0[state_id]}}}:{{{0[state_name]}}} does not contain key {{{0[key]}: {0[value]}}}', 'key_error2': '++ EXTRA : {{{0[state_id]}}}:{{{0[state_name]}}}:{{{0[key]}: {0[value]}}} not in test_data', 'test_data': 'TEST RESULTS - THE FOLLOWING IS MISSING FROM RENDERED STATE FILE', 'ruler': '========================================================================================', 'salt_data': 'TEST RESULTS - THE FOLLOWING IS PRESENT IN GENERATED STATE FILE, BUT NOT IN TEST FILE', 'end': 'TEST RESULTS - END =====================================================================', 'blank': '', 'no_error_test': 'Yamlscript Renderer{0}: No errors for test_data'.format(sls), 'no_error_salt': 'Yamlscript Renderer{0}: No errors for salt_data'.format(sls) } test1 = compare(test_data, salt_data, text=text) if test1: print text['test_data'] print text['ruler'] for message in test1: print message print text['blank'] else: print text['no_error_test'] test2 = compare(salt_data, test_data, text=text, mismatch='', key_error='key_error2') if test2: print text['salt_data'] print text['ruler'] for message in test2: print message print text['blank'] else: print text['no_error_salt'] return len(test1), len(test2)