diff --git a/scripts/prepare_program_solutions_browser.py b/scripts/prepare_program_solutions_browser.py index 95563e76..333f58b4 100644 --- a/scripts/prepare_program_solutions_browser.py +++ b/scripts/prepare_program_solutions_browser.py @@ -57,9 +57,11 @@ def rows(model, ids): assert not receipt.exists(), "Use a fresh fixture key; preparation must not be replayed." assert not PartnerProgram.objects.filter(tag__startswith=prefix).exists() baseline = {} + baseline_values = {} for model in protected_models: ids = list(model._base_manager.order_by("pk").values_list("pk", flat=True)) - baseline[model._meta.label] = {"ids": ids, "hash": digest(rows(model, ids))} + baseline_values[model._meta.label] = rows(model, ids) + baseline[model._meta.label] = {"ids": ids, "hash": digest(baseline_values[model._meta.label])} result = { "prefix": prefix, "managerId": manager_id, @@ -126,7 +128,31 @@ def rows(model, ids): ) for model in protected_models: entry = baseline[model._meta.label] - assert digest(rows(model, entry["ids"])) == entry["hash"] + current = rows(model, entry["ids"]) + if digest(current) != entry["hash"]: + pk_name = model._meta.pk.attname + old_rows = {row[pk_name]: row for row in baseline_values[model._meta.label]} + changed_fields = sorted( + { + name + for row in current + for name in row + if old_rows[row[pk_name]].get(name) != row[name] + } + ) + sys.stdout.write( + "PREPARE_RETENTION_DIFF=" + + json.dumps( + { + "model": model._meta.label, + "fields": changed_fields, + "beforeCount": len(old_rows), + "afterCount": len(current), + } + ) + + "\n" + ) + raise AssertionError(model._meta.label) receipt.write_text(json.dumps(result, ensure_ascii=False, default=str), encoding="utf8") receipt.chmod(0o600) sys.stdout.write( diff --git a/scripts/verify_program_solutions_dev.py b/scripts/verify_program_solutions_dev.py index e953a59a..8f072ff0 100644 --- a/scripts/verify_program_solutions_dev.py +++ b/scripts/verify_program_solutions_dev.py @@ -51,14 +51,19 @@ def digest(value): and not model._meta.proxy ] + baseline_ids = { + model._meta.label: list(model._base_manager.order_by("pk").values_list("pk", flat=True)) + for model in models + } + def retained(): - return { - model._meta.label: { - "count": model._base_manager.count(), - "hash": digest(list(model._base_manager.order_by("pk").values())), - } - for model in models - } + result = {} + for model in models: + rows = list( + model._base_manager.filter(pk__in=baseline_ids[model._meta.label]).order_by("pk").values() + ) + result[model._meta.label] = {"count": len(rows), "hash": digest(rows)} + return result baseline = retained() legacy_ids = [ @@ -360,12 +365,19 @@ def request(actor, method, path, body=None, expected=200, binary=False): rollback_complete = True finally: after = retained() + changed = { + label: {"before": baseline[label], "after": after[label]} + for label in baseline + if baseline[label] != after[label] + } + if changed: + sys.stdout.write("RETENTION_DIFF=" + json.dumps(changed, sort_keys=True) + "\n") assert ( after == baseline ), "Existing model data changed; inspect concurrent writers before attributing any difference." assert ( list( - PartnerProgram.objects.filter(solution_storage_mode="legacy_project") + PartnerProgram.objects.filter(pk__in=legacy_before, solution_storage_mode="legacy_project") .order_by("pk") .values_list("pk", flat=True) )