From 7c54a37618dbdfe639f19401809d4bd594d1d64e Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Tue, 11 Jun 2024 10:37:42 +0200 Subject: [PATCH] misc: add generate_configs.py script The script can be used to simulate setups of different sizes. A short description is added to the `misc/` folder for further information. This can be used for both benchmarking but also hunting down bugs which may occur with larger setups. Signed-off-by: Paul Spooren --- misc/README.md | 40 +++++++++++++++ misc/generate_configs.py | 105 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 misc/README.md create mode 100644 misc/generate_configs.py diff --git a/misc/README.md b/misc/README.md new file mode 100644 index 0000000..f32495d --- /dev/null +++ b/misc/README.md @@ -0,0 +1,40 @@ +# Additional files + +This folder contains additional files that are used in the project. + +## `generate_configs.py` + +The script is used to generate configuration files for a benchmark setup +consisting of a device under testing (DUT) and automatic test equipment (ATE), +basically a strong machine capable of running multiple Rosenpass instances at +once. + +At the top of the script multiple variables can be set to configure the DUT IP +address and more. Once configured you may run `python3 generate_configs.py` to +create the configuration files. + +A new folder called `output/` is created containing the subfolder `dut/` and +`ate/`. The former has to be copied on the DUT, ideally reproducible hardware +like a Raspberry Pi, while the latter is copied to the ATE, i.e. a laptop. + +### Running a benchmark + +On the ATE a run script is required since multiple instances of `rosenpass` are +started with different configurations in parallel. The scripts are named after +the number of instances they start, e.g. `run-50.sh` starts 50 instances. + +```shell +# on the ATE aka laptop +cd output/ate +./run-10.sh +``` + +On the DUT you start a single Rosenpass instance with the configuration matching +the ATE number of peers. + +```shell +# on the DUT aka Raspberry Pi +rosenpass exchange-config configs/dut-10.toml +``` + +Use whatever measurement tool you like to monitor the DUT and ATE. diff --git a/misc/generate_configs.py b/misc/generate_configs.py new file mode 100644 index 0000000..27f1c53 --- /dev/null +++ b/misc/generate_configs.py @@ -0,0 +1,105 @@ +from pathlib import Path +from subprocess import run + + +config = dict( + peer_counts=[1, 5, 10, 50, 100, 500], + peer_count_max=100, + ate_ip="192.168.2.1", + dut_ip="192.168.2.4", + dut_port=9999, + path_to_rosenpass_bin="/Users/user/src/rosenppass/rosenpass/target/debug/rosenpass", +) + +print(config) + +output_dir = Path("output") +output_dir.mkdir(exist_ok=True) + +template_dut = """ +public_key = "keys/dut-public-key" +secret_key = "keys/dut-secret-key" +listen = ["{dut_ip}:{dut_port}"] +verbosity = "Quiet" +""" +template_dut_peer = """ +[[peers]] # ATE-{i} +public_key = "keys/ate-{i}-public-key" +endpoint = "{ate_ip}:{ate_port}" +key_out = "out/key_out_{i}" +""" + +template_ate = """ +public_key = "keys/ate-{i}-public-key" +secret_key = "keys/ate-{i}-secret-key" +listen = ["{ate_ip}:{ate_port}"] +verbosity = "Quiet" + +[[peers]] # DUT +public_key = "keys/dut-public-key" +endpoint = "{dut_ip}:{dut_port}" +key_out = "out/key_out_{i}" +""" + +(output_dir / "dut" / "keys").mkdir(exist_ok=True, parents=True) +(output_dir / "dut" / "out").mkdir(exist_ok=True, parents=True) +(output_dir / "dut" / "configs").mkdir(exist_ok=True, parents=True) +(output_dir / "ate" / "keys").mkdir(exist_ok=True, parents=True) +(output_dir / "ate" / "out").mkdir(exist_ok=True, parents=True) +(output_dir / "ate" / "configs").mkdir(exist_ok=True, parents=True) + +for peer_count in config["peer_counts"]: + dut_config = template_dut.format(**config) + for i in range(peer_count): + dut_config += template_dut_peer.format(**config, i=i, ate_port=50000 + i) + + (output_dir / "dut" / "configs" / f"dut-{peer_count}.toml").write_text(dut_config) + + if not (output_dir / "dut" / "keys" / "dut-public-key").exists(): + print("Generate DUT keys") + run( + [ + config["path_to_rosenpass_bin"], + "gen-keys", + f"configs/dut-{peer_count}.toml", + ], + cwd=output_dir / "dut", + ) + else: + print("DUT keys already exist") + +# copy the DUT public key to the ATE +(output_dir / "ate" / "keys" / "dut-public-key").write_bytes( + (output_dir / "dut" / "keys" / "dut-public-key").read_bytes() +) + +ate_script = "(trap 'kill 0' SIGINT; \\\n" + +for i in range(config["peer_count_max"]): + (output_dir / "ate" / "configs" / f"ate-{i}.toml").write_text( + template_ate.format(**config, i=i, ate_port=50000 + i) + ) + + if not (output_dir / "ate" / "keys" / f"ate-{i}-public-key").exists(): + # generate ATE keys + run( + [config["path_to_rosenpass_bin"], "gen-keys", f"configs/ate-{i}.toml"], + cwd=output_dir / "ate", + ) + else: + print(f"ATE-{i} keys already exist") + + # copy the ATE public keys to the DUT + (output_dir / "dut" / "keys" / f"ate-{i}-public-key").write_bytes( + (output_dir / "ate" / "keys" / f"ate-{i}-public-key").read_bytes() + ) + + ate_script += ( + f"{config['path_to_rosenpass_bin']} exchange-config configs/ate-{i}.toml & \\\n" + ) + + if (i + 1) in config["peer_counts"]: + write_script = ate_script + write_script += "wait)" + + (output_dir / "ate" / f"run-{i+1}.sh").write_text(write_script)