mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
The test suite local client now properly receives the events. Fixes #3214.
* We were instantiating the integration testing local client too soon in the process. Deferring it to a little latter made it all work. * Added the ability to dump the master and minion testing configurations to files. Just prepend the `runtests` call with `DUMP_SALT_CONFIG=1` and you'll get the computed configuration files in `/tmp/salttest/{master,minion}`. * We now also un-subscribe from the event's once done. * Added `salt.utils.event.LocalClientEvent` just to differentiate from `salt.utils.event.MasterEvent` in the logs so we know who's who. It's just a subclass of the latter.
This commit is contained in:
parent
eacd67e902
commit
39f03c59cd
@ -77,7 +77,7 @@ class LocalClient(object):
|
||||
self.serial = salt.payload.Serial(self.opts)
|
||||
self.salt_user = self.__get_user()
|
||||
self.key = self.__read_master_key()
|
||||
self.event = salt.utils.event.MasterEvent(self.opts['sock_dir'])
|
||||
self.event = salt.utils.event.LocalClientEvent(self.opts['sock_dir'])
|
||||
|
||||
def __read_master_key(self):
|
||||
'''
|
||||
@ -163,9 +163,10 @@ class LocalClient(object):
|
||||
Common checks on the pub_data data structure returned from running pub
|
||||
'''
|
||||
if not pub_data:
|
||||
err = ('Failed to authenticate, is this user permitted to execute '
|
||||
'commands?')
|
||||
raise EauthAuthenticationError(err)
|
||||
raise EauthAuthenticationError(
|
||||
'Failed to authenticate, is this user permitted to execute '
|
||||
'commands?'
|
||||
)
|
||||
|
||||
# Failed to connect to the master and send the pub
|
||||
if not 'jid' in pub_data or pub_data['jid'] == '0':
|
||||
|
@ -130,18 +130,21 @@ class SaltEvent(object):
|
||||
if not self.cpub:
|
||||
self.connect_pub()
|
||||
self.sub.setsockopt(zmq.SUBSCRIBE, tag)
|
||||
while True:
|
||||
socks = dict(self.poller.poll(wait))
|
||||
if self.sub in socks and socks[self.sub] == zmq.POLLIN:
|
||||
raw = self.sub.recv()
|
||||
data = self.serial.loads(raw[20:])
|
||||
if full:
|
||||
ret = {'data': data,
|
||||
'tag': raw[:20].rstrip('|')}
|
||||
return ret
|
||||
return data
|
||||
else:
|
||||
try:
|
||||
while True:
|
||||
socks = dict(self.poller.poll(wait))
|
||||
if self.sub in socks and socks[self.sub] == zmq.POLLIN:
|
||||
raw = self.sub.recv()
|
||||
data = self.serial.loads(raw[20:])
|
||||
if full:
|
||||
ret = {'data': data,
|
||||
'tag': raw[:20].rstrip('|')}
|
||||
return ret
|
||||
return data
|
||||
return None
|
||||
finally:
|
||||
# No sense in keeping subscribed to this event
|
||||
self.sub.setsockopt(zmq.UNSUBSCRIBE, tag)
|
||||
|
||||
def iter_events(self, tag='', full=False):
|
||||
'''
|
||||
@ -202,6 +205,13 @@ class MasterEvent(SaltEvent):
|
||||
self.connect_pub()
|
||||
|
||||
|
||||
class LocalClientEvent(MasterEvent):
|
||||
'''
|
||||
This class is just used to differentiate who is handling the events,
|
||||
specially on logs, but it's the same as MasterEvent.
|
||||
'''
|
||||
|
||||
|
||||
class MinionEvent(SaltEvent):
|
||||
'''
|
||||
Create a master event management object
|
||||
|
@ -239,25 +239,28 @@ class TestDaemon(object):
|
||||
self.syndic_process = multiprocessing.Process(target=syndic.tune_in)
|
||||
self.syndic_process.start()
|
||||
|
||||
#if os.environ.get('DUMP_SALT_CONFIG', None) is not None:
|
||||
# try:
|
||||
# import yaml
|
||||
# os.makedirs('/tmp/salttest/conf')
|
||||
# except OSError:
|
||||
# pass
|
||||
# self.master_opts['user'] = pwd.getpwuid(os.getuid()).pw_name
|
||||
# self.minion_opts['user'] = pwd.getpwuid(os.getuid()).pw_name
|
||||
# open('/tmp/salttest/conf/master', 'w').write(
|
||||
# yaml.dump(self.master_opts)
|
||||
# )
|
||||
# open('/tmp/salttest/conf/minion', 'w').write(
|
||||
# yaml.dump(self.minion_opts)
|
||||
# )
|
||||
if os.environ.get('DUMP_SALT_CONFIG', None) is not None:
|
||||
from copy import deepcopy
|
||||
try:
|
||||
import yaml
|
||||
os.makedirs('/tmp/salttest/conf')
|
||||
except OSError:
|
||||
pass
|
||||
master_opts = deepcopy(self.master_opts)
|
||||
minion_opts = deepcopy(self.minion_opts)
|
||||
master_opts.pop('conf_file', None)
|
||||
master_opts['user'] = pwd.getpwuid(os.getuid()).pw_name
|
||||
|
||||
# Let's create a local client to ping and sync minions
|
||||
self.client = salt.client.LocalClient(
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master')
|
||||
)
|
||||
minion_opts['user'] = pwd.getpwuid(os.getuid()).pw_name
|
||||
minion_opts.pop('conf_file', None)
|
||||
minion_opts.pop('grains', None)
|
||||
minion_opts.pop('pillar', None)
|
||||
open('/tmp/salttest/conf/master', 'w').write(
|
||||
yaml.dump(master_opts)
|
||||
)
|
||||
open('/tmp/salttest/conf/minion', 'w').write(
|
||||
yaml.dump(minion_opts)
|
||||
)
|
||||
|
||||
self.minion_targets = set(['minion', 'sub_minion'])
|
||||
self.pre_setup_minions()
|
||||
@ -282,6 +285,20 @@ class TestDaemon(object):
|
||||
finally:
|
||||
self.post_setup_minions()
|
||||
|
||||
@property
|
||||
def client(self):
|
||||
'''
|
||||
Return a local client which will be used for example to ping and sync
|
||||
the test minions.
|
||||
|
||||
This client is defined as a class attribute because it's creation needs
|
||||
to be deferred to a latter stage. If created it on `__enter__` like it
|
||||
previously was, it would not receive the master events.
|
||||
'''
|
||||
return salt.client.LocalClient(
|
||||
mopts=self.master_opts
|
||||
)
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
'''
|
||||
Kill the minion and master processes
|
||||
@ -470,7 +487,7 @@ class TestDaemon(object):
|
||||
sys.stdout.flush()
|
||||
|
||||
responses = self.client.cmd(
|
||||
','.join(expected_connections), 'test.ping', expr_form='list',
|
||||
list(expected_connections), 'test.ping', expr_form='list',
|
||||
)
|
||||
for target in responses:
|
||||
if target not in expected_connections:
|
||||
|
Loading…
Reference in New Issue
Block a user