salt/tests/unit/context_test.py

199 lines
6.1 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
'''
tests.unit.context_test
~~~~~~~~~~~~~~~~~~~~
'''
# Import python libs
from __future__ import absolute_import
import json
import tornado.stack_context
import tornado.gen
from tornado.testing import AsyncTestCase, gen_test
import threading
import time
# Import Salt Testing libs
from salttesting import TestCase
2015-10-23 15:40:56 +00:00
from salt.ext.six.moves import range
from salttesting.helpers import ensure_in_syspath
ensure_in_syspath('../../')
# Import Salt libs
from salt.utils.context import ContextDict, NamespacedDictWrapper
class ContextDictTests(AsyncTestCase):
# how many threads/coroutines to run at a time
num_concurrent_tasks = 5
def setUp(self):
super(ContextDictTests, self).setUp()
self.cd = ContextDict()
# set a global value
self.cd['foo'] = 'global'
def test_threads(self):
'''Verify that ContextDict overrides properly within threads
'''
rets = []
def tgt(x, s):
inner_ret = []
over = self.cd.clone()
inner_ret.append(self.cd.get('foo'))
with over:
inner_ret.append(over.get('foo'))
over['foo'] = x
inner_ret.append(over.get('foo'))
time.sleep(s)
inner_ret.append(over.get('foo'))
rets.append(inner_ret)
threads = []
for x in range(0, self.num_concurrent_tasks):
s = self.num_concurrent_tasks - x
t = threading.Thread(target=tgt, args=(x, s))
t.start()
threads.append(t)
for t in threads:
t.join()
for r in rets:
self.assertEqual(r[0], r[1])
self.assertEqual(r[2], r[3])
@gen_test
def test_coroutines(self):
'''Verify that ContextDict overrides properly within coroutines
'''
@tornado.gen.coroutine
def secondary_coroutine(over):
raise tornado.gen.Return(over.get('foo'))
@tornado.gen.coroutine
def tgt(x, s, over):
inner_ret = []
# first grab the global
inner_ret.append(self.cd.get('foo'))
# grab the child's global (should match)
inner_ret.append(over.get('foo'))
# override the global
over['foo'] = x
inner_ret.append(over.get('foo'))
# sleep for some time to let other coroutines do this section of code
yield tornado.gen.sleep(s)
# get the value of the global again.
inner_ret.append(over.get('foo'))
# Call another coroutine to verify that we keep our context
r = yield secondary_coroutine(over)
inner_ret.append(r)
raise tornado.gen.Return(inner_ret)
futures = []
for x in range(0, self.num_concurrent_tasks):
s = self.num_concurrent_tasks - x
over = self.cd.clone()
2015-10-23 15:53:44 +00:00
f = tornado.stack_context.run_with_stack_context(
2015-10-23 15:53:44 +00:00
tornado.stack_context.StackContext(lambda: over), # pylint: disable=W0640
lambda: tgt(x, s/5.0, over), # pylint: disable=W0640
)
futures.append(f)
wait_iterator = tornado.gen.WaitIterator(*futures)
while not wait_iterator.done():
Remove repr formatting flag in places where it is used solely for quoting (#34183) * salt/cloud/__init__.py: remove repr formatting * salt/cloud/clouds/azurearm.py: remove repr formatting * salt/cloud/clouds/ec2.py: remove repr formatting * salt/cloud/clouds/profitbricks.py: remove repr formatting * salt/loader.py: remove repr formatting * salt/modules/win_file.py: remove repr formatting * salt/modules/zypper.py: remove repr formatting * salt/pillar/consul_pillar.py: remove repr formatting * salt/renderers/pyobjects.py: remove repr formatting * salt/returners/sentry_return.py: remove repr formatting * salt/states/bower.py: remove repr formatting * salt/states/cabal.py: remove repr formatting * salt/states/cmd.py: remove repr formatting * salt/states/composer.py: remove repr formatting * salt/states/win_network.py: remove repr formatting * salt/states/eselect.py: remove repr formatting * salt/states/file.py: remove repr formatting * salt/states/htpasswd.py: remove repr formatting * salt/states/memcached.py: remove repr formatting * salt/states/npm.py: remove repr formatting * salt/states/pip_state.py: remove repr formatting * salt/states/pkg.py: remove repr formatting * salt/states/pkgrepo.py: remove repr formatting * salt/states/supervisord.py: remove repr formatting * salt/states/timezone.py: remove repr formatting * salt/states/virtualenv_mod.py: remove repr formatting * salt/states/dockerio.py: remove repr formatting * salt/states/win_system.py: remove repr formatting * salt/utils/nb_popen.py: remove repr formatting * salt/utils/cloud.py: remove repr formatting * Add pylint disable due to legit usage of repr flag See https://github.com/saltstack/salt-pylint/pull/6 * Fix composer tests These tests needed to be updated because quoting was changed in the state module in 9dc9146. There was an unnecessary !r used for the exception class there, which means that instead of the exception class being passed through the formatter and coming out with the equivalent value of err.__str__(), we get a repr'ed instance of the exception class (i.e. SaltException('',)) in the state output. The unit test was asserting that we have that repr'ed instance of SaltException in the output, a case of writing the test to confirm the badly-conceived output in the state. This has also been corrected. * salt/cloud/clouds/azurearm.py: lint fixes * salt/modules/boto_s3_bucket.py: lint fixes * salt/modules/minion.py: lint fixes * salt/modules/reg.py: lint fixes * salt/modules/testinframod.py: lint fixes * salt/modules/win_iis.py: lint fixes * salt/pillar/csvpillar.py: lint fixes * salt/utils/win_functions.py: lint fixes * salt/states/nxos.py: lint fixes * salt/returners/mongo_future_return.py: lint fixes * tests/integration/__init__.py: lint fixes * tests/unit/context_test.py: lint fixes * tests/integration/states/file.py: lint fixes * tests/integration/utils/test_reactor.py: lint fixes * tests/integration/utils/testprogram.py: lint fixes * tests/unit/__init__.py: lint fixes * tests/integration/shell/minion.py: lint fixes * tests/unit/modules/boto_apigateway_test.py: lint fixes * tests/unit/modules/boto_cognitoidentity_test.py: lint fixes * tests/unit/modules/boto_elasticsearch_domain_test.py: lint fixes * tests/unit/modules/k8s_test.py: lint fixes * tests/unit/modules/reg_win_test.py: lint fixes * tests/unit/states/boto_apigateway_test.py: lint fixes * tests/unit/states/boto_cognitoidentity_test.py: lint fixes * tests/unit/states/boto_elasticsearch_domain_test.py: lint fixes
2016-06-29 20:30:18 +00:00
r = yield wait_iterator.next() # pylint: disable=incompatible-py3-code
self.assertEqual(r[0], r[1]) # verify that the global value remails
self.assertEqual(r[2], r[3]) # verify that the override sticks locally
self.assertEqual(r[3], r[4]) # verify that the override sticks across coroutines
def test_basic(self):
'''Test that the contextDict is a dict
'''
# ensure we get the global value
self.assertEqual(
dict(self.cd),
{'foo': 'global'},
)
def test_override(self):
over = self.cd.clone()
over['bar'] = 'global'
self.assertEqual(
dict(over),
{'foo': 'global', 'bar': 'global'},
)
self.assertEqual(
dict(self.cd),
{'foo': 'global'},
)
with over:
self.assertEqual(
dict(over),
{'foo': 'global', 'bar': 'global'},
)
self.assertEqual(
dict(self.cd),
{'foo': 'global', 'bar': 'global'},
)
over['bar'] = 'baz'
self.assertEqual(
dict(over),
{'foo': 'global', 'bar': 'baz'},
)
self.assertEqual(
dict(self.cd),
{'foo': 'global', 'bar': 'baz'},
)
self.assertEqual(
dict(over),
{'foo': 'global', 'bar': 'baz'},
)
self.assertEqual(
dict(self.cd),
{'foo': 'global'},
)
def test_multiple_contexts(self):
cds = []
2015-10-23 15:40:56 +00:00
for x in range(0, 10):
cds.append(self.cd.clone(bar=x))
for x, cd in enumerate(cds):
self.assertNotIn('bar', self.cd)
with cd:
self.assertEqual(
dict(self.cd),
{'bar': x, 'foo': 'global'},
)
self.assertNotIn('bar', self.cd)
class NamespacedDictWrapperTests(TestCase):
PREFIX = 'prefix'
def setUp(self):
self._dict = {}
def test_single_key(self):
self._dict['prefix'] = {'foo': 'bar'}
w = NamespacedDictWrapper(self._dict, 'prefix')
self.assertEqual(w['foo'], 'bar')
def test_multiple_key(self):
self._dict['prefix'] = {'foo': {'bar': 'baz'}}
w = NamespacedDictWrapper(self._dict, ('prefix', 'foo'))
self.assertEqual(w['bar'], 'baz')
def test_json_dumps_single_key(self):
self._dict['prefix'] = {'foo': {'bar': 'baz'}}
w = NamespacedDictWrapper(self._dict, 'prefix')
self.assertEqual(json.dumps(w), '{"foo": {"bar": "baz"}}')
def test_json_dumps_multiple_key(self):
self._dict['prefix'] = {'foo': {'bar': 'baz'}}
w = NamespacedDictWrapper(self._dict, ('prefix', 'foo'))
self.assertEqual(json.dumps(w), '{"bar": "baz"}')