conftest.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. # -*- coding: utf-8 -*-
  2. '''
  3. tests.multimaster.conftest
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. Multimaster PyTest prep routines
  6. '''
  7. from __future__ import absolute_import, print_function, unicode_literals
  8. import os
  9. import shutil
  10. import logging
  11. from collections import OrderedDict
  12. import pytest
  13. import psutil
  14. import salt.utils.files
  15. from salt.serializers import yaml
  16. from salt.utils.immutabletypes import freeze
  17. from tests.support.runtests import RUNTIME_VARS
  18. from pytestsalt.fixtures.ports import get_unused_localhost_port
  19. from pytestsalt.fixtures.config import apply_master_config, apply_minion_config
  20. from pytestsalt.fixtures.daemons import SaltMaster, SaltMinion, start_daemon
  21. log = logging.getLogger(__name__)
  22. SESSION_ROOT_DIR = 'sess-mm-root'
  23. SESSION_SECONDARY_ROOT_DIR = 'sess-sec-mm-root'
  24. @pytest.fixture(scope='session')
  25. def session_mm_root_dir(tempdir):
  26. '''
  27. Return the session scoped salt root dir
  28. '''
  29. return tempdir.mkdir(SESSION_ROOT_DIR)
  30. @pytest.fixture(scope='session')
  31. def session_mm_conf_dir(session_mm_root_dir):
  32. '''
  33. Return the session scoped salt root dir
  34. '''
  35. return session_mm_root_dir.join('conf').ensure(dir=True)
  36. # ----- Master Fixtures --------------------------------------------------------------------------------------------->
  37. @pytest.fixture(scope='session')
  38. def session_mm_master_id():
  39. '''
  40. Returns the session scoped master id
  41. '''
  42. return 'mm-master'
  43. @pytest.fixture(scope='session')
  44. def session_mm_master_publish_port():
  45. '''
  46. Returns an unused localhost port for the master publish interface
  47. '''
  48. return get_unused_localhost_port()
  49. @pytest.fixture(scope='session')
  50. def session_mm_master_return_port():
  51. '''
  52. Returns an unused localhost port for the master return interface
  53. '''
  54. return get_unused_localhost_port()
  55. @pytest.fixture(scope='session')
  56. def session_mm_master_engine_port():
  57. '''
  58. Returns an unused localhost port for the pytest session salt master engine
  59. '''
  60. return get_unused_localhost_port()
  61. @pytest.fixture(scope='session')
  62. def session_mm_master_tcp_master_pub_port():
  63. '''
  64. Returns an unused localhost port
  65. '''
  66. return get_unused_localhost_port()
  67. @pytest.fixture(scope='session')
  68. def session_mm_master_tcp_master_pull_port():
  69. '''
  70. Returns an unused localhost port
  71. '''
  72. return get_unused_localhost_port()
  73. @pytest.fixture(scope='session')
  74. def session_mm_master_tcp_master_publish_pull():
  75. '''
  76. Returns an unused localhost port
  77. '''
  78. return get_unused_localhost_port()
  79. @pytest.fixture(scope='session')
  80. def session_mm_master_tcp_master_workers():
  81. '''
  82. Returns an unused localhost port
  83. '''
  84. return get_unused_localhost_port()
  85. @pytest.fixture(scope='session')
  86. def session_mm_master_log_prefix(session_mm_master_id):
  87. return 'salt-master/{}'.format(session_mm_master_id)
  88. @pytest.fixture(scope='session')
  89. def session_mm_master_config_file(session_mm_conf_dir):
  90. '''
  91. Returns the path to the salt master configuration file
  92. '''
  93. return session_mm_conf_dir.join('master').realpath().strpath
  94. @pytest.fixture(scope='session')
  95. def session_mm_master_default_options(session_master_default_options):
  96. with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, 'mm_master')) as rfh:
  97. config_file_opts = yaml.deserialize(rfh.read())
  98. opts = session_master_default_options.copy()
  99. if config_file_opts:
  100. opts.update(config_file_opts)
  101. return opts
  102. @pytest.fixture(scope='session')
  103. def session_mm_master_config_overrides(session_master_config_overrides,
  104. session_mm_root_dir):
  105. overrides = session_master_config_overrides.copy()
  106. pytest_stop_sending_events_file = session_mm_root_dir.join('pytest_mm_stop_sending_events_file').strpath
  107. with salt.utils.files.fopen(pytest_stop_sending_events_file, 'w') as wfh:
  108. wfh.write('')
  109. overrides['pytest_stop_sending_events_file'] = pytest_stop_sending_events_file
  110. return overrides
  111. @pytest.fixture(scope='session')
  112. def session_mm_master_config(session_mm_root_dir,
  113. session_mm_master_default_options,
  114. session_mm_master_config_file,
  115. session_mm_master_publish_port,
  116. session_mm_master_return_port,
  117. session_mm_master_engine_port,
  118. session_mm_master_config_overrides,
  119. session_mm_master_id,
  120. session_base_env_state_tree_root_dir,
  121. session_prod_env_state_tree_root_dir,
  122. session_base_env_pillar_tree_root_dir,
  123. session_prod_env_pillar_tree_root_dir,
  124. running_username,
  125. log_server_port,
  126. log_server_level,
  127. engines_dir,
  128. log_handlers_dir,
  129. session_mm_master_log_prefix,
  130. session_mm_master_tcp_master_pub_port,
  131. session_mm_master_tcp_master_pull_port,
  132. session_mm_master_tcp_master_publish_pull,
  133. session_mm_master_tcp_master_workers):
  134. '''
  135. This fixture will return the salt master configuration options after being
  136. overridden with any options passed from ``session_master_config_overrides``
  137. '''
  138. return apply_master_config(session_mm_master_default_options,
  139. session_mm_root_dir,
  140. session_mm_master_config_file,
  141. session_mm_master_publish_port,
  142. session_mm_master_return_port,
  143. session_mm_master_engine_port,
  144. session_mm_master_config_overrides,
  145. session_mm_master_id,
  146. [session_base_env_state_tree_root_dir.strpath],
  147. [session_prod_env_state_tree_root_dir.strpath],
  148. [session_base_env_pillar_tree_root_dir.strpath],
  149. [session_prod_env_pillar_tree_root_dir.strpath],
  150. running_username,
  151. log_server_port,
  152. log_server_level,
  153. engines_dir,
  154. log_handlers_dir,
  155. session_mm_master_log_prefix,
  156. session_mm_master_tcp_master_pub_port,
  157. session_mm_master_tcp_master_pull_port,
  158. session_mm_master_tcp_master_publish_pull,
  159. session_mm_master_tcp_master_workers)
  160. @pytest.fixture(scope='session')
  161. def session_mm_salt_master(request,
  162. session_mm_conf_dir,
  163. session_mm_master_id,
  164. session_mm_master_config,
  165. log_server, # pylint: disable=unused-argument
  166. session_mm_master_log_prefix,
  167. cli_master_script_name,
  168. _cli_bin_dir,
  169. _salt_fail_hard,
  170. ):
  171. '''
  172. Returns a running salt-master
  173. '''
  174. return start_daemon(request,
  175. daemon_name='salt-master',
  176. daemon_id=session_mm_master_id,
  177. daemon_log_prefix=session_mm_master_log_prefix,
  178. daemon_cli_script_name=cli_master_script_name,
  179. daemon_config=session_mm_master_config,
  180. daemon_config_dir=session_mm_conf_dir,
  181. daemon_class=SaltMaster,
  182. bin_dir_path=_cli_bin_dir,
  183. fail_hard=_salt_fail_hard,
  184. event_listener_config_dir=session_mm_conf_dir,
  185. start_timeout=120)
  186. # <---- Master Fixtures ----------------------------------------------------------------------------------------------
  187. @pytest.fixture(scope='session')
  188. def session_mm_secondary_root_dir(tempdir):
  189. '''
  190. Return the session scoped salt secondary root dir
  191. '''
  192. return tempdir.mkdir(SESSION_SECONDARY_ROOT_DIR)
  193. @pytest.fixture(scope='session')
  194. def session_mm_secondary_conf_dir(session_mm_secondary_root_dir):
  195. '''
  196. Return the session scoped salt root dir
  197. '''
  198. return session_mm_secondary_root_dir.join('conf').ensure(dir=True)
  199. # ----- Sub Master Fixtures ----------------------------------------------------------------------------------------->
  200. @pytest.fixture(scope='session')
  201. def session_mm_secondary_master_id():
  202. '''
  203. Returns the session scoped master id
  204. '''
  205. return 'mm-sub-master'
  206. @pytest.fixture(scope='session')
  207. def session_mm_secondary_master_publish_port():
  208. '''
  209. Returns an unused localhost port for the master publish interface
  210. '''
  211. return get_unused_localhost_port()
  212. @pytest.fixture(scope='session')
  213. def session_mm_secondary_master_return_port():
  214. '''
  215. Returns an unused localhost port for the master return interface
  216. '''
  217. return get_unused_localhost_port()
  218. @pytest.fixture(scope='session')
  219. def session_mm_secondary_master_engine_port():
  220. '''
  221. Returns an unused localhost port for the pytest session salt master engine
  222. '''
  223. return get_unused_localhost_port()
  224. @pytest.fixture(scope='session')
  225. def session_mm_secondary_master_tcp_master_pub_port():
  226. '''
  227. Returns an unused localhost port
  228. '''
  229. return get_unused_localhost_port()
  230. @pytest.fixture(scope='session')
  231. def session_mm_secondary_master_tcp_master_pull_port():
  232. '''
  233. Returns an unused localhost port
  234. '''
  235. return get_unused_localhost_port()
  236. @pytest.fixture(scope='session')
  237. def session_mm_secondary_master_tcp_master_publish_pull():
  238. '''
  239. Returns an unused localhost port
  240. '''
  241. return get_unused_localhost_port()
  242. @pytest.fixture(scope='session')
  243. def session_mm_secondary_master_tcp_master_workers():
  244. '''
  245. Returns an unused localhost port
  246. '''
  247. return get_unused_localhost_port()
  248. @pytest.fixture(scope='session')
  249. def session_mm_secondary_master_log_prefix(session_mm_secondary_master_id):
  250. return 'salt-master/{}'.format(session_mm_secondary_master_id)
  251. @pytest.fixture(scope='session')
  252. def session_mm_secondary_master_config_file(session_mm_secondary_conf_dir):
  253. '''
  254. Returns the path to the salt master configuration file
  255. '''
  256. return session_mm_secondary_conf_dir.join('master').realpath().strpath
  257. @pytest.fixture(scope='session')
  258. def session_mm_secondary_master_default_options(session_master_default_options):
  259. opts = session_master_default_options.copy()
  260. with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, 'mm_sub_master')) as rfh:
  261. opts.update(yaml.deserialize(rfh.read()))
  262. return opts
  263. @pytest.fixture(scope='session')
  264. def session_mm_secondary_master_config_overrides(session_master_config_overrides,
  265. session_mm_secondary_root_dir):
  266. overrides = session_master_config_overrides.copy()
  267. pytest_stop_sending_events_file = session_mm_secondary_root_dir.join('pytest_mm_stop_sending_events_file').strpath
  268. with salt.utils.files.fopen(pytest_stop_sending_events_file, 'w') as wfh:
  269. wfh.write('')
  270. overrides['pytest_stop_sending_events_file'] = pytest_stop_sending_events_file
  271. return overrides
  272. @pytest.fixture(scope='session')
  273. def session_mm_secondary_master_config(session_mm_secondary_root_dir,
  274. session_mm_secondary_master_default_options,
  275. session_mm_secondary_master_config_file,
  276. session_mm_secondary_master_publish_port,
  277. session_mm_secondary_master_return_port,
  278. session_mm_secondary_master_engine_port,
  279. session_mm_secondary_master_config_overrides,
  280. session_mm_secondary_master_id,
  281. session_base_env_state_tree_root_dir,
  282. session_prod_env_state_tree_root_dir,
  283. session_base_env_pillar_tree_root_dir,
  284. session_prod_env_pillar_tree_root_dir,
  285. running_username,
  286. log_server_port,
  287. log_server_level,
  288. engines_dir,
  289. log_handlers_dir,
  290. session_mm_secondary_master_log_prefix,
  291. session_mm_secondary_master_tcp_master_pub_port,
  292. session_mm_secondary_master_tcp_master_pull_port,
  293. session_mm_secondary_master_tcp_master_publish_pull,
  294. session_mm_secondary_master_tcp_master_workers):
  295. '''
  296. This fixture will return the salt master configuration options after being
  297. overridden with any options passed from ``session_master_config_overrides``
  298. '''
  299. return apply_master_config(session_mm_secondary_master_default_options,
  300. session_mm_secondary_root_dir,
  301. session_mm_secondary_master_config_file,
  302. session_mm_secondary_master_publish_port,
  303. session_mm_secondary_master_return_port,
  304. session_mm_secondary_master_engine_port,
  305. session_mm_secondary_master_config_overrides,
  306. session_mm_secondary_master_id,
  307. [session_base_env_state_tree_root_dir.strpath],
  308. [session_prod_env_state_tree_root_dir.strpath],
  309. [session_base_env_pillar_tree_root_dir.strpath],
  310. [session_prod_env_pillar_tree_root_dir.strpath],
  311. running_username,
  312. log_server_port,
  313. log_server_level,
  314. engines_dir,
  315. log_handlers_dir,
  316. session_mm_secondary_master_log_prefix,
  317. session_mm_secondary_master_tcp_master_pub_port,
  318. session_mm_secondary_master_tcp_master_pull_port,
  319. session_mm_secondary_master_tcp_master_publish_pull,
  320. session_mm_secondary_master_tcp_master_workers)
  321. @pytest.fixture(scope='session')
  322. def session_mm_secondary_salt_master(request,
  323. session_mm_secondary_conf_dir,
  324. session_mm_secondary_master_id,
  325. session_mm_secondary_master_config,
  326. log_server, # pylint: disable=unused-argument
  327. session_mm_secondary_master_log_prefix,
  328. cli_master_script_name,
  329. _cli_bin_dir,
  330. _salt_fail_hard,
  331. session_mm_master_config,
  332. session_mm_salt_master
  333. ):
  334. '''
  335. Returns a running salt-master
  336. '''
  337. # The secondary salt master depends on the primarily salt master fixture
  338. # because we need to clone the keys
  339. for keyfile in ('master.pem', 'master.pub'):
  340. shutil.copyfile(
  341. os.path.join(session_mm_master_config['pki_dir'], keyfile),
  342. os.path.join(session_mm_secondary_master_config['pki_dir'], keyfile)
  343. )
  344. return start_daemon(request,
  345. daemon_name='salt-master',
  346. daemon_id=session_mm_secondary_master_id,
  347. daemon_log_prefix=session_mm_secondary_master_log_prefix,
  348. daemon_cli_script_name=cli_master_script_name,
  349. daemon_config=session_mm_secondary_master_config,
  350. daemon_config_dir=session_mm_secondary_conf_dir,
  351. daemon_class=SaltMaster,
  352. bin_dir_path=_cli_bin_dir,
  353. fail_hard=_salt_fail_hard,
  354. event_listener_config_dir=session_mm_secondary_conf_dir,
  355. start_timeout=120)
  356. # <---- Sub Master Fixtures ------------------------------------------------------------------------------------------
  357. # ----- Sub Minion Fixtures --------------------------------------------------------------------------------------------->
  358. @pytest.fixture(scope='session')
  359. def session_mm_secondary_minion_id():
  360. '''
  361. Returns the session scoped minion id
  362. '''
  363. return 'mm-sub-minion'
  364. @pytest.fixture(scope='session')
  365. def session_mm_secondary_minion_tcp_pub_port():
  366. '''
  367. Returns an unused localhost port
  368. '''
  369. return get_unused_localhost_port()
  370. @pytest.fixture(scope='session')
  371. def session_mm_secondary_minion_tcp_pull_port():
  372. '''
  373. Returns an unused localhost port
  374. '''
  375. return get_unused_localhost_port()
  376. @pytest.fixture(scope='session')
  377. def session_mm_secondary_minion_log_prefix(session_mm_secondary_minion_id):
  378. return 'salt-minion/{}'.format(session_mm_secondary_minion_id)
  379. @pytest.fixture(scope='session')
  380. def session_mm_secondary_minion_config_file(session_mm_secondary_conf_dir):
  381. '''
  382. Returns the path to the salt minion configuration file
  383. '''
  384. return session_mm_secondary_conf_dir.join('minion').realpath().strpath
  385. @pytest.fixture(scope='session')
  386. def session_mm_secondary_minion_default_options(session_secondary_minion_default_options):
  387. opts = session_secondary_minion_default_options.copy()
  388. with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, 'mm_sub_minion')) as rfh:
  389. opts.update(yaml.deserialize(rfh.read()))
  390. return opts
  391. @pytest.fixture(scope='session')
  392. def session_mm_secondary_minion_config_overrides(session_secondary_minion_config_overrides,
  393. session_mm_master_return_port,
  394. session_mm_secondary_master_return_port):
  395. if session_secondary_minion_config_overrides:
  396. opts = session_secondary_minion_config_overrides.copy()
  397. else:
  398. opts = {}
  399. opts['master_port'] = None
  400. opts['master'] = [
  401. 'localhost:{}'.format(session_mm_master_return_port),
  402. 'localhost:{}'.format(session_mm_secondary_master_return_port)
  403. ]
  404. return opts
  405. @pytest.fixture(scope='session')
  406. def session_mm_secondary_minion_config(session_mm_secondary_root_dir,
  407. session_mm_secondary_minion_config_file,
  408. session_mm_secondary_master_return_port,
  409. session_mm_secondary_minion_default_options,
  410. session_mm_secondary_minion_config_overrides,
  411. session_mm_secondary_minion_id,
  412. running_username,
  413. log_server_port,
  414. log_server_level,
  415. log_handlers_dir,
  416. session_mm_secondary_minion_log_prefix,
  417. session_mm_secondary_minion_tcp_pub_port,
  418. session_mm_secondary_minion_tcp_pull_port):
  419. '''
  420. This fixture will return the session salt minion configuration options after being
  421. overrided with any options passed from ``session_secondary_minion_config_overrides``
  422. '''
  423. return apply_minion_config(session_mm_secondary_minion_default_options,
  424. session_mm_secondary_root_dir,
  425. session_mm_secondary_minion_config_file,
  426. session_mm_secondary_master_return_port,
  427. session_mm_secondary_minion_config_overrides,
  428. session_mm_secondary_minion_id,
  429. running_username,
  430. log_server_port,
  431. log_server_level,
  432. log_handlers_dir,
  433. session_mm_secondary_minion_log_prefix,
  434. session_mm_secondary_minion_tcp_pub_port,
  435. session_mm_secondary_minion_tcp_pull_port)
  436. @pytest.fixture(scope='session')
  437. def session_mm_secondary_salt_minion(request,
  438. session_mm_salt_master,
  439. session_mm_secondary_salt_master,
  440. session_mm_secondary_minion_id,
  441. session_mm_secondary_minion_config,
  442. session_mm_secondary_minion_log_prefix,
  443. cli_minion_script_name,
  444. log_server,
  445. _cli_bin_dir,
  446. _salt_fail_hard,
  447. session_mm_secondary_conf_dir):
  448. '''
  449. Returns a running salt-minion
  450. '''
  451. return start_daemon(request,
  452. daemon_name='salt-minion',
  453. daemon_id=session_mm_secondary_minion_id,
  454. daemon_log_prefix=session_mm_secondary_minion_log_prefix,
  455. daemon_cli_script_name=cli_minion_script_name,
  456. daemon_config=session_mm_secondary_minion_config,
  457. daemon_config_dir=session_mm_secondary_conf_dir,
  458. daemon_class=SaltMinion,
  459. bin_dir_path=_cli_bin_dir,
  460. fail_hard=_salt_fail_hard,
  461. event_listener_config_dir=session_mm_secondary_conf_dir,
  462. start_timeout=120)
  463. # <---- Minion Fixtures ----------------------------------------------------------------------------------------------
  464. # ----- Minion Fixtures ----------------------------------------------------------------------------------------->
  465. @pytest.fixture(scope='session')
  466. def session_mm_minion_id():
  467. '''
  468. Returns the session scoped minion id
  469. '''
  470. return 'mm-minion'
  471. @pytest.fixture(scope='session')
  472. def session_mm_minion_tcp_pub_port():
  473. '''
  474. Returns an unused localhost port
  475. '''
  476. return get_unused_localhost_port()
  477. @pytest.fixture(scope='session')
  478. def session_mm_minion_tcp_pull_port():
  479. '''
  480. Returns an unused localhost port
  481. '''
  482. return get_unused_localhost_port()
  483. @pytest.fixture(scope='session')
  484. def session_mm_minion_log_prefix(session_mm_minion_id):
  485. return 'salt-minion/{}'.format(session_mm_minion_id)
  486. @pytest.fixture(scope='session')
  487. def session_mm_minion_config_file(session_mm_conf_dir):
  488. '''
  489. Returns the path to the salt minion configuration file
  490. '''
  491. return session_mm_conf_dir.join('minion').realpath().strpath
  492. @pytest.fixture(scope='session')
  493. def session_mm_minion_default_options(session_minion_default_options):
  494. opts = session_minion_default_options.copy()
  495. with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, 'mm_sub_minion')) as rfh:
  496. opts.update(yaml.deserialize(rfh.read()))
  497. return opts
  498. @pytest.fixture(scope='session')
  499. def session_mm_minion_config_overrides(session_minion_config_overrides,
  500. session_mm_master_return_port,
  501. session_mm_secondary_master_return_port):
  502. if session_minion_config_overrides:
  503. opts = session_minion_config_overrides.copy()
  504. else:
  505. opts = {}
  506. opts['master_port'] = None
  507. opts['master'] = [
  508. 'localhost:{}'.format(session_mm_master_return_port),
  509. 'localhost:{}'.format(session_mm_secondary_master_return_port)
  510. ]
  511. return opts
  512. @pytest.fixture(scope='session')
  513. def session_mm_minion_config(session_mm_root_dir,
  514. session_mm_minion_config_file,
  515. session_mm_master_return_port,
  516. session_mm_minion_default_options,
  517. session_mm_minion_config_overrides,
  518. session_mm_minion_id,
  519. running_username,
  520. log_server_port,
  521. log_server_level,
  522. log_handlers_dir,
  523. session_mm_minion_log_prefix,
  524. session_mm_minion_tcp_pub_port,
  525. session_mm_minion_tcp_pull_port):
  526. '''
  527. This fixture will return the session salt minion configuration options after being
  528. overrided with any options passed from ``session_minion_config_overrides``
  529. '''
  530. return apply_minion_config(session_mm_minion_default_options,
  531. session_mm_root_dir,
  532. session_mm_minion_config_file,
  533. session_mm_master_return_port,
  534. session_mm_minion_config_overrides,
  535. session_mm_minion_id,
  536. running_username,
  537. log_server_port,
  538. log_server_level,
  539. log_handlers_dir,
  540. session_mm_minion_log_prefix,
  541. session_mm_minion_tcp_pub_port,
  542. session_mm_minion_tcp_pull_port)
  543. @pytest.fixture(scope='session')
  544. def session_mm_salt_minion(request,
  545. session_mm_salt_master,
  546. session_mm_secondary_salt_master,
  547. session_mm_minion_id,
  548. session_mm_minion_config,
  549. session_mm_minion_log_prefix,
  550. cli_minion_script_name,
  551. log_server,
  552. _cli_bin_dir,
  553. _salt_fail_hard,
  554. session_mm_conf_dir):
  555. '''
  556. Returns a running salt-minion
  557. '''
  558. return start_daemon(request,
  559. daemon_name='salt-minion',
  560. daemon_id=session_mm_minion_id,
  561. daemon_log_prefix=session_mm_minion_log_prefix,
  562. daemon_cli_script_name=cli_minion_script_name,
  563. daemon_config=session_mm_minion_config,
  564. daemon_config_dir=session_mm_conf_dir,
  565. daemon_class=SaltMinion,
  566. bin_dir_path=_cli_bin_dir,
  567. fail_hard=_salt_fail_hard,
  568. event_listener_config_dir=session_mm_conf_dir,
  569. start_timeout=120)
  570. # <---- Sub Minion Fixtures ------------------------------------------------------------------------------------------
  571. @pytest.fixture(scope='session')
  572. def default_session_daemons(request,
  573. log_server,
  574. session_mm_salt_master,
  575. session_mm_secondary_salt_master,
  576. session_mm_salt_minion,
  577. session_mm_secondary_salt_minion,
  578. ):
  579. request.session.stats_processes.update(OrderedDict((
  580. ('Salt MM Master', psutil.Process(session_mm_salt_master.pid)),
  581. ('Salt MM Minion', psutil.Process(session_mm_salt_minion.pid)),
  582. ('Salt MM Sub Master', psutil.Process(session_mm_secondary_salt_master.pid)),
  583. ('Salt MM Sub Minion', psutil.Process(session_mm_secondary_salt_minion.pid)),
  584. )).items())
  585. # Run tests
  586. yield
  587. # Stop daemons now(they would be stopped at the end of the test run session
  588. for daemon in (session_mm_secondary_salt_minion,
  589. session_mm_secondary_salt_master,
  590. session_mm_salt_minion,
  591. session_mm_salt_master
  592. ):
  593. try:
  594. daemon.terminate()
  595. except Exception as exc: # pylint: disable=broad-except
  596. log.warning('Failed to terminate daemon: %s', daemon.__class__.__name__)
  597. @pytest.fixture(scope='session', autouse=True)
  598. def mm_bridge_pytest_and_runtests(reap_stray_processes,
  599. session_mm_conf_dir,
  600. session_mm_secondary_conf_dir,
  601. session_base_env_pillar_tree_root_dir,
  602. session_base_env_state_tree_root_dir,
  603. session_prod_env_state_tree_root_dir,
  604. session_mm_master_config,
  605. session_mm_minion_config,
  606. session_mm_secondary_master_config,
  607. session_mm_secondary_minion_config,
  608. default_session_daemons):
  609. # Make sure unittest2 classes know their paths
  610. RUNTIME_VARS.TMP_MM_CONF_DIR = session_mm_conf_dir.realpath().strpath
  611. RUNTIME_VARS.TMP_MM_SUB_CONF_DIR = session_mm_secondary_conf_dir.realpath().strpath
  612. RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR = session_mm_secondary_conf_dir.realpath().strpath
  613. RUNTIME_VARS.TMP_PILLAR_TREE = session_base_env_pillar_tree_root_dir.realpath().strpath
  614. RUNTIME_VARS.TMP_STATE_TREE = session_base_env_state_tree_root_dir.realpath().strpath
  615. RUNTIME_VARS.TMP_PRODENV_STATE_TREE = session_prod_env_state_tree_root_dir.realpath().strpath
  616. # Make sure unittest2 uses the pytest generated configuration
  617. RUNTIME_VARS.RUNTIME_CONFIGS['mm_master'] = freeze(session_mm_master_config)
  618. RUNTIME_VARS.RUNTIME_CONFIGS['mm_minion'] = freeze(session_mm_minion_config)
  619. RUNTIME_VARS.RUNTIME_CONFIGS['mm_sub_master'] = freeze(session_mm_secondary_master_config)
  620. RUNTIME_VARS.RUNTIME_CONFIGS['mm_sub_minion'] = freeze(session_mm_secondary_minion_config)