From d3f83dc5534ffd155234ff738795ac801ecd7043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Mon, 7 Oct 2024 20:43:16 +0200 Subject: [PATCH 1/2] Add sample data seeding Can be used to manually test the UI. Might be helpful for automated tests in the future. --- README.md | 6 ++++ pyproject.toml | 4 +++ sample_data.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 sample_data.py diff --git a/README.md b/README.md index b53568ad..1dedc220 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,12 @@ After a model change create the migration poetry run aerich migrate ``` +To seed some sample data (attention: drops all current data) use + +```bash +poetry run generate-sample-data +``` + ### Code formatting and linting Code is formatted using different tools diff --git a/pyproject.toml b/pyproject.toml index 17ef946f..8b58e7e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ pre-commit = "^3.6.2" flake8 = "7.1.0" mypy = "^1.11.2" types-pyyaml = "^6.0.12.20240808" +faker = "^30.1.0" [tool.poetry.group.docs.dependencies] mkdocs = "^1.6.0" @@ -48,6 +49,9 @@ pytest-asyncio = "^0.24.0" pytest-md-report = "^0.6.2" pytest_httpserver = "^1.1.0" +[tool.poetry.scripts] +generate-sample-data = "sample_data:main" + [tool.pytest] asyncio_mode = "auto" diff --git a/sample_data.py b/sample_data.py new file mode 100644 index 00000000..d72b5817 --- /dev/null +++ b/sample_data.py @@ -0,0 +1,88 @@ +import asyncio + +from faker import Faker +from faker.providers import company + +import goosebit +from goosebit.db.models import ( + Device, + Hardware, + Rollout, + Software, + UpdateModeEnum, + UpdateStateEnum, +) + +fake = Faker() +fake.add_provider(company) + + +async def generate_sample_data(): + await Rollout.all().delete() + await Device.all().delete() + await Software.all().delete() + await Hardware.all().delete() + + hardware1 = await Hardware.create(model="router", revision="1.1") + hardware2a = await Hardware.create(model="ap", revision="1.0") + hardware2b = await Hardware.create(model="ap", revision="2.0") + + software_for_hw1 = [] + software_for_hw2 = [] + + versions = ["0.12.0", "0.1.0", "1.0.1", "1.0.0-alpha2", "1.0.0-rc1", "1.0.0-rc12", "10.0.0", "1.0.0"] + for version in versions: + size = fake.random_int(min=100000, max=1000000) + software = await Software.create(version=version, hash=fake.sha1(), size=size, uri=fake.uri()) + await software.compatibility.add(hardware1) + software_for_hw1.append(software) + + versions = [ + "0.1.0", + "0.3.0", + "0.2.0", + "0.4.0", + ] + for version in versions: + size = fake.random_int(min=100000, max=1000000) + software = await Software.create(version=version, hash=fake.sha1(), size=size, uri=fake.uri()) + await software.compatibility.add(hardware2a) + await software.compatibility.add(hardware2b) + software_for_hw2.append(software) + + for i in range(50): + update_mode = fake.random_element([UpdateModeEnum.ROLLOUT, UpdateModeEnum.LATEST, UpdateModeEnum.ASSIGNED]) + hardware = fake.random_element([hardware1, hardware2a, hardware2b]) + software = ( + fake.random_element(software_for_hw1) if hardware == hardware1 else fake.random_element(software_for_hw2) + ) + await Device.create( + uuid=fake.uuid4(), + name=fake.bs(), + feed=fake.random_element(["dev", "qa", "live"]) if update_mode == UpdateModeEnum.ROLLOUT else "", + last_state=fake.random_element( + [UpdateStateEnum.REGISTERED, UpdateStateEnum.ERROR, UpdateStateEnum.FINISHED, UpdateStateEnum.RUNNING] + ), + update_mode=update_mode, + hardware=hardware, + assigned_software=software if update_mode == UpdateModeEnum.ASSIGNED else None, + ) + + for software in software_for_hw1 + software_for_hw2: + feed = fake.random_element(["dev", "qa", "live"]) + await Rollout.create(name=f"Release {software.version} to {feed}", feed=feed, software_id=software.id) + + print("Sample data created!") + + +async def run(): + db_ready = await goosebit.db.init() + if db_ready: + await generate_sample_data() + await goosebit.db.close() + else: + print("Failed to initialize database") + + +def main(): + asyncio.run(run()) From 7af79b9f8c0883be10cf46ba8cd2c294d1b39faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Mon, 7 Oct 2024 20:44:51 +0200 Subject: [PATCH 2/2] Sort software list in reverse order This should bring the most likely version to the top of the list. --- goosebit/ui/static/js/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goosebit/ui/static/js/util.js b/goosebit/ui/static/js/util.js index dd968687..669e1d2f 100644 --- a/goosebit/ui/static/js/util.js +++ b/goosebit/ui/static/js/util.js @@ -22,7 +22,7 @@ function secondsToRecentDate(t) { async function updateSoftwareSelection(devices = null) { try { - const url = new URL("/ui/bff/software", window.location.origin); + const url = new URL("/ui/bff/software?order[0][dir]=desc&order[0][name]=version", window.location.origin); if (devices != null) { for (const device of devices) { url.searchParams.append("uuids", device.uuid);