Skip to content

feat: implement tree details denormalization with tests_rollup table#1795

Open
gustavobtflores wants to merge 4 commits intokernelci:mainfrom
gustavobtflores:feat/tree-details-denormalization
Open

feat: implement tree details denormalization with tests_rollup table#1795
gustavobtflores wants to merge 4 commits intokernelci:mainfrom
gustavobtflores:feat/tree-details-denormalization

Conversation

@gustavobtflores
Copy link
Contributor

@gustavobtflores gustavobtflores commented Mar 12, 2026

Description

Implements a denormalization strategy for tree details by introducing a rollup table to improve query performance. This PR adds new database models and refactors the tree details summary view to use pre-aggregated data instead of computing statistics on-the-fly.

Changes

  • Add tests_rollup and modify pending_test table for storing pre-aggregated test data
  • Add treeDetailsRollup helper module with data transformation and aggregation logic
  • Create optimized tree queries in queries/tree.py for fetching rollup data
  • Refactor treeDetailsSummaryView to use denormalized rollup data instead of raw test queries

How to test

  1. Run migrations to create new tables: poetry run python manage.py migrate
  2. Start the aggregation processor: poetry run python manage.py process_pending_aggregations
  3. Navigate to a tree details page and verify the summary loads correctly
  4. Check that test statistics (pass/fail counts, durations) are accurate in the summary view
  5. Verify the aggregation command processes pending tests and updates rollup tables

Related issues

Closes #1801

@gustavobtflores gustavobtflores force-pushed the feat/tree-details-denormalization branch 3 times, most recently from 644025c to 0330580 Compare March 12, 2026 16:24
@MarceloRobert MarceloRobert added Backend Most or all of the changes for this issue will be in the backend code. Frontend Most or all of the changes for this issue will be in the frontend code. Queries Issue that involves modifying some DB query labels Mar 12, 2026
Copy link
Contributor

@alanpeixinho alanpeixinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job.


checkout = build.checkout
path = test.path or ""
path_group = path.split(".", 1)[0] if path else "-"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we could build a helper function for this kind of string manipulation.

issue_version = issue_info["issue_version"] if issue_info else None
issue_uncategorized = issue_id is None and test.full_status == "FAIL"

arch = build.architecture or "Unknown"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer the UNKNOWN constant here.
Or (not for this PR) should we invest in some input sanitization? this way we could avoid Nones and other invalid states.

for test in tests:
checkout = test.build.checkout
path = test.path or ""
path_group = path.split(".", 1)[0] if path else "-"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we could build a helper function for this kind of string manipulation.

config = test.build.config_name or "Unknown"
is_boot = bool(path) and path.startswith("boot")

rollup_key = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why we need to create a tuple, instead of using the Rollup object here.



class TestsRollup(models.Model):
origin = models.TextField()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't varchar be preferable for the smaller strings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

varchar and text have similar performance in Postgres, and the origin field varies in size, so I think keeping text here is okay


return incidents

def create_tests_rollup(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this function could mostly be shared with the one in process_pending_aggregation

@gustavobtflores gustavobtflores force-pushed the feat/tree-details-denormalization branch 4 times, most recently from f03087d to 21a7f67 Compare March 19, 2026 00:44
status=simplify_status(t.status),
is_boot=is_boot(t.path) if t.path else False,
path=t.path,
duration=t.duration,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PendingTest has no duration field, this is breaking the ingester because the model is not expecting this field

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, forgot to remove it after we decide to not have duration in the rollup table

@gustavobtflores gustavobtflores force-pushed the feat/tree-details-denormalization branch from 82a0ed5 to 1ecfc60 Compare March 20, 2026 15:48
@gustavobtflores gustavobtflores force-pushed the feat/tree-details-denormalization branch from 1ecfc60 to 169c461 Compare March 20, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend Most or all of the changes for this issue will be in the backend code. Frontend Most or all of the changes for this issue will be in the frontend code. Queries Issue that involves modifying some DB query

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: denormalize tree details with rollup table to improve summary performance

3 participants