def _auth_client_module(request, uwsgi=False): import sirepo.srunit from pykern.pkcollections import PKDict cfg = PKDict( SIREPO_AUTH_BASIC_PASSWORD='******', SIREPO_AUTH_BASIC_UID='dev-no-validate', SIREPO_SMTP_FROM_EMAIL='x', SIREPO_SMTP_FROM_NAME='x', SIREPO_SMTP_PASSWORD='******', SIREPO_SMTP_SERVER='dev', SIREPO_SMTP_USER='******', SIREPO_AUTH_GITHUB_CALLBACK_URI='/uri', SIREPO_AUTH_GITHUB_KEY='key', SIREPO_AUTH_GITHUB_SECRET='secret', SIREPO_AUTH_GUEST_EXPIRY_DAYS='1', SIREPO_AUTH_METHODS='basic:email:guest', SIREPO_FEATURE_CONFIG_API_MODULES='status', ) if 'email3_test' in str(request.fspath.purebasename): cfg.SIREPO_AUTH_METHODS += ':github' else: cfg.SIREPO_AUTH_DEPRECATED_METHODS = 'github' from pykern import pkconfig pkconfig.reset_state_for_testing(cfg) with _subprocess_start(request, cfg=cfg, uwsgi=uwsgi) as c: yield c
def test_main3(): """Verify underscores are converted to dashes""" pkconfig.reset_state_for_testing() assert 0 == _main('p3', ['some-mod', 'some-func']), \ 'some-mod some-func: dashed module and function should work' assert 0 == _main('p3', ['some_mod', 'some_func']), \ 'some_mod some-func: underscored module and function should work'
def test_auth_hash_copy(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_FEATURE_CONFIG_API_MODULES': 'bluesky', 'SIREPO_BLUESKY_AUTH_SECRET': 'anything', }) from pykern import pkcollections from pykern.pkunit import pkeq from sirepo import bluesky import base64 import hashlib import numconv import random import time req = dict( simulationType='xyz', simulationId='1234', ) r = random.SystemRandom() req['authNonce'] = str(int(time.time())) + '-' + ''.join( r.choice(numconv.BASE62) for x in range(32) ) h = hashlib.sha256() h.update( ':'.join([ req['authNonce'], req['simulationType'], req['simulationId'], bluesky.cfg.auth_secret, ]), ) req['authHash'] = 'v1:' + base64.urlsafe_b64encode(h.digest()) bluesky.auth_hash(pkcollections.Dict(req), verify=True)
def flask_client(cfg=None, sim_types=None): """Return FlaskClient with easy access methods. Creates a new run directory every test file so can assume sharing of state on the server within a file (module). Two methods of interest: `sr_post` and `sr_get`. Args: cfg (dict): extra configuration for reset_state_for_testing sim_types (str): value for SIREPO_FEATURE_CONFIG_SIM_TYPES Returns: FlaskClient: for local requests to Flask server """ global server, app a = 'srunit_flask_client' if not cfg: cfg = {} if sim_types: cfg['SIREPO_FEATURE_CONFIG_SIM_TYPES'] = sim_types wd = pkunit.work_dir() cfg['SIREPO_SRDB_ROOT'] = str(pkio.mkdir_parent(wd.join('db'))) if not (server and hasattr(app, a)): with pkio.save_chdir(wd): pkconfig.reset_state_for_testing(cfg) from sirepo import server as s server = s app = server.init() app.config['TESTING'] = True app.test_client_class = _TestClient setattr(app, a, app.test_client()) return getattr(app, a)
def test_auth_hash(monkeypatch): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_AUTH_METHODS': 'bluesky', 'SIREPO_AUTH_BLUESKY_SECRET': 'a simple string is fine', 'SIREPO_FEATURE_CONFIG_SIM_TYPES': 'srw:myapp', }) from sirepo.auth import bluesky from pykern import pkcollections from pykern.pkunit import pkexcept, pkre import time import werkzeug.exceptions bluesky.init_apis() monkeypatch.setattr(bluesky, '_AUTH_NONCE_REPLAY_SECS', 1) req = pkcollections.Dict( simulationType='xyz', simulationId='1234', ) bluesky.auth_hash(req) bluesky.auth_hash(req, verify=True) time.sleep(2) with pkexcept(werkzeug.exceptions.Unauthorized): bluesky.auth_hash(req, verify=True)
def flask_client(cfg=None): """Return FlaskClient with easy access methods. Creates a new run directory every test file so can assume sharing of state on the server within a file (module). Two methods of interest: `sr_post` and `sr_get`. Args: cfg (dict): extra configuration for reset_state_for_testing Returns: FlaskClient: for local requests to Flask server """ global server a = 'srunit_flask_client' if not cfg: cfg = {} wd = pkunit.work_dir() cfg['SIREPO_SERVER_DB_DIR'] = str(pkio.mkdir_parent(wd.join('db'))) if not (server and hasattr(server.app, a)): with pkio.save_chdir(wd): pkconfig.reset_state_for_testing(cfg) from sirepo import server as s server = s server.app.config['TESTING'] = True server.app.test_client_class = _TestClient server.init() setattr(server.app, a, server.app.test_client()) return getattr(server.app, a)
def test_auth_hash_copy(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_BLUESKY_AUTH_SECRET': 'anything', }) from pykern import pkcollections from pykern.pkunit import pkeq from sirepo import bluesky import base64 import hashlib import numconv import random import time req = pkcollections.Dict( simulationType='xyz', simulationId='1234', ) r = random.SystemRandom() req['authNonce'] = str(int(time.time())) + '-' + ''.join( r.choice(numconv.BASE62) for x in range(32)) h = hashlib.sha256() h.update( ':'.join([ req['authNonce'], req['simulationType'], req['simulationId'], bluesky.cfg.auth_secret, ]), ) req['authHash'] = 'v1:' + base64.urlsafe_b64encode(h.digest()) bluesky.auth_hash(req, verify=True)
def test_main1(): """Verify basic modes work""" for rp in _PKGS: pkconfig.reset_state_for_testing() _conf(rp, ['conf1', 'cmd1', '1']) _conf(rp, ['conf1', 'cmd2'], first_time=False) _conf(rp, ['conf2', 'cmd1', '2']) _conf(rp, ['conf3', '3'], default_command=True)
def res(cfg=None, env=None): # Can't import anything yet data_dir = py.path.local(__file__).dirpath('pkconfig_data') for k, v in (env or {}).items(): monkeypatch.setenv(k, v) if data_dir not in sys.path: sys.path.insert(0, str(data_dir)) from pykern import pkconfig pkconfig.reset_state_for_testing(add_to_environ=cfg) return pkconfig
def test_main1(): """Verify basic modes work""" from pykern import pkconfig pkconfig.reset_state_for_testing() rp = 'p1' _conf(rp, ['conf1', 'cmd1', '1']) _conf(rp, ['conf1', 'cmd2'], first_time=False) _conf(rp, ['conf2', 'cmd1', '2']) _conf(rp, ['conf3', '3'], default_command=True)
def test_main2(capsys): all_modules = r':\nconf1\nconf2\nconf3\n$' for rp in _PKGS: pkconfig.reset_state_for_testing() _dev(rp, [], None, all_modules, capsys) _dev(rp, ['--help'], None, all_modules, capsys) _dev(rp, ['conf1'], SystemExit, r'cmd1,cmd2.*too few', capsys) _dev(rp, ['conf1', '-h'], SystemExit, r'\{cmd1,cmd2\}.*positional arguments', capsys) _dev(rp,['not_found'], None, r'no module', capsys) _dev(rp, ['conf2', 'not-cmd1'], SystemExit, r'\{cmd1\}', capsys)
def test_main2(capsys): all_modules = r':\nconf1\nconf2\nconf3\n$' for rp in _PKGS: pkconfig.reset_state_for_testing() _dev(rp, [], None, all_modules, capsys) _dev(rp, ['--help'], None, all_modules, capsys) _dev(rp, ['conf1'], SystemExit, r'cmd1,cmd2.*too few', capsys) _dev(rp, ['conf1', '-h'], SystemExit, r'\{cmd1,cmd2\}.*positional arguments', capsys) _dev(rp, ['not_found'], None, r'no module', capsys) _dev(rp, ['conf2', 'not-cmd1'], SystemExit, r'\{cmd1\}', capsys)
def _setup(monkeypatch): # Can't import anything yet global pkconfig data_dir = py.path.local(__file__).dirpath('pkconfig_data') home = str(data_dir) monkeypatch.setenv('HOME', home) monkeypatch.setenv('PYKERN_PKCONFIG_CHANNEL', _CHANNEL) sys.path.insert(0, str(data_dir)) from pykern import pkconfig pkconfig.reset_state_for_testing() return home
def test_command_error(capsys): from pykern import pkcli from pykern import pkconfig pkconfig.reset_state_for_testing() with pytest.raises(pkcli.CommandError) as e: pkcli.command_error('{abc}', abc='abcdef') assert 'abcdef' in str(e.value), \ 'When passed a format, command_error should output formatted result' _dev('p2', ['some-mod', 'command-error'], None, r'raising CommandError', capsys)
def test_backup(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'PYKERN_PKCLI_GITHUB_TEST_MODE': '1', 'PYKERN_PKCLI_GITHUB_API_PAUSE_SECONDS': '0', }) from pykern.pkcli import github from pykern import pkunit from pykern import pkio with pkunit.save_chdir_work(): github.backup() github.backup()
def test_auth_hash(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_BLUESKY_AUTH_SECRET': 'a simple string is fine', }) from sirepo import bluesky from pykern import pkcollections from pykern.pkunit import pkeq req = pkcollections.Dict( simulationType='xyz', simulationId='1234', authNonce='some random string', ) bluesky.auth_hash(req) pkeq('v1:-TEGBNOAt9dCTtCCvRD0WHtL_XaZR_lHM37cy6PePwE=', req.authHash)
def flask_client(cfg=None, sim_types=None, job_run_mode=None): """Return FlaskClient with easy access methods. Creates a new run directory every test file so can assume sharing of state on the server within a file (module). Two methods of interest: `sr_post` and `sr_get`. Args: cfg (dict): extra configuration for reset_state_for_testing sim_types (str): value for SIREPO_FEATURE_CONFIG_SIM_TYPES [CONFTEST_DEFAULT_CODES] Returns: FlaskClient: for local requests to Flask server """ global server, app a = 'srunit_flask_client' if not cfg: cfg = PKDict() t = sim_types or CONFTEST_DEFAULT_CODES if t: if isinstance(t, (tuple, list)): t = ':'.join(t) cfg['SIREPO_FEATURE_CONFIG_SIM_TYPES'] = t if not (server and hasattr(app, a)): from pykern import pkconfig # initialize pkdebug with correct values pkconfig.reset_state_for_testing(cfg) from pykern import pkunit with pkunit.save_chdir_work() as wd: from pykern import pkio setup_srdb_root(cfg=cfg) pkconfig.reset_state_for_testing(cfg) from sirepo import server as s server = s app = server.init(is_server=True) app.config['TESTING'] = True app.test_client_class = _TestClient setattr(app, a, app.test_client(job_run_mode=job_run_mode)) return getattr(app, a)
def test_srw_auth_hash_copy(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_AUTH_BLUESKY_SECRET': 'anything', 'SIREPO_AUTH_METHODS': 'bluesky', 'SIREPO_FEATURE_CONFIG_SIM_TYPES': 'srw:myapp', }) from pykern import pkcollections from pykern import pkcompat from pykern.pkdebug import pkdp from pykern.pkunit import pkeq from sirepo.auth import bluesky import base64 import hashlib import numconv import random import time bluesky.init_apis() req = dict( simulationType='xyz', simulationId='1234', ) r = random.SystemRandom() req['authNonce'] = str(int(time.time())) + '-' + ''.join( r.choice(numconv.BASE62) for x in range(32) ) h = hashlib.sha256() h.update( pkcompat.to_bytes( ':'.join([ req['authNonce'], req['simulationType'], req['simulationId'], bluesky.cfg.secret, ]), ), ) req['authHash'] = 'v1:' + pkcompat.from_bytes( base64.urlsafe_b64encode(h.digest()), ) bluesky.auth_hash(pkcollections.Dict(req), verify=True)
def test_oauth(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_SERVER_OAUTH_LOGIN': '******', 'SIREPO_OAUTH_GITHUB_KEY': 'n/a', 'SIREPO_OAUTH_GITHUB_SECRET': 'n/a', 'SIREPO_OAUTH_GITHUB_CALLBACK_URI': 'n/a', }) from pykern.pkunit import pkfail, pkok from sirepo import server from sirepo import sr_unit import re sim_type = 'srw' fc = sr_unit.flask_client() fc.sr_post('listSimulations', {'simulationType': sim_type}) text = fc.sr_get( 'oauthLogin', { 'simulation_type': sim_type, 'oauth_type': 'github', }, raw_response=True, ).data state = re.search(r'state=(.*?)"', text).group(1) #TODO(pjm): causes a forbidden error due to missing variables, need to mock-up an oauth test type text = fc.get('/oauth-authorized/github') text = fc.sr_get( 'oauthLogout', { 'simulation_type': sim_type, }, raw_response=True, ).data pkok( text.find('Redirecting') > 0, 'missing redirect', ) pkok( text.find('"/{}"'.format(sim_type)) > 0, 'missing redirect target', )
def test_auth_hash(monkeypatch): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_BLUESKY_AUTH_SECRET': 'a simple string is fine', }) from sirepo import bluesky from pykern import pkcollections from pykern.pkunit import pkexcept, pkre import time import werkzeug.exceptions monkeypatch.setattr(bluesky, '_AUTH_NONCE_REPLAY_SECS', 1) req = pkcollections.Dict( simulationType='xyz', simulationId='1234', ) bluesky.auth_hash(req) bluesky.auth_hash(req, verify=True) time.sleep(2) with pkexcept(werkzeug.exceptions.NotFound): bluesky.auth_hash(req, verify=True)
def test_auth_hash(monkeypatch): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'SIREPO_FEATURE_CONFIG_API_MODULES': 'bluesky', 'SIREPO_BLUESKY_AUTH_SECRET': 'a simple string is fine', }) from sirepo import bluesky from pykern import pkcollections from pykern.pkunit import pkexcept, pkre import time import werkzeug.exceptions monkeypatch.setattr(bluesky, '_AUTH_NONCE_REPLAY_SECS', 1) req = pkcollections.Dict( simulationType='xyz', simulationId='1234', ) bluesky.auth_hash(req) bluesky.auth_hash(req, verify=True) time.sleep(2) with pkexcept(werkzeug.exceptions.NotFound): bluesky.auth_hash(req, verify=True)
def auth_fc_module(request): import sirepo.srunit from pykern.pkcollections import PKDict cfg = PKDict( SIREPO_AUTH_BASIC_PASSWORD='******', SIREPO_AUTH_BASIC_UID='dev-no-validate', SIREPO_AUTH_EMAIL_FROM_EMAIL='x', SIREPO_AUTH_EMAIL_FROM_NAME='x', SIREPO_AUTH_EMAIL_SMTP_PASSWORD='******', SIREPO_AUTH_EMAIL_SMTP_SERVER='dev', SIREPO_AUTH_EMAIL_SMTP_USER='******', SIREPO_AUTH_GITHUB_CALLBACK_URI='/uri', SIREPO_AUTH_GITHUB_KEY='key', SIREPO_AUTH_GITHUB_SECRET='secret', SIREPO_AUTH_GUEST_EXPIRY_DAYS='1', SIREPO_AUTH_METHODS='basic:email:guest', SIREPO_FEATURE_CONFIG_API_MODULES='status', ) if 'email3_test' in str(request.fspath): cfg.SIREPO_AUTH_METHODS += ':github' else: cfg.SIREPO_AUTH_DEPRECATED_METHODS = 'github' from pykern import pkconfig pkconfig.reset_state_for_testing(cfg) from pykern import pkunit from pykern import pkio cfg['SIREPO_SRDB_ROOT'] = str( pkio.mkdir_parent(pkunit.work_dir().join('db'))) p, fc = _job_supervisor_start(request, cfg=cfg) if p: yield fc p.terminate() p.wait() else: yield sirepo.srunit.flask_client(cfg=cfg)
def test_pkdformat(): from pykern import pkconfig pkconfig.reset_state_for_testing({ 'PYKERN_PKDEBUG_MAX_DEPTH': '2', 'PYKERN_PKDEBUG_MAX_ELEMENTS': '5', 'PYKERN_PKDEBUG_MAX_STRING': '5', }) from pykern.pkdebug import pkdformat from pykern.pkunit import pkeq def _e(expected, value): pkeq(expected, pkdformat('{}', value)) _e( "{'a': 'b', 'c': {'d': {<SNIP>}}, 'h': 'i'}", { 'a': 'b', 'c': { 'd': { 'e': { 'f': 'g' } } }, 'h': 'i' }, ) _e( '{1}', set([1]), ) _e( '(1, 2, 3, 4, 5)', (1, 2, 3, 4, 5), ) _e( '[1, 2, 3, 4, 5, <SNIP>]', [1, 2, 3, 4, 5, 6], ) _e( '(1, 2, 3, 4)', (1, 2, 3, 4), ) _e("(1, {2, 3}, {'passw<SNIP>': <REDACTED>}, [6, 7])", (1, {2, 3}, { 'password': 5 }, [6, 7])) _e( "{'Secre<SNIP>': <REDACTED>, 'c2': {'botp': <REDACTED>}, 'q3': ['passw<SNIP>', 1], 's4': 'r', 't5': 'u', <SNIP>}", { 'Secret1': 'b', 'c2': { 'botp': 'a' }, 'totp7': 'iiii', 'q3': ['password', 1], 'x6': 'y', 's4': 'r', 't5': 'u' }, ) _e('a' * 5 + '<SNIP>', 'a' * 80) _e('<SNIP>' + 'a' * 5, '\n File "' + 'a' * 80) class T(): def pkdebug_str(self): return 'foo' _e('foo', T())