mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-04 21:18:11 +08:00
Add a function to check the configuration for errors. (#1919)
This can be used as a sanity check before a deployment: chanzuckerberg/single-cell#63
This commit is contained in:
@@ -114,7 +114,7 @@ class ServerConfig(BaseConfig):
|
|||||||
self.validate_correct_type_of_configuration_attribute("app__port", (type(None), int))
|
self.validate_correct_type_of_configuration_attribute("app__port", (type(None), int))
|
||||||
self.validate_correct_type_of_configuration_attribute("app__open_browser", bool)
|
self.validate_correct_type_of_configuration_attribute("app__open_browser", bool)
|
||||||
self.validate_correct_type_of_configuration_attribute("app__force_https", bool)
|
self.validate_correct_type_of_configuration_attribute("app__force_https", bool)
|
||||||
self.validate_correct_type_of_configuration_attribute("app__flask_secret_key", (type(None), str))
|
self.validate_correct_type_of_configuration_attribute("app__flask_secret_key", str)
|
||||||
self.validate_correct_type_of_configuration_attribute("app__generate_cache_control_headers", bool)
|
self.validate_correct_type_of_configuration_attribute("app__generate_cache_control_headers", bool)
|
||||||
self.validate_correct_type_of_configuration_attribute("app__server_timing_headers", bool)
|
self.validate_correct_type_of_configuration_attribute("app__server_timing_headers", bool)
|
||||||
self.validate_correct_type_of_configuration_attribute("app__csp_directives", (type(None), dict))
|
self.validate_correct_type_of_configuration_attribute("app__csp_directives", (type(None), dict))
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from server.common.config.app_config import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser("A script to check hosted configuration files")
|
||||||
|
parser.add_argument("config_file", help="the configuration file")
|
||||||
|
parser.add_argument(
|
||||||
|
"-s",
|
||||||
|
"--show",
|
||||||
|
default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="print the configuration. NOTE: this may print secret values to stdout",
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
app_config = AppConfig()
|
||||||
|
app_config.update_from_config_file(args.config_file)
|
||||||
|
try:
|
||||||
|
app_config.complete_config()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {str(e)}")
|
||||||
|
print("FAIL:", args.config_file)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if args.show:
|
||||||
|
yaml_config = app_config.config_to_dict()
|
||||||
|
yaml.dump(yaml_config, sys.stdout)
|
||||||
|
|
||||||
|
print("PASS:", args.config_file)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -34,7 +34,7 @@ def data_with_tmp_tiledb_annotations(ext: MatrixDataType):
|
|||||||
data_locator = DataLocator(fname)
|
data_locator = DataLocator(fname)
|
||||||
config = AppConfig()
|
config = AppConfig()
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
multi_dataset__dataroot=data_locator.path, authentication__type="test",
|
app__flask_secret_key="secret", multi_dataset__dataroot=data_locator.path, authentication__type="test",
|
||||||
)
|
)
|
||||||
config.update_default_dataset_config(
|
config.update_default_dataset_config(
|
||||||
embeddings__names=["umap"],
|
embeddings__names=["umap"],
|
||||||
@@ -64,7 +64,10 @@ def data_with_tmp_annotations(ext: MatrixDataType, annotations_fixture=False):
|
|||||||
data_locator = DataLocator(fname)
|
data_locator = DataLocator(fname)
|
||||||
config = AppConfig()
|
config = AppConfig()
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
single_dataset__obs_names=None, single_dataset__var_names=None, single_dataset__datapath=data_locator.path
|
app__flask_secret_key="secret",
|
||||||
|
single_dataset__obs_names=None,
|
||||||
|
single_dataset__var_names=None,
|
||||||
|
single_dataset__datapath=data_locator.path,
|
||||||
)
|
)
|
||||||
config.update_default_dataset_config(
|
config.update_default_dataset_config(
|
||||||
embeddings__names=["umap"], presentation__max_categories=100, diffexp__lfc_cutoff=0.01,
|
embeddings__names=["umap"], presentation__max_categories=100, diffexp__lfc_cutoff=0.01,
|
||||||
@@ -97,6 +100,7 @@ def skip_if(condition, reason: str):
|
|||||||
def app_config(data_locator, backed=False, extra_server_config={}, extra_dataset_config={}):
|
def app_config(data_locator, backed=False, extra_server_config={}, extra_dataset_config={}):
|
||||||
config = AppConfig()
|
config = AppConfig()
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
|
app__flask_secret_key="secret",
|
||||||
single_dataset__obs_names=None,
|
single_dataset__obs_names=None,
|
||||||
single_dataset__var_names=None,
|
single_dataset__var_names=None,
|
||||||
adaptor__anndata_adaptor__backed=backed,
|
adaptor__anndata_adaptor__backed=backed,
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ class AuthTest(unittest.TestCase):
|
|||||||
self.dataset_dataroot = FIXTURES_ROOT
|
self.dataset_dataroot = FIXTURES_ROOT
|
||||||
|
|
||||||
def test_auth_none(self):
|
def test_auth_none(self):
|
||||||
c = AppConfig()
|
app_config = AppConfig()
|
||||||
c.update_server_config(authentication__type=None, multi_dataset__dataroot=self.dataset_dataroot)
|
app_config.update_server_config(app__flask_secret_key="secret")
|
||||||
c.update_default_dataset_config(user_annotations__enable=False)
|
app_config.update_server_config(authentication__type=None, multi_dataset__dataroot=self.dataset_dataroot)
|
||||||
|
app_config.update_default_dataset_config(user_annotations__enable=False)
|
||||||
|
|
||||||
c.complete_config()
|
app_config.complete_config()
|
||||||
|
|
||||||
with test_server(app_config=c) as server:
|
with test_server(app_config=app_config) as server:
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
config = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config").json()
|
config = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config").json()
|
||||||
userinfo = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/userinfo").json()
|
userinfo = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/userinfo").json()
|
||||||
@@ -25,12 +26,13 @@ class AuthTest(unittest.TestCase):
|
|||||||
self.assertIsNone(userinfo)
|
self.assertIsNone(userinfo)
|
||||||
|
|
||||||
def test_auth_session(self):
|
def test_auth_session(self):
|
||||||
c = AppConfig()
|
app_config = AppConfig()
|
||||||
c.update_server_config(authentication__type="session", multi_dataset__dataroot=self.dataset_dataroot)
|
app_config.update_server_config(app__flask_secret_key="secret")
|
||||||
c.update_default_dataset_config(user_annotations__enable=True)
|
app_config.update_server_config(authentication__type="session", multi_dataset__dataroot=self.dataset_dataroot)
|
||||||
c.complete_config()
|
app_config.update_default_dataset_config(user_annotations__enable=True)
|
||||||
|
app_config.complete_config()
|
||||||
|
|
||||||
with test_server(app_config=c) as server:
|
with test_server(app_config=app_config) as server:
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
config = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config").json()
|
config = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config").json()
|
||||||
userinfo = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/userinfo").json()
|
userinfo = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/userinfo").json()
|
||||||
@@ -40,9 +42,10 @@ class AuthTest(unittest.TestCase):
|
|||||||
self.assertEqual(userinfo["userinfo"]["username"], "anonymous")
|
self.assertEqual(userinfo["userinfo"]["username"], "anonymous")
|
||||||
|
|
||||||
def test_auth_test(self):
|
def test_auth_test(self):
|
||||||
c = AppConfig()
|
app_config = AppConfig()
|
||||||
c.update_server_config(authentication__type="test")
|
app_config.update_server_config(app__flask_secret_key="secret")
|
||||||
c.update_server_config(
|
app_config.update_server_config(authentication__type="test")
|
||||||
|
app_config.update_server_config(
|
||||||
multi_dataset__dataroot=dict(
|
multi_dataset__dataroot=dict(
|
||||||
a1=dict(dataroot=self.dataset_dataroot, base_url="auth"),
|
a1=dict(dataroot=self.dataset_dataroot, base_url="auth"),
|
||||||
a2=dict(dataroot=self.dataset_dataroot, base_url="no-auth"),
|
a2=dict(dataroot=self.dataset_dataroot, base_url="no-auth"),
|
||||||
@@ -50,12 +53,12 @@ class AuthTest(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# specialize the configs
|
# specialize the configs
|
||||||
c.add_dataroot_config("a1", app__authentication_enable=True, user_annotations__enable=True)
|
app_config.add_dataroot_config("a1", app__authentication_enable=True, user_annotations__enable=True)
|
||||||
c.add_dataroot_config("a2", app__authentication_enable=False, user_annotations__enable=False)
|
app_config.add_dataroot_config("a2", app__authentication_enable=False, user_annotations__enable=False)
|
||||||
|
|
||||||
c.complete_config()
|
app_config.complete_config()
|
||||||
|
|
||||||
with test_server(app_config=c) as server:
|
with test_server(app_config=app_config) as server:
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
|
|
||||||
# auth datasets
|
# auth datasets
|
||||||
@@ -102,20 +105,21 @@ class AuthTest(unittest.TestCase):
|
|||||||
self.assertFalse(config["config"]["parameters"]["annotations"])
|
self.assertFalse(config["config"]["parameters"]["annotations"])
|
||||||
|
|
||||||
# login with a picture
|
# login with a picture
|
||||||
r = session.get(f"{server}/{login_uri}&picture=myimage.png")
|
session.get(f"{server}/{login_uri}&picture=myimage.png")
|
||||||
userinfo = session.get(f"{server}/auth/pbmc3k.cxg/api/v0.2/userinfo").json()
|
userinfo = session.get(f"{server}/auth/pbmc3k.cxg/api/v0.2/userinfo").json()
|
||||||
self.assertTrue(userinfo["userinfo"]["is_authenticated"])
|
self.assertTrue(userinfo["userinfo"]["is_authenticated"])
|
||||||
self.assertEqual(userinfo["userinfo"]["picture"], "myimage.png")
|
self.assertEqual(userinfo["userinfo"]["picture"], "myimage.png")
|
||||||
|
|
||||||
def test_auth_test_single(self):
|
def test_auth_test_single(self):
|
||||||
c = AppConfig()
|
app_config = AppConfig()
|
||||||
c.update_server_config(
|
app_config.update_server_config(app__flask_secret_key="secret")
|
||||||
|
app_config.update_server_config(
|
||||||
authentication__type="test", single_dataset__datapath=f"{self.dataset_dataroot}/pbmc3k.cxg"
|
authentication__type="test", single_dataset__datapath=f"{self.dataset_dataroot}/pbmc3k.cxg"
|
||||||
)
|
)
|
||||||
|
|
||||||
c.complete_config()
|
app_config.complete_config()
|
||||||
|
|
||||||
with test_server(app_config=c) as server:
|
with test_server(app_config=app_config) as server:
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
config = session.get(f"{server}/api/v0.2/config").json()
|
config = session.get(f"{server}/api/v0.2/config").json()
|
||||||
userinfo = session.get(f"{server}/api/v0.2/userinfo").json()
|
userinfo = session.get(f"{server}/api/v0.2/userinfo").json()
|
||||||
@@ -130,10 +134,10 @@ class AuthTest(unittest.TestCase):
|
|||||||
self.assertEqual(login_uri, "/login")
|
self.assertEqual(login_uri, "/login")
|
||||||
self.assertEqual(logout_uri, "/logout")
|
self.assertEqual(logout_uri, "/logout")
|
||||||
|
|
||||||
r = session.get(f"{server}/{login_uri}")
|
response = session.get(f"{server}/{login_uri}")
|
||||||
# check that the login redirect worked
|
# check that the login redirect worked
|
||||||
self.assertEqual(r.history[0].status_code, 302)
|
self.assertEqual(response.history[0].status_code, 302)
|
||||||
self.assertEqual(r.url, f"{server}/")
|
self.assertEqual(response.url, f"{server}/")
|
||||||
|
|
||||||
config = session.get(f"{server}/api/v0.2/config").json()
|
config = session.get(f"{server}/api/v0.2/config").json()
|
||||||
userinfo = session.get(f"{server}/api/v0.2/userinfo").json()
|
userinfo = session.get(f"{server}/api/v0.2/userinfo").json()
|
||||||
@@ -141,10 +145,10 @@ class AuthTest(unittest.TestCase):
|
|||||||
self.assertEqual(userinfo["userinfo"]["username"], "test_account")
|
self.assertEqual(userinfo["userinfo"]["username"], "test_account")
|
||||||
self.assertTrue(config["config"]["parameters"]["annotations"])
|
self.assertTrue(config["config"]["parameters"]["annotations"])
|
||||||
|
|
||||||
r = session.get(f"{server}/{logout_uri}")
|
response = session.get(f"{server}/{logout_uri}")
|
||||||
# check that the logout redirect worked
|
# check that the logout redirect worked
|
||||||
self.assertEqual(r.history[0].status_code, 302)
|
self.assertEqual(response.history[0].status_code, 302)
|
||||||
self.assertEqual(r.url, f"{server}/")
|
self.assertEqual(response.url, f"{server}/")
|
||||||
config = session.get(f"{server}/api/v0.2/config").json()
|
config = session.get(f"{server}/api/v0.2/config").json()
|
||||||
userinfo = session.get(f"{server}/api/v0.2/userinfo").json()
|
userinfo = session.get(f"{server}/api/v0.2/userinfo").json()
|
||||||
self.assertFalse(userinfo["userinfo"]["is_authenticated"])
|
self.assertFalse(userinfo["userinfo"]["is_authenticated"])
|
||||||
|
|||||||
@@ -160,12 +160,14 @@ class AuthTest(unittest.TestCase):
|
|||||||
def test_auth_oauth_session(self):
|
def test_auth_oauth_session(self):
|
||||||
# test with session cookies
|
# test with session cookies
|
||||||
app_config = AppConfig()
|
app_config = AppConfig()
|
||||||
|
app_config.update_server_config(app__flask_secret_key="secret")
|
||||||
app_config.update_server_config(authentication__params_oauth__session_cookie=True,)
|
app_config.update_server_config(authentication__params_oauth__session_cookie=True,)
|
||||||
self.auth_flow(app_config)
|
self.auth_flow(app_config)
|
||||||
|
|
||||||
def test_auth_oauth_cookie(self):
|
def test_auth_oauth_cookie(self):
|
||||||
# test with specified cookie
|
# test with specified cookie
|
||||||
app_config = AppConfig()
|
app_config = AppConfig()
|
||||||
|
app_config.update_server_config(app__flask_secret_key="secret")
|
||||||
app_config.update_server_config(
|
app_config.update_server_config(
|
||||||
authentication__params_oauth__session_cookie=False,
|
authentication__params_oauth__session_cookie=False,
|
||||||
authentication__params_oauth__cookie=dict(key="test_cxguser", httponly=True, max_age=60),
|
authentication__params_oauth__cookie=dict(key="test_cxguser", httponly=True, max_age=60),
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class ConfigTests(unittest.TestCase):
|
|||||||
port="null",
|
port="null",
|
||||||
open_browser="false",
|
open_browser="false",
|
||||||
force_https="false",
|
force_https="false",
|
||||||
flask_secret_key="null",
|
flask_secret_key="secret",
|
||||||
generate_cache_control_headers="false",
|
generate_cache_control_headers="false",
|
||||||
server_timing_headers="false",
|
server_timing_headers="false",
|
||||||
csp_directives="null",
|
csp_directives="null",
|
||||||
@@ -82,7 +82,7 @@ class ConfigTests(unittest.TestCase):
|
|||||||
port="null",
|
port="null",
|
||||||
open_browser="false",
|
open_browser="false",
|
||||||
force_https="false",
|
force_https="false",
|
||||||
flask_secret_key="null",
|
flask_secret_key="secret",
|
||||||
generate_cache_control_headers="false",
|
generate_cache_control_headers="false",
|
||||||
server_timing_headers="false",
|
server_timing_headers="false",
|
||||||
csp_directives="null",
|
csp_directives="null",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class AppConfigTest(ConfigTests):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
||||||
self.config = AppConfig()
|
self.config = AppConfig()
|
||||||
|
self.config.update_server_config(app__flask_secret_key="secret")
|
||||||
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
||||||
self.server_config = self.config.server_config
|
self.server_config = self.config.server_config
|
||||||
self.config.complete_config()
|
self.config.complete_config()
|
||||||
@@ -106,6 +107,8 @@ class AppConfigTest(ConfigTests):
|
|||||||
with open(configfile, "w") as fconfig:
|
with open(configfile, "w") as fconfig:
|
||||||
config = """
|
config = """
|
||||||
server:
|
server:
|
||||||
|
app:
|
||||||
|
flask_secret_key: secret
|
||||||
multi_dataset:
|
multi_dataset:
|
||||||
dataroot: test_dataroot
|
dataroot: test_dataroot
|
||||||
|
|
||||||
@@ -116,7 +119,10 @@ class AppConfigTest(ConfigTests):
|
|||||||
app_config.update_from_config_file(configfile)
|
app_config.update_from_config_file(configfile)
|
||||||
server_changes = app_config.server_config.changes_from_default()
|
server_changes = app_config.server_config.changes_from_default()
|
||||||
dataset_changes = app_config.default_dataset_config.changes_from_default()
|
dataset_changes = app_config.default_dataset_config.changes_from_default()
|
||||||
self.assertEqual(server_changes, [("multi_dataset__dataroot", "test_dataroot", None)])
|
self.assertEqual(
|
||||||
|
server_changes,
|
||||||
|
[("app__flask_secret_key", "secret", None), ("multi_dataset__dataroot", "test_dataroot", None)],
|
||||||
|
)
|
||||||
self.assertEqual(dataset_changes, [])
|
self.assertEqual(dataset_changes, [])
|
||||||
|
|
||||||
def test_configfile_no_server_section(self):
|
def test_configfile_no_server_section(self):
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class BaseConfigTest(ConfigTests):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
||||||
self.config = AppConfig()
|
self.config = AppConfig()
|
||||||
|
self.config.update_server_config(app__flask_secret_key="secret")
|
||||||
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
||||||
self.server_config = self.config.server_config
|
self.server_config = self.config.server_config
|
||||||
self.config.complete_config()
|
self.config.complete_config()
|
||||||
@@ -47,6 +48,7 @@ class BaseConfigTest(ConfigTests):
|
|||||||
server_changes,
|
server_changes,
|
||||||
[
|
[
|
||||||
("app__verbose", True, False),
|
("app__verbose", True, False),
|
||||||
|
("app__flask_secret_key", "secret", None),
|
||||||
("multi_dataset__dataroot", FIXTURES_ROOT, None),
|
("multi_dataset__dataroot", FIXTURES_ROOT, None),
|
||||||
("multi_dataset__matrix_cache__timelimit_s", 5, 30),
|
("multi_dataset__matrix_cache__timelimit_s", 5, 30),
|
||||||
("data_locator__s3__region_name", "us-east-1", True),
|
("data_locator__s3__region_name", "us-east-1", True),
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class TestDatasetConfig(ConfigTests):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
||||||
self.config = AppConfig()
|
self.config = AppConfig()
|
||||||
|
self.config.update_server_config(app__flask_secret_key="secret")
|
||||||
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
||||||
self.dataset_config = self.config.default_dataset_config
|
self.dataset_config = self.config.default_dataset_config
|
||||||
self.config.complete_config()
|
self.config.complete_config()
|
||||||
@@ -155,7 +156,8 @@ class TestDatasetConfig(ConfigTests):
|
|||||||
# test for illegal url_dataroots
|
# test for illegal url_dataroots
|
||||||
for illegal in ("../b", "!$*", "\\n", "", "(bad)"):
|
for illegal in ("../b", "!$*", "\\n", "", "(bad)"):
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
multi_dataset__dataroot={"tag": {"base_url": illegal, "dataroot": f"{PROJECT_ROOT}/example-dataset"}}
|
app__flask_secret_key="secret",
|
||||||
|
multi_dataset__dataroot={"tag": {"base_url": illegal, "dataroot": f"{PROJECT_ROOT}/example-dataset"}},
|
||||||
)
|
)
|
||||||
with self.assertRaises(ConfigurationError):
|
with self.assertRaises(ConfigurationError):
|
||||||
config.complete_config()
|
config.complete_config()
|
||||||
@@ -163,17 +165,19 @@ class TestDatasetConfig(ConfigTests):
|
|||||||
# test for legal url_dataroots
|
# test for legal url_dataroots
|
||||||
for legal in ("d", "this.is-okay_", "a/b"):
|
for legal in ("d", "this.is-okay_", "a/b"):
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
multi_dataset__dataroot={"tag": {"base_url": legal, "dataroot": f"{PROJECT_ROOT}/example-dataset"}}
|
app__flask_secret_key="secret",
|
||||||
|
multi_dataset__dataroot={"tag": {"base_url": legal, "dataroot": f"{PROJECT_ROOT}/example-dataset"}},
|
||||||
)
|
)
|
||||||
config.complete_config()
|
config.complete_config()
|
||||||
|
|
||||||
# test that multi dataroots work end to end
|
# test that multi dataroots work end to end
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
|
app__flask_secret_key="secret",
|
||||||
multi_dataset__dataroot=dict(
|
multi_dataset__dataroot=dict(
|
||||||
s1=dict(dataroot=f"{PROJECT_ROOT}/example-dataset", base_url="set1/1/2"),
|
s1=dict(dataroot=f"{PROJECT_ROOT}/example-dataset", base_url="set1/1/2"),
|
||||||
s2=dict(dataroot=f"{FIXTURES_ROOT}", base_url="set2"),
|
s2=dict(dataroot=f"{FIXTURES_ROOT}", base_url="set2"),
|
||||||
s3=dict(dataroot=f"{FIXTURES_ROOT}", base_url="set3"),
|
s3=dict(dataroot=f"{FIXTURES_ROOT}", base_url="set3"),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Change this default to test if the dataroot overrides below work.
|
# Change this default to test if the dataroot overrides below work.
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class TestServerConfig(ConfigTests):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
self.config_file_name = f"{unittest.TestCase.id(self).split('.')[-1]}.yml"
|
||||||
self.config = AppConfig()
|
self.config = AppConfig()
|
||||||
|
self.config.update_server_config(app__flask_secret_key="secret")
|
||||||
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
self.config.update_server_config(multi_dataset__dataroot=FIXTURES_ROOT)
|
||||||
self.server_config = self.config.server_config
|
self.server_config = self.config.server_config
|
||||||
self.config.complete_config()
|
self.config.complete_config()
|
||||||
@@ -103,6 +104,7 @@ class TestServerConfig(ConfigTests):
|
|||||||
# Note if the port is set in the config file it will NOT be overwritten by a different envvar
|
# Note if the port is set in the config file it will NOT be overwritten by a different envvar
|
||||||
os.environ["CXG_SERVER_PORT"] = "4008"
|
os.environ["CXG_SERVER_PORT"] = "4008"
|
||||||
self.config = AppConfig()
|
self.config = AppConfig()
|
||||||
|
self.config.update_server_config(app__flask_secret_key="secret")
|
||||||
self.config.server_config.handle_app(self.context)
|
self.config.server_config.handle_app(self.context)
|
||||||
self.assertEqual(self.config.server_config.app__port, 4008)
|
self.assertEqual(self.config.server_config.app__port, 4008)
|
||||||
del os.environ["CXG_SERVER_PORT"]
|
del os.environ["CXG_SERVER_PORT"]
|
||||||
@@ -152,6 +154,7 @@ class TestServerConfig(ConfigTests):
|
|||||||
config = AppConfig()
|
config = AppConfig()
|
||||||
backend_port = find_available_port("localhost", 10000)
|
backend_port = find_available_port("localhost", 10000)
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
|
app__flask_secret_key="secret",
|
||||||
app__api_base_url=f"http://localhost:{backend_port}/additional/path",
|
app__api_base_url=f"http://localhost:{backend_port}/additional/path",
|
||||||
multi_dataset__dataroot=f"{PROJECT_ROOT}/example-dataset",
|
multi_dataset__dataroot=f"{PROJECT_ROOT}/example-dataset",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from server.test import PROJECT_ROOT, FIXTURES_ROOT
|
|||||||
from server.common.config.app_config import AppConfig
|
from server.common.config.app_config import AppConfig
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import time
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@@ -34,12 +35,12 @@ class Elastic_Beanstalk_Test(unittest.TestCase):
|
|||||||
tempdir = tempfile.TemporaryDirectory(dir=f"{PROJECT_ROOT}/server")
|
tempdir = tempfile.TemporaryDirectory(dir=f"{PROJECT_ROOT}/server")
|
||||||
tempdirname = tempdir.name
|
tempdirname = tempdir.name
|
||||||
|
|
||||||
c = AppConfig()
|
config = AppConfig()
|
||||||
# test that eb works
|
# test that eb works
|
||||||
c.update_server_config(multi_dataset__dataroot=f"{FIXTURES_ROOT}", app__flask_secret_key="open sesame")
|
config.update_server_config(multi_dataset__dataroot=f"{FIXTURES_ROOT}", app__flask_secret_key="open sesame")
|
||||||
|
|
||||||
c.complete_config()
|
config.complete_config()
|
||||||
c.write_config(f"{tempdirname}/config.yaml")
|
config.write_config(f"{tempdirname}/config.yaml")
|
||||||
|
|
||||||
subprocess.check_call(f"git ls-files . | cpio -pdm {tempdirname}", cwd=f"{PROJECT_ROOT}/server/eb", shell=True)
|
subprocess.check_call(f"git ls-files . | cpio -pdm {tempdirname}", cwd=f"{PROJECT_ROOT}/server/eb", shell=True)
|
||||||
subprocess.check_call(["make", "build"], cwd=tempdirname)
|
subprocess.check_call(["make", "build"], cwd=tempdirname)
|
||||||
@@ -50,3 +51,33 @@ class Elastic_Beanstalk_Test(unittest.TestCase):
|
|||||||
r = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config")
|
r = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config")
|
||||||
data_config = r.json()
|
data_config = r.json()
|
||||||
assert data_config["config"]["displayNames"]["dataset"] == "pbmc3k"
|
assert data_config["config"]["displayNames"]["dataset"] == "pbmc3k"
|
||||||
|
|
||||||
|
def test_config(self):
|
||||||
|
check_config_script = os.path.join(PROJECT_ROOT, "server", "eb", "check_config.py")
|
||||||
|
with tempfile.TemporaryDirectory() as tempdir:
|
||||||
|
configfile = os.path.join(tempdir, "config.yaml")
|
||||||
|
app_config = AppConfig()
|
||||||
|
app_config.update_server_config(multi_dataset__dataroot=f"{FIXTURES_ROOT}")
|
||||||
|
app_config.write_config(configfile)
|
||||||
|
|
||||||
|
command = ["python", check_config_script, configfile]
|
||||||
|
|
||||||
|
# test failure mode (flask_secret_key not set)
|
||||||
|
env = os.environ.copy()
|
||||||
|
env.pop("CXG_SECRET_KEY", None)
|
||||||
|
with self.assertRaises(subprocess.CalledProcessError) as exception_context:
|
||||||
|
subprocess.check_output(command, env=env)
|
||||||
|
output = str(exception_context.exception.stdout, "utf-8")
|
||||||
|
self.assertTrue(
|
||||||
|
output.startswith(
|
||||||
|
"Error: Invalid type for attribute: app__flask_secret_key, expected type str, got NoneType"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(exception_context.exception.returncode, 1)
|
||||||
|
|
||||||
|
# test passing case
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["CXG_SECRET_KEY"] = "secret"
|
||||||
|
output = subprocess.check_output(command, env=env)
|
||||||
|
output = str(output, "utf-8")
|
||||||
|
self.assertTrue(output.startswith("PASS"))
|
||||||
|
|||||||
Reference in New Issue
Block a user