mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 00:55:19 +00:00
60d80e7cda
This makes it possible to merge the state return for a subresource into a main state return. This is useful for configuring e.g. alarms to go along with a resource.
689 lines
29 KiB
Python
689 lines
29 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
Unit Tests for functions located in salt.utils.state.py.
|
|
'''
|
|
|
|
# Import python libs
|
|
from __future__ import absolute_import
|
|
import copy
|
|
import textwrap
|
|
|
|
# Import Salt libs
|
|
from salt.ext import six
|
|
import salt.utils.odict
|
|
import salt.utils.state
|
|
|
|
# Import Salt Testing libs
|
|
from tests.support.unit import TestCase
|
|
|
|
|
|
class StateUtilTestCase(TestCase):
|
|
'''
|
|
Test case for state util.
|
|
'''
|
|
def test_check_result(self):
|
|
self.assertFalse(salt.utils.state.check_result(None),
|
|
'Failed to handle None as an invalid data type.')
|
|
self.assertFalse(salt.utils.state.check_result([]),
|
|
'Failed to handle an invalid data type.')
|
|
self.assertFalse(salt.utils.state.check_result({}),
|
|
'Failed to handle an empty dictionary.')
|
|
self.assertFalse(salt.utils.state.check_result({'host1': []}),
|
|
'Failed to handle an invalid host data structure.')
|
|
test_valid_state = {'host1': {'test_state': {'result': 'We have liftoff!'}}}
|
|
self.assertTrue(salt.utils.state.check_result(test_valid_state))
|
|
test_valid_false_states = {
|
|
'test1': salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': False}),
|
|
])),
|
|
]),
|
|
'test2': salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
('host2',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': False}),
|
|
])),
|
|
]),
|
|
'test3': ['a'],
|
|
'test4': salt.utils.odict.OrderedDict([
|
|
('asup', salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
('host2',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': False}),
|
|
]))
|
|
]))
|
|
]),
|
|
'test5': salt.utils.odict.OrderedDict([
|
|
('asup', salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
('host2', salt.utils.odict.OrderedDict([]))
|
|
]))
|
|
])
|
|
}
|
|
for test, data in six.iteritems(test_valid_false_states):
|
|
self.assertFalse(
|
|
salt.utils.state.check_result(data),
|
|
msg='{0} failed'.format(test))
|
|
test_valid_true_states = {
|
|
'test1': salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
]),
|
|
'test3': salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
('host2',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
]),
|
|
'test4': salt.utils.odict.OrderedDict([
|
|
('asup', salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
('host2',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': True}),
|
|
]))
|
|
]))
|
|
]),
|
|
'test2': salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': None}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
('host2',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': True}),
|
|
('test_state', {'result': 'abc'}),
|
|
]))
|
|
])
|
|
}
|
|
for test, data in six.iteritems(test_valid_true_states):
|
|
self.assertTrue(
|
|
salt.utils.state.check_result(data),
|
|
msg='{0} failed'.format(test))
|
|
test_invalid_true_ht_states = {
|
|
'test_onfail_simple2': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_vstate0', {'result': False}),
|
|
('test_vstate1', {'result': True}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_vstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_vstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', True),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_vstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
),
|
|
'test_onfail_integ2': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('t_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate1_|-echo_|-run', {
|
|
'result': False}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_ivstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}],
|
|
't': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_ivstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', False),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_ivstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
),
|
|
'test_onfail_integ3': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('t_|-test_ivstate0_|-echo_|-run', {
|
|
'result': True}),
|
|
('cmd_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate1_|-echo_|-run', {
|
|
'result': False}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_ivstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}],
|
|
't': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_ivstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', False),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_ivstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
),
|
|
'test_onfail_integ4': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('t_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate1_|-echo_|-run', {
|
|
'result': True}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_ivstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}],
|
|
't': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_ivstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', False),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_ivstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
'test_ivstate2': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', True),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_ivstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
),
|
|
'test_onfail': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': False}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
]),
|
|
None
|
|
),
|
|
'test_onfail_d': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_state0', {'result': False}),
|
|
('test_state', {'result': True}),
|
|
])),
|
|
]),
|
|
{}
|
|
)
|
|
}
|
|
for test, testdata in six.iteritems(test_invalid_true_ht_states):
|
|
data, ht = testdata
|
|
for t_ in [a for a in data['host1']]:
|
|
tdata = data['host1'][t_]
|
|
if '_|-' in t_:
|
|
t_ = t_.split('_|-')[1]
|
|
tdata['__id__'] = t_
|
|
self.assertFalse(
|
|
salt.utils.state.check_result(data, highstate=ht),
|
|
msg='{0} failed'.format(test))
|
|
|
|
test_valid_true_ht_states = {
|
|
'test_onfail_integ': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('cmd_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate1_|-echo_|-run', {
|
|
'result': True}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_ivstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_ivstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', False),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_ivstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
),
|
|
'test_onfail_intega3': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('t_|-test_ivstate0_|-echo_|-run', {
|
|
'result': True}),
|
|
('cmd_|-test_ivstate0_|-echo_|-run', {
|
|
'result': False}),
|
|
('cmd_|-test_ivstate1_|-echo_|-run', {
|
|
'result': True}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_ivstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}],
|
|
't': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_ivstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', False),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_ivstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
),
|
|
'test_onfail_simple': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_vstate0', {'result': False}),
|
|
('test_vstate1', {'result': True}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_vstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_vstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail_stop', False),
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_vstate0')])])
|
|
]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
), # order is different
|
|
'test_onfail_simple_rev': (
|
|
salt.utils.odict.OrderedDict([
|
|
('host1',
|
|
salt.utils.odict.OrderedDict([
|
|
('test_vstate0', {'result': False}),
|
|
('test_vstate1', {'result': True}),
|
|
])),
|
|
]),
|
|
{
|
|
'test_vstate0': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
'run',
|
|
{'order': 10002}]},
|
|
'test_vstate1': {
|
|
'__env__': 'base',
|
|
'__sls__': u'a',
|
|
'cmd': [salt.utils.odict.OrderedDict([('name', '/bin/true')]),
|
|
salt.utils.odict.OrderedDict([
|
|
('onfail',
|
|
[salt.utils.odict.OrderedDict([('cmd', 'test_vstate0')])])
|
|
]),
|
|
salt.utils.odict.OrderedDict([('onfail_stop', False)]),
|
|
'run',
|
|
{'order': 10004}]},
|
|
}
|
|
)
|
|
}
|
|
for test, testdata in six.iteritems(test_valid_true_ht_states):
|
|
data, ht = testdata
|
|
for t_ in [a for a in data['host1']]:
|
|
tdata = data['host1'][t_]
|
|
if '_|-' in t_:
|
|
t_ = t_.split('_|-')[1]
|
|
tdata['__id__'] = t_
|
|
self.assertTrue(
|
|
salt.utils.state.check_result(data, highstate=ht),
|
|
msg='{0} failed'.format(test))
|
|
test_valid_false_state = {'host1': {'test_state': {'result': False}}}
|
|
self.assertFalse(salt.utils.state.check_result(test_valid_false_state))
|
|
|
|
|
|
class UtilStateMergeSubreturnTestcase(TestCase):
|
|
'''
|
|
Test cases for salt.utils.state.merge_subreturn function.
|
|
'''
|
|
main_ret = {
|
|
'name': 'primary',
|
|
# result may be missing, as primarysalt.utils.state is still in progress
|
|
'comment': '',
|
|
'changes': {},
|
|
}
|
|
sub_ret = {
|
|
'name': 'secondary',
|
|
'result': True,
|
|
'comment': '',
|
|
'changes': {},
|
|
}
|
|
|
|
def test_merge_result(self):
|
|
# result not created if not needed
|
|
for no_effect_result in [True, None]:
|
|
m = copy.deepcopy(self.main_ret)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['result'] = no_effect_result
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertNotIn('result', res)
|
|
|
|
# False subresult is propagated to existing result
|
|
for original_result in [True, None, False]:
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['result'] = original_result
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['result'] = False
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertFalse(res['result'])
|
|
|
|
# False result cannot be overriden
|
|
for any_result in [True, None, False]:
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['result'] = False
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['result'] = any_result
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertFalse(res['result'])
|
|
|
|
def test_merge_changes(self):
|
|
# The main changes dict should always already exist,
|
|
# and there should always be a changes dict in the secondary.
|
|
primary_changes = {'old': None, 'new': 'my_resource'}
|
|
secondary_changes = {'old': None, 'new': ['alarm-1', 'alarm-2']}
|
|
|
|
# No changes case
|
|
m = copy.deepcopy(self.main_ret)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertDictEqual(res['changes'], {})
|
|
|
|
# New changes don't get rid of existing changes
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['changes'] = copy.deepcopy(primary_changes)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['changes'] = copy.deepcopy(secondary_changes)
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertDictEqual(res['changes'], {
|
|
'old': None,
|
|
'new': 'my_resource',
|
|
'secondary': secondary_changes,
|
|
})
|
|
|
|
# The subkey parameter is respected
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['changes'] = copy.deepcopy(primary_changes)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['changes'] = copy.deepcopy(secondary_changes)
|
|
res = salt.utils.state.merge_subreturn(m, s, subkey='alarms')
|
|
self.assertDictEqual(res['changes'], {
|
|
'old': None,
|
|
'new': 'my_resource',
|
|
'alarms': secondary_changes,
|
|
})
|
|
|
|
def test_merge_pchanges(self):
|
|
primary_pchanges = {'old': None, 'new': 'my_resource'}
|
|
secondary_pchanges = {'old': None, 'new': ['alarm-1', 'alarm-2']}
|
|
|
|
# Neither main nor sub pchanges case
|
|
m = copy.deepcopy(self.main_ret)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertNotIn('pchanges', res)
|
|
|
|
# No main pchanges, sub pchanges
|
|
m = copy.deepcopy(self.main_ret)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['pchanges'] = copy.deepcopy(secondary_pchanges)
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertDictEqual(res['pchanges'], {
|
|
'secondary': secondary_pchanges
|
|
})
|
|
|
|
# Main pchanges, no sub pchanges
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['pchanges'] = copy.deepcopy(primary_pchanges)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertDictEqual(res['pchanges'], primary_pchanges)
|
|
|
|
# Both main and sub pchanges, new pchanges don't affect existing ones
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['pchanges'] = copy.deepcopy(primary_pchanges)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['pchanges'] = copy.deepcopy(secondary_pchanges)
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertDictEqual(res['pchanges'], {
|
|
'old': None,
|
|
'new': 'my_resource',
|
|
'secondary': secondary_pchanges,
|
|
})
|
|
|
|
# The subkey parameter is respected
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['pchanges'] = copy.deepcopy(primary_pchanges)
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['pchanges'] = copy.deepcopy(secondary_pchanges)
|
|
res = salt.utils.state.merge_subreturn(m, s, subkey='alarms')
|
|
self.assertDictEqual(res['pchanges'], {
|
|
'old': None,
|
|
'new': 'my_resource',
|
|
'alarms': secondary_pchanges,
|
|
})
|
|
|
|
def test_merge_comments(self):
|
|
main_comment_1 = 'First primary comment.'
|
|
main_comment_2 = 'Second primary comment.'
|
|
sub_comment_1 = 'First secondary comment,\nwhich spans two lines.'
|
|
sub_comment_2 = 'Second secondary comment: {0}'.format(
|
|
'some error\n And a traceback',
|
|
)
|
|
final_comment = textwrap.dedent('''\
|
|
First primary comment.
|
|
Second primary comment.
|
|
First secondary comment,
|
|
which spans two lines.
|
|
Second secondary comment: some error
|
|
And a traceback
|
|
'''.rstrip())
|
|
|
|
# Joining two strings
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = main_comment_1 + u'\n' + main_comment_2
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = sub_comment_1 + u'\n' + sub_comment_2
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertMultiLineEqual(res['comment'], final_comment)
|
|
|
|
# Joining string and a list
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = main_comment_1 + u'\n' + main_comment_2
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = [sub_comment_1, sub_comment_2]
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertMultiLineEqual(res['comment'], final_comment)
|
|
|
|
# For tests where output is a list,
|
|
# also test that final joined output will match
|
|
# Joining list and a string
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = [main_comment_1, main_comment_2]
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = sub_comment_1 + u'\n' + sub_comment_2
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertEqual(res['comment'], [
|
|
main_comment_1,
|
|
main_comment_2,
|
|
sub_comment_1 + u'\n' + sub_comment_2,
|
|
])
|
|
self.assertMultiLineEqual(u'\n'.join(res['comment']), final_comment)
|
|
|
|
# Joining two lists
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = [main_comment_1, main_comment_2]
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = [sub_comment_1, sub_comment_2]
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertEqual(res['comment'], [
|
|
main_comment_1,
|
|
main_comment_2,
|
|
sub_comment_1,
|
|
sub_comment_2,
|
|
])
|
|
self.assertMultiLineEqual(u'\n'.join(res['comment']), final_comment)
|
|
|
|
def test_merge_empty_comments(self):
|
|
# Since the primarysalt.utils.state is in progress,
|
|
# the main comment may be empty, either '' or [].
|
|
# Note that [''] is a degenerate case and should never happen,
|
|
# hence the behavior is left unspecified in that case.
|
|
# The secondary comment should never be empty,
|
|
# because thatsalt.utils.state has already returned,
|
|
# so we leave the behavior unspecified in that case.
|
|
sub_comment_1 = 'Secondary comment about changes:'
|
|
sub_comment_2 = 'A diff that goes with the previous comment'
|
|
# No contributions from primary
|
|
final_comment = sub_comment_1 + u'\n' + sub_comment_2
|
|
|
|
# Joining empty string and a string
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = ''
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = sub_comment_1 + u'\n' + sub_comment_2
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertEqual(res['comment'], final_comment)
|
|
|
|
# Joining empty string and a list
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = ''
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = [sub_comment_1, sub_comment_2]
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertEqual(res['comment'], final_comment)
|
|
|
|
# For tests where output is a list,
|
|
# also test that final joined output will match
|
|
# Joining empty list and a string
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = []
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = sub_comment_1 + u'\n' + sub_comment_2
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertEqual(res['comment'], [final_comment])
|
|
self.assertEqual(u'\n'.join(res['comment']), final_comment)
|
|
|
|
# Joining empty list and a list
|
|
m = copy.deepcopy(self.main_ret)
|
|
m['comment'] = []
|
|
s = copy.deepcopy(self.sub_ret)
|
|
s['comment'] = [sub_comment_1, sub_comment_2]
|
|
res = salt.utils.state.merge_subreturn(m, s)
|
|
self.assertEqual(res['comment'], [sub_comment_1, sub_comment_2])
|
|
self.assertEqual(u'\n'.join(res['comment']), final_comment)
|