Skip to content

Reproduce a report with seeds

Every random choice dpm-synth makes, starting values and generated identifiers alike, comes from one random generator seeded with --seed (default 0). The written package has fixed ZIP timestamps and a fixed order of files and facts. So the same inputs give the same bytes:

import hashlib
from pathlib import Path

from dpmxbrl import write_xbrl_csv

from dpmsynth import generate, load_template

template = load_template("sample.json")
for folder, seed in (("first", 7), ("second", 7), ("other", 8)):
    Path(folder).mkdir()
    write_xbrl_csv(generate(template, seed=seed).report, f"{folder}/report.zip")


def digest(folder):
    return hashlib.sha256(Path(folder, "report.zip").read_bytes()).hexdigest()


print(digest("first") == digest("second"))
print(digest("first") == digest("other"))
True
False

What the output depends on

The package is a function of:

  • the template, including the order of its tables, cells and rules;
  • the seed and the other options: --open-rows, --max-rounds, --entity, --level, --reference-date and --scale-rows;
  • the package's file name, which names its root folder (the example writes each package as report.zip, in its own folder);
  • the versions of dpm-synth, dpm-xl and dpm-xbrl.

It does not depend on the machine, the time, the working directory or Python's hash seed. A patch or minor release of any of the three packages may change the values generated for a seed, for example when a repair or a rule's evaluation improves; the changelog says so when it does.

Several different reports

Use different seeds for reports that differ, such as one report per test case or a set of reports for a performance test:

$ dpm-synth generate minimal.json -o report-1.zip --seed 1
rules: 2, passed: 2, failed: 0, not evaluated: 0, not applicable: 0
rounds: 2 (failing rules per round: 1, 0)
wrote report-1.zip (3 facts)
$ dpm-synth generate minimal.json -o report-2.zip --seed 2
rules: 2, passed: 2, failed: 0, not evaluated: 0, not applicable: 0
rounds: 2 (failing rules per round: 1, 0)
wrote report-2.zip (3 facts)

The values differ; on a large module, the number of rounds and the rules that still fail may differ from seed to seed too.

Stable test fixtures

To keep a test fixture stable across upgrades, commit the generated package rather than regenerating it in every test run, and regenerate it on purpose, with the same seed, when you upgrade. A test that only needs a valid report of a module can regenerate it each time and check the rule results instead of the bytes.