added asins for woot listings
This commit is contained in:
1 parent
93013c5d55
commit
03cc3a35cb
24 files changed
+1565
-2
No files matched your search
@@ -0,0 +1,302 @@
|
||||
"""Unit tests for scripts/bootstrap_db.py with a fake Mongo at the leaf.
|
||||
|
||||
The $jsonSchema validator's runtime behavior is server-side and is not
|
||||
covered here; it is verified against the live cluster when the script runs.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
|
||||
|
||||
import bootstrap_db # noqa: E402
|
||||
|
||||
|
||||
class FakeCollection:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.docs = {}
|
||||
self.indexes = []
|
||||
|
||||
def find_one(self, query, projection=None):
|
||||
return self.docs.get(query["_id"])
|
||||
|
||||
def update_one(self, query, update, upsert=False):
|
||||
class Result:
|
||||
upserted_id = None
|
||||
|
||||
result = Result()
|
||||
if query["_id"] not in self.docs and upsert:
|
||||
self.docs[query["_id"]] = {"_id": query["_id"], **update["$setOnInsert"]}
|
||||
result.upserted_id = query["_id"]
|
||||
|
||||
return result
|
||||
|
||||
def create_index(self, keys, **options):
|
||||
self.indexes.append((keys, options))
|
||||
return "_".join(f"{field}_{direction}" for field, direction in keys)
|
||||
|
||||
|
||||
class FakeDatabase:
|
||||
def __init__(self, existing=()):
|
||||
self.collections = {name: FakeCollection(name) for name in existing}
|
||||
self.options = {name: {} for name in existing}
|
||||
self.created = []
|
||||
self.commands = []
|
||||
|
||||
def list_collection_names(self):
|
||||
return list(self.collections)
|
||||
|
||||
def list_collections(self, filter=None):
|
||||
names = [filter["name"]] if filter else list(self.collections)
|
||||
return [
|
||||
{"name": n, "options": self.options[n]}
|
||||
for n in names
|
||||
if n in self.collections
|
||||
]
|
||||
|
||||
def create_collection(self, name, **options):
|
||||
self.collections[name] = FakeCollection(name)
|
||||
self.options[name] = options
|
||||
self.created.append((name, options))
|
||||
|
||||
def command(self, name, collection, **kwargs):
|
||||
self.commands.append((name, collection, kwargs))
|
||||
self.options[collection].update(kwargs)
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.collections.setdefault(name, FakeCollection(name))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def seed_root(tmp_path):
|
||||
for mode in ("production", "testing"):
|
||||
(tmp_path / mode).mkdir()
|
||||
(tmp_path / mode / "woot.json").write_text(
|
||||
json.dumps({"categories": ["tech"], "channels": {"50-60": "1"}})
|
||||
)
|
||||
(tmp_path / "production" / "bestbuy.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"categories": {"a": "categoryid$a"},
|
||||
"channels": {"60-70": "2"},
|
||||
"extra": "ignored",
|
||||
}
|
||||
)
|
||||
)
|
||||
(tmp_path / "control.json").write_text(
|
||||
json.dumps({"monitors": {"names": ["woot"], "settings": {}}})
|
||||
)
|
||||
return tmp_path
|
||||
|
||||
|
||||
def test_ensure_collection_creates_absent_with_options():
|
||||
db = FakeDatabase()
|
||||
assert bootstrap_db.ensure_collection(db, "configs", validator={"x": 1}) is True
|
||||
assert db.created == [("configs", {"validator": {"x": 1}})]
|
||||
|
||||
|
||||
def test_ensure_collection_skips_existing():
|
||||
db = FakeDatabase(existing=["configs"])
|
||||
assert bootstrap_db.ensure_collection(db, "configs") is False
|
||||
assert db.created == []
|
||||
|
||||
|
||||
def test_ensure_collection_dry_run_writes_nothing():
|
||||
db = FakeDatabase()
|
||||
assert bootstrap_db.ensure_collection(db, "configs", dry_run=True) is True
|
||||
assert db.created == []
|
||||
|
||||
|
||||
def test_ensure_config_validator_applies_collmod_once():
|
||||
db = FakeDatabase(existing=["configs"])
|
||||
assert bootstrap_db.ensure_config_validator(db, "configs") is True
|
||||
assert db.commands == [
|
||||
("collMod", "configs", {"validator": bootstrap_db.CONFIG_VALIDATOR})
|
||||
]
|
||||
assert bootstrap_db.ensure_config_validator(db, "configs") is False
|
||||
assert len(db.commands) == 1
|
||||
|
||||
|
||||
def test_ensure_config_validator_dry_run_and_missing_collection():
|
||||
db = FakeDatabase(existing=["configs"])
|
||||
assert bootstrap_db.ensure_config_validator(db, "configs", dry_run=True) is True
|
||||
assert db.commands == []
|
||||
assert bootstrap_db.ensure_config_validator(db, "nope") is False
|
||||
|
||||
|
||||
def test_load_seed_configs_rejects_list_channels(tmp_path):
|
||||
(tmp_path / "woot.json").write_text(
|
||||
json.dumps({"categories": [], "channels": {"50-60": ["1", "2"]}})
|
||||
)
|
||||
with pytest.raises(ValueError, match="single id strings"):
|
||||
bootstrap_db.load_seed_configs(tmp_path)
|
||||
|
||||
|
||||
def test_alert_indexes_match_consumer_spec():
|
||||
alerts = FakeCollection("alerts")
|
||||
bootstrap_db.ensure_alert_indexes(alerts)
|
||||
assert alerts.indexes == [
|
||||
([("claimed", 1), ("priority", -1), ("createdAt", 1)], {}),
|
||||
(
|
||||
[("product_id", 1)],
|
||||
{"unique": True, "partialFilterExpression": {"claimed": False}},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def test_load_seed_configs_keys_by_stem_and_drops_extra_fields(seed_root):
|
||||
docs = bootstrap_db.load_seed_configs(seed_root / "production")
|
||||
assert set(docs) == {"bestbuy", "woot"}
|
||||
assert docs["bestbuy"] == {
|
||||
"categories": {"a": "categoryid$a"},
|
||||
"channels": {"60-70": "2"},
|
||||
}
|
||||
|
||||
|
||||
def test_load_seed_configs_rejects_missing_keys(tmp_path):
|
||||
(tmp_path / "bad.json").write_text(json.dumps({"categories": []}))
|
||||
with pytest.raises(ValueError, match="channels"):
|
||||
bootstrap_db.load_seed_configs(tmp_path)
|
||||
|
||||
|
||||
def test_load_seed_configs_rejects_wrong_shape_for_monitor(tmp_path):
|
||||
(tmp_path / "bestbuy.json").write_text(
|
||||
json.dumps({"categories": ["abcat0"], "channels": {}})
|
||||
)
|
||||
with pytest.raises(ValueError, match="categories must be dict for bestbuy"):
|
||||
bootstrap_db.load_seed_configs(tmp_path)
|
||||
|
||||
(tmp_path / "bestbuy.json").unlink()
|
||||
(tmp_path / "woot.json").write_text(
|
||||
json.dumps({"categories": {"tech": "tech"}, "channels": {}})
|
||||
)
|
||||
with pytest.raises(ValueError, match="categories must be list for woot"):
|
||||
bootstrap_db.load_seed_configs(tmp_path)
|
||||
|
||||
|
||||
def test_load_seed_configs_empty_dir(tmp_path):
|
||||
assert bootstrap_db.load_seed_configs(tmp_path) == {}
|
||||
|
||||
|
||||
def test_seed_configs_inserts_absent_and_preserves_existing():
|
||||
configs = FakeCollection("configs")
|
||||
configs.docs["woot"] = {"_id": "woot", "categories": ["edited"], "channels": {}}
|
||||
docs = {
|
||||
"woot": {"categories": ["tech"], "channels": {}},
|
||||
"hp": {"categories": [], "channels": {}},
|
||||
}
|
||||
assert bootstrap_db.seed_configs(configs, docs) == ["hp"]
|
||||
assert configs.docs["woot"]["categories"] == ["edited"]
|
||||
assert configs.docs["hp"] == {"_id": "hp", "categories": [], "channels": {}}
|
||||
|
||||
|
||||
def test_seed_configs_dry_run_reports_without_writing():
|
||||
configs = FakeCollection("configs")
|
||||
docs = {"hp": {"categories": [], "channels": {}}}
|
||||
assert bootstrap_db.seed_configs(configs, docs, dry_run=True) == ["hp"]
|
||||
assert configs.docs == {}
|
||||
|
||||
|
||||
def test_load_control_seed_keys_by_id(seed_root):
|
||||
docs = bootstrap_db.load_control_seed(seed_root / "control.json")
|
||||
assert docs == {"monitors": {"names": ["woot"], "settings": {}}}
|
||||
|
||||
|
||||
def test_load_control_seed_rejects_non_object_doc(tmp_path):
|
||||
path = tmp_path / "control.json"
|
||||
path.write_text(json.dumps({"monitors": ["woot"]}))
|
||||
with pytest.raises(ValueError, match="monitors"):
|
||||
bootstrap_db.load_control_seed(path)
|
||||
|
||||
|
||||
def test_seed_control_inserts_absent_and_preserves_existing():
|
||||
control = FakeCollection("control")
|
||||
control.docs["monitors"] = {"_id": "monitors", "names": ["edited"]}
|
||||
docs = {"monitors": {"names": ["woot"]}, "other": {"x": 1}}
|
||||
assert bootstrap_db.seed_control(control, docs) == ["other"]
|
||||
assert control.docs["monitors"]["names"] == ["edited"]
|
||||
assert control.docs["other"] == {"_id": "other", "x": 1}
|
||||
|
||||
|
||||
def test_seed_control_dry_run_reports_without_writing():
|
||||
control = FakeCollection("control")
|
||||
assert bootstrap_db.seed_control(control, {"monitors": {}}, dry_run=True) == [
|
||||
"monitors"
|
||||
]
|
||||
assert control.docs == {}
|
||||
|
||||
|
||||
def test_bootstrap_builds_both_modes(seed_root):
|
||||
db = FakeDatabase()
|
||||
summary = bootstrap_db.bootstrap(db, seed_root=seed_root)
|
||||
|
||||
created = dict(db.created)
|
||||
for suffix in ("", "_testing"):
|
||||
assert created[f"configs{suffix}"] == {
|
||||
"validator": bootstrap_db.CONFIG_VALIDATOR
|
||||
}
|
||||
assert f"alerts{suffix}" in created
|
||||
assert f"control{suffix}" in created
|
||||
for monitor in bootstrap_db.MONITORS:
|
||||
assert f"{monitor}{suffix}" in created
|
||||
assert len(db[f"alerts{suffix}"].indexes) == 2
|
||||
|
||||
assert summary["seeded"]["configs"] == ["bestbuy", "woot"]
|
||||
assert summary["seeded"]["configs_testing"] == ["woot"]
|
||||
assert summary["seeded"]["control"] == ["monitors"]
|
||||
assert summary["seeded"]["control_testing"] == ["monitors"]
|
||||
assert db["control"].docs["monitors"]["names"] == ["woot"]
|
||||
assert len(summary["created"]) == 2 * (3 + len(bootstrap_db.MONITORS))
|
||||
|
||||
|
||||
def test_bootstrap_rerun_is_noop(seed_root):
|
||||
db = FakeDatabase()
|
||||
bootstrap_db.bootstrap(db, seed_root=seed_root)
|
||||
db.created.clear()
|
||||
summary = bootstrap_db.bootstrap(db, seed_root=seed_root)
|
||||
assert db.created == []
|
||||
assert db.commands == []
|
||||
assert summary["created"] == []
|
||||
assert summary["validators"] == []
|
||||
assert summary["seeded"] == {
|
||||
"configs": [],
|
||||
"configs_testing": [],
|
||||
"control": [],
|
||||
"control_testing": [],
|
||||
}
|
||||
|
||||
|
||||
def test_shipped_control_seed_matches_registry_shape():
|
||||
"""monitors doc: names list and per-name {min_percentage, ping_threshold}"""
|
||||
|
||||
docs = bootstrap_db.load_control_seed(bootstrap_db.CONTROL_SEED)
|
||||
monitors = docs["monitors"]
|
||||
assert set(monitors["settings"]) == set(monitors["names"])
|
||||
for name, settings in monitors["settings"].items():
|
||||
assert set(settings) == {"min_percentage", "ping_threshold"}, name
|
||||
assert isinstance(settings["min_percentage"], int), name
|
||||
assert 40 <= settings["min_percentage"] <= 100, name
|
||||
assert settings["ping_threshold"] is None or isinstance(
|
||||
settings["ping_threshold"], int
|
||||
), name
|
||||
|
||||
|
||||
def test_shipped_seed_files_load_and_match_validator_shape():
|
||||
"""every checked-in seed doc has the shape the validator and setup_config want"""
|
||||
|
||||
for mode in ("production", "testing"):
|
||||
docs = bootstrap_db.load_seed_configs(bootstrap_db.SEED_ROOT / mode)
|
||||
assert docs, mode
|
||||
for name, doc in docs.items():
|
||||
categories, channels = doc["categories"], doc["channels"]
|
||||
assert isinstance(categories, bootstrap_db.CATEGORY_SHAPES[name]), name
|
||||
if isinstance(categories, dict):
|
||||
assert all(isinstance(v, str) for v in categories.values()), name
|
||||
else:
|
||||
assert all(isinstance(v, str) for v in categories), name
|
||||
for value in channels.values():
|
||||
assert isinstance(value, str) and value.isdigit(), (name, value)
|
||||
Reference in new issue
Block a user