update tests to remove unittest uses and adjust configurations
This commit is contained in:
Родитель
7eb2b77bc4
Коммит
9b63b7d017
|
@ -94,24 +94,8 @@ def client(app_context, experiment):
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="class")
|
@pytest.fixture
|
||||||
def cirrus_client(request):
|
def cirrus_client(app_context, bucket_config):
|
||||||
app_context = json.dumps(
|
|
||||||
{
|
|
||||||
"app_id": "test app id",
|
|
||||||
"app_name": "test app name",
|
|
||||||
"channel": "dev",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
bucket_config = {
|
|
||||||
"randomizationUnit": "user_id",
|
|
||||||
"count": 100,
|
|
||||||
"namespace": "",
|
|
||||||
"start": 1,
|
|
||||||
"total": 100,
|
|
||||||
}
|
|
||||||
|
|
||||||
branches = [
|
branches = [
|
||||||
{
|
{
|
||||||
"slug": "control",
|
"slug": "control",
|
||||||
|
@ -149,14 +133,15 @@ def cirrus_client(request):
|
||||||
"featureIds": ["imported-module-1-included-feature-1"],
|
"featureIds": ["imported-module-1-included-feature-1"],
|
||||||
}
|
}
|
||||||
|
|
||||||
request.cls.cirrus_client = CirrusClient(app_context)
|
client = CirrusClient(app_context)
|
||||||
data = json.dumps({"data": [experiment]})
|
data = json.dumps({"data": [experiment]})
|
||||||
request.cls.cirrus_client.set_experiments(data)
|
client.set_experiments(data)
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="class")
|
@pytest.fixture
|
||||||
def fml_client(request):
|
def fml_client():
|
||||||
def _client(_, path, channel):
|
def _client(path, channel):
|
||||||
return FmlClient("./automation/python-tests/resources/" + path, channel)
|
return FmlClient("./automation/python-tests/resources/" + path, channel)
|
||||||
|
|
||||||
request.cls.fml_client = _client
|
return _client
|
||||||
|
|
|
@ -1,85 +1,74 @@
|
||||||
import json
|
import json
|
||||||
import pytest
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("fml_client", "cirrus_client")
|
# 1. create request
|
||||||
class TestCirrusClientFmlClientIntegration(unittest.TestCase):
|
# 2. enroll, convert response to dict from JSON
|
||||||
def test_enroll_and_get_enrolled_feature_json(self):
|
# 3. map enrolledFeatureConfigMap values to the feature values
|
||||||
# create request
|
# 4. create FmlClient
|
||||||
req_1 = json.dumps(
|
# 5. merge feature configs into default JSON and validate their values against the manifest
|
||||||
{
|
# 6. load JSON response as dict
|
||||||
"clientId": "jeddai",
|
def test_enroll_and_get_enrolled_feature_json_control(fml_client, cirrus_client):
|
||||||
"requestContext": {"username": "jeddai"},
|
req = json.dumps(
|
||||||
}
|
{
|
||||||
)
|
"clientId": "jeddai",
|
||||||
# enroll, convert response to dict from JSON
|
"requestContext": {"username": "jeddai"},
|
||||||
res_1 = json.loads(self.cirrus_client.handle_enrollment(req_1))
|
}
|
||||||
# map enrolledFeatureConfigMap values to the feature values
|
)
|
||||||
feature_configs = json.dumps(
|
res = json.loads(cirrus_client.handle_enrollment(req))
|
||||||
[value["feature"] for value in res_1["enrolledFeatureConfigMap"].values()]
|
feature_configs = json.dumps(
|
||||||
)
|
[value["feature"] for value in res["enrolledFeatureConfigMap"].values()]
|
||||||
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
res_1["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"][
|
res["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"]["slug"]
|
||||||
"slug"
|
== "experiment-slug"
|
||||||
]
|
)
|
||||||
== "experiment-slug"
|
assert (
|
||||||
)
|
res["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"][
|
||||||
assert (
|
"branch"
|
||||||
res_1["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"][
|
]
|
||||||
"branch"
|
== "control"
|
||||||
]
|
)
|
||||||
== "control"
|
|
||||||
)
|
|
||||||
|
|
||||||
# create FmlClient
|
fml_client = fml_client("test-include-import.fml.yml", "developer")
|
||||||
fml_client = self.fml_client("test-include-import.fml.yml", "developer")
|
merged_res = fml_client.validate_feature_configs_and_merge_into_defaults(
|
||||||
# merge feature configs into default JSON and validate their values against the manifest
|
feature_configs
|
||||||
merged_res_1 = fml_client.validate_feature_configs_and_merge_into_defaults(
|
)
|
||||||
feature_configs
|
merged_res_json = json.loads(merged_res.json)
|
||||||
)
|
|
||||||
# load JSON response as dict
|
|
||||||
merged_res_json_1 = json.loads(merged_res_1.json)
|
|
||||||
|
|
||||||
assert (
|
assert merged_res_json["imported-module-1-included-feature-1"]["enabled"] is False
|
||||||
merged_res_json_1["imported-module-1-included-feature-1"]["enabled"]
|
assert len(merged_res.errors) == 0
|
||||||
is False
|
|
||||||
)
|
|
||||||
assert len(merged_res_1.errors) == 0
|
|
||||||
|
|
||||||
# repeat the above but with a different client/username on the request
|
|
||||||
req_2 = json.dumps(
|
|
||||||
{
|
|
||||||
"clientId": "test",
|
|
||||||
"requestContext": {"username": "test"},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
res_2 = json.loads(self.cirrus_client.handle_enrollment(req_2))
|
|
||||||
feature_configs = json.dumps(
|
|
||||||
[value["feature"] for value in res_2["enrolledFeatureConfigMap"].values()]
|
|
||||||
)
|
|
||||||
|
|
||||||
assert (
|
# repeat the above but with a different client/username on the request
|
||||||
res_2["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"][
|
def test_enroll_and_get_enrolled_feature_json_treatment(fml_client, cirrus_client):
|
||||||
"slug"
|
req = json.dumps(
|
||||||
]
|
{
|
||||||
== "experiment-slug"
|
"clientId": "test",
|
||||||
)
|
"requestContext": {"username": "test"},
|
||||||
assert (
|
}
|
||||||
res_2["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"][
|
)
|
||||||
"branch"
|
res = json.loads(cirrus_client.handle_enrollment(req))
|
||||||
]
|
feature_configs = json.dumps(
|
||||||
== "treatment"
|
[value["feature"] for value in res["enrolledFeatureConfigMap"].values()]
|
||||||
)
|
)
|
||||||
|
|
||||||
fml_client = self.fml_client("test-include-import.fml.yml", "developer")
|
assert (
|
||||||
merged_res_2 = fml_client.validate_feature_configs_and_merge_into_defaults(
|
res["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"]["slug"]
|
||||||
feature_configs
|
== "experiment-slug"
|
||||||
)
|
)
|
||||||
merged_res_json_2 = json.loads(merged_res_2.json)
|
assert (
|
||||||
|
res["enrolledFeatureConfigMap"]["imported-module-1-included-feature-1"][
|
||||||
|
"branch"
|
||||||
|
]
|
||||||
|
== "treatment"
|
||||||
|
)
|
||||||
|
|
||||||
assert (
|
fml_client = fml_client("test-include-import.fml.yml", "developer")
|
||||||
merged_res_json_2["imported-module-1-included-feature-1"]["enabled"] is True
|
merged_res = fml_client.validate_feature_configs_and_merge_into_defaults(
|
||||||
)
|
feature_configs
|
||||||
assert len(merged_res_2.errors) == 0
|
)
|
||||||
|
merged_res_json = json.loads(merged_res.json)
|
||||||
|
|
||||||
|
assert merged_res_json["imported-module-1-included-feature-1"]["enabled"] is True
|
||||||
|
assert len(merged_res.errors) == 0
|
||||||
|
|
|
@ -1,107 +1,116 @@
|
||||||
import json
|
import json
|
||||||
import pytest
|
import pytest
|
||||||
import unittest
|
|
||||||
from fml import FmlError, InternalError
|
from fml import FmlError, InternalError
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("fml_client")
|
def test_instantiate_fml_client(fml_client):
|
||||||
class TestFmlClient(unittest.TestCase):
|
fml_client("test.fml.yml", "developer")
|
||||||
def test_instantiate_fml_client(self):
|
|
||||||
self.fml_client("test.fml.yml", "developer")
|
|
||||||
|
|
||||||
def test_instantiate_fml_client_fails_if_invalid_path(self):
|
|
||||||
with self.assertRaises(FmlError):
|
|
||||||
self.fml_client("a-random-path", "developer")
|
|
||||||
|
|
||||||
def test_instantiate_fml_client_fails_if_invalid_yml(self):
|
def test_instantiate_fml_client_fails_if_invalid_path(fml_client):
|
||||||
with self.assertRaises(InternalError):
|
with pytest.raises(FmlError):
|
||||||
self.fml_client("test-invalid.fml.yml", "developer")
|
fml_client("a-random-path", "developer")
|
||||||
|
|
||||||
def test_instantiate_fml_client_fails_if_invalid_channel(self):
|
|
||||||
with self.assertRaises(FmlError):
|
|
||||||
self.fml_client("test.fml.yml", "release")
|
|
||||||
|
|
||||||
def test_default_json(self):
|
def test_instantiate_fml_client_fails_if_invalid_yml(fml_client):
|
||||||
client = self.fml_client("test.fml.yml", "developer")
|
with pytest.raises(InternalError):
|
||||||
defaults = json.loads(client.get_default_json())
|
fml_client("test-invalid.fml.yml", "developer")
|
||||||
assert defaults["example-feature"]["enabled"] is False
|
|
||||||
assert defaults["example-feature"]["something"] == "wicked"
|
|
||||||
|
|
||||||
client = self.fml_client("test.fml.yml", "nightly")
|
|
||||||
defaults = json.loads(client.get_default_json())
|
|
||||||
assert defaults["example-feature"]["enabled"] is True
|
|
||||||
assert defaults["example-feature"].get("something") is None
|
|
||||||
|
|
||||||
def test_validate(self):
|
def test_instantiate_fml_client_fails_if_invalid_channel(fml_client):
|
||||||
client = self.fml_client("test.fml.yml", "developer")
|
with pytest.raises(FmlError):
|
||||||
config = {"featureId": "example-feature", "value": {"enabled": True}}
|
fml_client("test.fml.yml", "release")
|
||||||
assert client.validate_feature_config(json.dumps(config)) is True
|
|
||||||
|
|
||||||
def test_validate_false(self):
|
|
||||||
client = self.fml_client("test.fml.yml", "developer")
|
|
||||||
config = {"featureId": "example-featurea", "value": {"enabled": True}}
|
|
||||||
|
|
||||||
with self.assertRaises(FmlError):
|
def test_default_json(fml_client):
|
||||||
client.validate_feature_config(json.dumps(config))
|
client = fml_client("test.fml.yml", "developer")
|
||||||
|
defaults = json.loads(client.get_default_json())
|
||||||
|
assert defaults["example-feature"]["enabled"] is False
|
||||||
|
assert defaults["example-feature"]["something"] == "wicked"
|
||||||
|
|
||||||
def test_merge_and_validate(self):
|
client = fml_client("test.fml.yml", "nightly")
|
||||||
client = self.fml_client("test.fml.yml", "developer")
|
defaults = json.loads(client.get_default_json())
|
||||||
configs = [{"featureId": "example-feature", "value": {"enabled": True}}]
|
assert defaults["example-feature"]["enabled"] is True
|
||||||
result = client.validate_feature_configs_and_merge_into_defaults(
|
assert defaults["example-feature"].get("something") is None
|
||||||
json.dumps(configs)
|
|
||||||
)
|
|
||||||
assert len(result.errors) == 0
|
|
||||||
|
|
||||||
result_json = json.loads(result.json)["example-feature"]
|
|
||||||
assert result_json["enabled"] is True
|
|
||||||
assert result_json["something"] == "wicked"
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason="This functionality is hindered by EXP-3503")
|
def test_validate_single_feature(fml_client):
|
||||||
def test_merge_and_validate_error_on_invalid_key(self):
|
client = fml_client("test.fml.yml", "developer")
|
||||||
client = self.fml_client("test.fml.yml", "developer")
|
config = {"featureId": "example-feature", "value": {"enabled": True}}
|
||||||
configs = [{"featureId": "example-feature", "value": {"enabled1": False}}]
|
assert client.validate_feature_config(json.dumps(config)) is True
|
||||||
result = client.validate_feature_configs_and_merge_into_defaults(
|
|
||||||
json.dumps(configs)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert len(result.errors) == 1
|
|
||||||
assert isinstance(result.errors[0], FmlError)
|
|
||||||
|
|
||||||
def test_merge_and_validate_error_on_invalid_value(self):
|
def test_validate_single_feature_false_invalid_feature(fml_client):
|
||||||
client = self.fml_client("test.fml.yml", "developer")
|
client = fml_client("test.fml.yml", "developer")
|
||||||
configs = [{"featureId": "example-feature", "value": {"enabled": "false"}}]
|
config = {"featureId": "example-featurea", "value": {"enabled": True}}
|
||||||
result = client.validate_feature_configs_and_merge_into_defaults(
|
|
||||||
json.dumps(configs)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert len(result.errors) == 1
|
with pytest.raises(FmlError):
|
||||||
assert isinstance(result.errors[0], FmlError)
|
client.validate_feature_config(json.dumps(config))
|
||||||
|
|
||||||
def test_merge_and_validate_on_included_and_imported_features(self):
|
|
||||||
client = self.fml_client(
|
|
||||||
"test-include-import.fml.yml",
|
|
||||||
"developer",
|
|
||||||
)
|
|
||||||
configs = [
|
|
||||||
{"featureId": "example-feature", "value": {"enabled": True}},
|
|
||||||
{"featureId": "included-feature-1", "value": {"enabled": True}},
|
|
||||||
]
|
|
||||||
result = client.validate_feature_configs_and_merge_into_defaults(
|
|
||||||
json.dumps(configs)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert len(result.errors) == 0
|
def test_merge_and_validate(fml_client):
|
||||||
|
client = fml_client("test.fml.yml", "developer")
|
||||||
|
configs = [{"featureId": "example-feature", "value": {"enabled": True}}]
|
||||||
|
result = client.validate_feature_configs_and_merge_into_defaults(
|
||||||
|
json.dumps(configs)
|
||||||
|
)
|
||||||
|
assert len(result.errors) == 0
|
||||||
|
|
||||||
example_feature = json.loads(result.json)["example-feature"]
|
result_json = json.loads(result.json)["example-feature"]
|
||||||
assert example_feature["enabled"] is True
|
assert result_json["enabled"] is True
|
||||||
assert example_feature["something"] == "wicked"
|
assert result_json["something"] == "wicked"
|
||||||
included_feature_1 = json.loads(result.json)["included-feature-1"]
|
|
||||||
assert included_feature_1["enabled"] is True
|
|
||||||
imported_module_1_feature_1 = json.loads(result.json)[
|
@pytest.mark.skip(reason="This functionality is hindered by EXP-3503")
|
||||||
"imported-module-1-feature-1"
|
def test_merge_and_validate_error_on_invalid_key(fml_client):
|
||||||
]
|
client = fml_client("test.fml.yml", "developer")
|
||||||
assert imported_module_1_feature_1["enabled"] is True
|
configs = [{"featureId": "example-feature", "value": {"enabled1": False}}]
|
||||||
imported_module_1_included_feature_1 = json.loads(result.json)[
|
result = client.validate_feature_configs_and_merge_into_defaults(
|
||||||
"imported-module-1-included-feature-1"
|
json.dumps(configs)
|
||||||
]
|
)
|
||||||
assert imported_module_1_included_feature_1["enabled"] is False
|
|
||||||
|
assert len(result.errors) == 1
|
||||||
|
assert isinstance(result.errors[0], FmlError)
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge_and_validate_error_on_invalid_value(fml_client):
|
||||||
|
client = fml_client("test.fml.yml", "developer")
|
||||||
|
configs = [{"featureId": "example-feature", "value": {"enabled": "false"}}]
|
||||||
|
result = client.validate_feature_configs_and_merge_into_defaults(
|
||||||
|
json.dumps(configs)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(result.errors) == 1
|
||||||
|
assert isinstance(result.errors[0], FmlError)
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge_and_validate_on_included_and_imported_features(fml_client):
|
||||||
|
client = fml_client(
|
||||||
|
"test-include-import.fml.yml",
|
||||||
|
"developer",
|
||||||
|
)
|
||||||
|
configs = [
|
||||||
|
{"featureId": "example-feature", "value": {"enabled": True}},
|
||||||
|
{"featureId": "included-feature-1", "value": {"enabled": True}},
|
||||||
|
{
|
||||||
|
"featureId": "imported-module-1-included-feature-1",
|
||||||
|
"value": {"enabled": True},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
result = client.validate_feature_configs_and_merge_into_defaults(
|
||||||
|
json.dumps(configs)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(result.errors) == 0
|
||||||
|
|
||||||
|
example_feature = json.loads(result.json)["example-feature"]
|
||||||
|
assert example_feature["enabled"] is True
|
||||||
|
assert example_feature["something"] == "wicked"
|
||||||
|
included_feature_1 = json.loads(result.json)["included-feature-1"]
|
||||||
|
assert included_feature_1["enabled"] is True
|
||||||
|
imported_module_1_feature_1 = json.loads(result.json)["imported-module-1-feature-1"]
|
||||||
|
assert imported_module_1_feature_1["enabled"] is True
|
||||||
|
imported_module_1_included_feature_1 = json.loads(result.json)[
|
||||||
|
"imported-module-1-included-feature-1"
|
||||||
|
]
|
||||||
|
assert imported_module_1_included_feature_1["enabled"] is True
|
||||||
|
|
Загрузка…
Ссылка в новой задаче