Skip to content

Conversation

@ctron
Copy link
Contributor

@ctron ctron commented Dec 8, 2025

TC-3286 is about the fact that processing of q works differently for the DB implementation than it does for the in-memory implementation. This lead to weird behavior in the past. Both implementations must be aligned to prevent this in the future.

This test gives an example. The test is expected to fail with the current codebase.

Summary by Sourcery

Align graph query handling with shared graph cache and add regression test ensuring DB and in-memory q query logic stay consistent.

Enhancements:

  • Refactor analysis service to use its internal graph cache and expose a helper for loading graphs by query.
  • Add utility to escape values for use in q parameters.

Tests:

  • Add integration test comparing SBOM selection via DB q filtering and in-memory graph query to prevent divergence between implementations.

@ctron ctron requested a review from jcrossley3 December 8, 2025 09:50
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 8, 2025

Reviewer's Guide

Adds a regression-style test to reproduce TC-3286, ensuring DB and in-memory query logic stay aligned, refactors AnalysisService graph-query helpers to reuse the internal graph cache instead of passing it around, and exposes a helper to load graphs directly for tests.

Sequence diagram for updated run_graph_query using internal graph_cache

sequenceDiagram
    actor Test as TestCode
    participant AS as AnalysisService
    participant ASI as AnalysisServiceInner
    participant DB as ConnectionTrait
    participant PG as PackageGraph
    participant GC as GraphMap

    Test->>AS: run_graph_query(query, options, graphs, connection)
    activate AS
    AS->>DB: use connection with graphs
    loop for each graph in graphs
        AS->>ASI: access graph_cache
        ASI-->>AS: Arc_GraphMap_
        AS->>GC: lookup relationships for node
        GC-->>AS: cached_result or miss
        AS->>PG: traverse graph with relationships
        PG-->>AS: matching_nodes
    end
    AS-->>Test: Vec_Node_
    deactivate AS
Loading

Class diagram for updated AnalysisService graph query helpers

classDiagram
    class AnalysisService {
        +concurrency: usize
        -inner: AnalysisServiceInner
        +run_graph_query<C>(query: GraphQuery, options: QueryOptions, graphs: Vec_PackageGraph_, connection: C) Result_Vec_Node__Error_
        +load_graphs_query(connection: ConnectionTrait, query: GraphQuery) Result_Vec_PackageGraph__Error_
    }

    class AnalysisServiceInner {
        +graph_cache: Arc_GraphMap_
        +load_graphs_query(connection: ConnectionTrait, query: GraphQuery) Result_Vec_PackageGraph__Error_
    }

    class GraphQuery {
    }

    class QueryOptions {
        +relationships: Relationships
    }

    class PackageGraph {
    }

    class GraphMap {
    }

    class Node {
    }

    class Relationships {
    }

    class ConnectionTrait {
    }

    class Error {
    }

    class Uuid {
    }

    AnalysisService --> AnalysisServiceInner : inner
    AnalysisServiceInner --> GraphMap : graph_cache
    AnalysisService --> PackageGraph : uses
    AnalysisService --> GraphQuery : uses
    AnalysisService --> QueryOptions : uses
    AnalysisService --> ConnectionTrait : uses
    AnalysisService --> Node : returns
    AnalysisService --> Error : returns
    AnalysisService --> Uuid : uses
    AnalysisServiceInner --> ConnectionTrait : uses
    AnalysisServiceInner --> PackageGraph : returns
Loading

File-Level Changes

Change Details Files
Refactor graph query helpers to use internal graph cache and expose a graph-loading helper.
  • Remove the graph_cache parameter from run_graph_query and obtain the cache from self.inner.graph_cache inside the closure.
  • Update callers of run_graph_query in AnalysisService methods to stop passing a graph cache explicitly.
  • Add a new pub(crate) load_graphs_query method on AnalysisService that forwards to inner.load_graphs_query.
  • Adjust instrumentation attributes to match the new run_graph_query signature and avoid skipping graph_cache.
modules/analysis/src/service/mod.rs
Introduce a helper for escaping q parameters for tests.
  • Add escape_q utility that escapes backslashes, ampersands, and equals signs for use in q query parameters.
modules/analysis/src/test.rs
Add a regression test to compare DB and in-memory query behavior for q processing.
  • Create a new query test module under the service tests and register it in the test mod.
  • Ingest a sample CycloneDX document via TrustifyContext to set up test data.
  • Use load_graphs_query to compute SBOM IDs via DB filtering and run_graph_query plus in-memory filtering over all graphs to compute SBOM IDs in memory.
  • Compare the two SBOM ID sets and assert they are equal and match the expected count for a given escaped q value.
modules/analysis/src/service/test/mod.rs
modules/analysis/src/service/test/query.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The new helper escape_q is only used in tests; consider moving it into the test module (or making it #[cfg(test)]) to avoid expanding the public API surface unnecessarily.
  • The test test_circular_deps_cyclonedx_service_count name no longer reflects what it checks (DB vs in-memory q handling); renaming it to something like db_and_in_memory_query_alignment would make its purpose clearer.
  • Now that run_graph_query always uses self.inner.graph_cache, you might add a brief comment on why bypassing a passed-in cache is intentional to avoid future refactors reintroducing divergence between implementations.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new helper `escape_q` is only used in tests; consider moving it into the test module (or making it `#[cfg(test)]`) to avoid expanding the public API surface unnecessarily.
- The test `test_circular_deps_cyclonedx_service_count` name no longer reflects what it checks (DB vs in-memory `q` handling); renaming it to something like `db_and_in_memory_query_alignment` would make its purpose clearer.
- Now that `run_graph_query` always uses `self.inner.graph_cache`, you might add a brief comment on why bypassing a passed-in cache is intentional to avoid future refactors reintroducing divergence between implementations.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@jcrossley3 jcrossley3 left a comment

Choose a reason for hiding this comment

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

Thanks for the tests! I have questions...

@codecov
Copy link

codecov bot commented Dec 9, 2025

Codecov Report

❌ Patch coverage is 89.63415% with 17 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@545028c). Learn more about missing BASE report.

Files with missing lines Patch % Lines
common/src/cpe.rs 76.92% 9 Missing ⚠️
common/src/db/query/columns.rs 78.57% 0 Missing and 3 partials ⚠️
common/src/db/query/value.rs 93.33% 3 Missing ⚠️
modules/ingestor/src/graph/sbom/cyclonedx.rs 85.71% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2171   +/-   ##
=======================================
  Coverage        ?   68.37%           
=======================================
  Files           ?      377           
  Lines           ?    21282           
  Branches        ?    21282           
=======================================
  Hits            ?    14552           
  Misses          ?     5858           
  Partials        ?      872           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jcrossley3
Copy link
Contributor

/scale-test

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🛠️ Scale test has started! Follow the progress here: Workflow Run

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

Goose Report

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 25-12-09 21:14:32 25-12-09 21:14:39 00:00:07 0 → 7
Maintaining 25-12-09 21:14:39 25-12-09 21:19:39 00:05:00 7
Decreasing 25-12-09 21:19:39 25-12-09 21:19:59 00:00:20 0 ← 7

Request Metrics

Method Name # Requests # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 38 (0) 0 933.26 (-65.89) 117 (+12) 2683 (-462) 0.13 (+0.00) 0.00 (+0.00)
GET download_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 (0) 10 20.70 (-0.60) 2 (0) 62 (-36) 0.03 (+0.00) 0.03 (+0.00)
GET get_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 (0) 10 17.30 (+11.40) 1 (0) 119 (+102) 0.03 (+0.00) 0.03 (+0.00)
GET get_advisory_by_doc_id 10 (0) 0 16.20 (-16.00) 3 (-2) 83 (-36) 0.03 (+0.00) 0.00 (+0.00)
GET get_analysis_latest_cpe 15 (+1) 0 292.13 (-89.72) 183 (+56) 572 (-129) 0.05 (+0.00) 0.00 (+0.00)
GET get_analysis_status 15 (+1) 0 20.00 (+7.71) 2 (+1) 59 (-2) 0.05 (+0.00) 0.00 (+0.00)
GET get_purl_details[b00df2ca-df21-5…874-304e9c54e2bd] 10 (0) 0 811.50 (+73.60) 98 (+20) 1288 (-134) 0.03 (+0.00) 0.00 (+0.00)
GET get_sbom[sha256:720e4451…a939656247164447] 15 (+5) 0 1350.67 (+299.07) 344 (-277) 3013 (+1229) 0.05 (+0.02) 0.00 (+0.00)
GET get_sbom_advisories[sha256:87fd06bc…9d7b8304c0d2d9b2] 15 (+5) 0 58112.46 (+907.77) 46884 (-1711) 68147 (+4714) 0.05 (+0.02) 0.00 (+0.00)
GET get_sbom_license_ids[urn:uuid:019731…104-331632a21144] 10 (0) 0 8187.80 (-1168.80) 4566 (-2117) 12131 (-3080) 0.03 (+0.00) 0.00 (+0.00)
GET list_advisory 10 (0) 0 915.70 (-68.50) 169 (-103) 1480 (-292) 0.03 (+0.00) 0.00 (+0.00)
GET list_advisory_labels 15 (+1) 0 15801.20 (+2193.13) 11491 (+1506) 21799 (+821) 0.05 (+0.00) 0.00 (+0.00)
GET list_advisory_paginated 10 (0) 0 605.20 (+69.70) 141 (-84) 1072 (+356) 0.03 (+0.00) 0.00 (+0.00)
GET list_importer 11 (0) 0 2.73 (-1.09) 1 (0) 4 (-4) 0.04 (+0.00) 0.00 (+0.00)
GET list_organizations 10 (0) 0 12.40 (-8.70) 2 (0) 48 (-4) 0.03 (+0.00) 0.00 (+0.00)
GET list_packages 11 (0) 0 390.45 (-54.55) 160 (+53) 590 (-319) 0.04 (+0.00) 0.00 (+0.00)
GET list_packages_paginated 11 (0) 0 413.18 (+118.09) 179 (+49) 709 (+210) 0.04 (+0.00) 0.00 (+0.00)
GET list_products 15 (0) 0 8.27 (-4.53) 3 (-1) 17 (-9) 0.05 (+0.00) 0.00 (+0.00)
GET list_sboms 15 (0) 0 1326.87 (-13.47) 550 (-159) 2681 (-1045) 0.05 (+0.00) 0.00 (+0.00)
GET list_sboms_paginated 15 (0) 0 1346.67 (-3719.67) 332 (-203) 2506 (-6561) 0.05 (+0.00) 0.00 (+0.00)
GET list_vulnerabilities 11 (+1) 0 327.45 (-194.95) 93 (-45) 792 (-217) 0.04 (+0.00) 0.00 (+0.00)
GET list_vulnerabilities_paginated 11 (0) 0 183.36 (-58.73) 47 (-9) 292 (-29) 0.04 (+0.00) 0.00 (+0.00)
GET sbom_by_package[pkg:maven/io.qu…dhat.com%2fga%2f] 10 (0) 0 56.80 (-0.60) 9 (-6) 122 (+6) 0.03 (+0.00) 0.00 (+0.00)
GET search_advisory 10 (0) 0 827.90 (-641.60) 169 (-224) 1682 (-314) 0.03 (+0.00) 0.00 (+0.00)
GET search_exact_purl 15 (0) 0 28.73 (-31.67) 4 (-3) 56 (-43) 0.05 (+0.00) 0.00 (+0.00)
GET search_licenses 1 (-1) 0 99012.00 (+48417.00) 99012 (+55275) 99012 (+41559) 0.00 (-0.00) 0.00 (+0.00)
GET search_purls 15 (0) 0 17705.73 (-16936.27) 9755 (-16076) 24953 (-15715) 0.05 (+0.00) 0.00 (+0.00)
GET search_purls_by_license 1 (0) 0 158926.00 (+39600.00) 158926 (+39600) 158926 (+39600) 0.00 (+0.00) 0.00 (+0.00)
GET search_sboms_by_license 1 (-1) 0 63630.00 (+10215.00) 63630 (+27147) 63630 (-6717) 0.00 (-0.00) 0.00 (+0.00)
POST get_recommendations[pkg:rpm/redhat/…[email protected]] 10 (0) 0 68.00 (-68.10) 6 (-1) 122 (-156) 0.03 (+0.00) 0.00 (+0.00)
POST post_vulnerability_analyze[pkg:rpm/redhat/…h=noarch&epoch=1] 10 (0) 0 489.20 (-21.80) 50 (-94) 801 (-410) 0.03 (+0.00) 0.00 (+0.00)
Aggregated 366 (+12) 20 5277.87 (-133.13) 1 (0) 158926 (+39600) 1.22 (+0.04) 0.07 (+0.00)

Response Time Metrics

Method Name 50%ile (ms) 60%ile (ms) 70%ile (ms) 80%ile (ms) 90%ile (ms) 95%ile (ms) 99%ile (ms) 100%ile (ms)
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 700 (0) 1,000 (0) 1,000 (0) 1,000 (0) 2,000 (0) 2,000 (-1,000) 2,683 (-317) 2,683 (-317)
GET download_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 6 (-3) 7 (-5) 7 (-8) 52 (+34) 60 (+22) 62 (-36) 62 (-36) 62 (-36)
GET get_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 2 (0) 3 (+1) 5 (0) 18 (+7) 19 (+2) 119 (+102) 119 (+102) 119 (+102)
GET get_advisory_by_doc_id 6 (-11) 9 (-8) 10 (-10) 11 (-42) 26 (-37) 83 (-36) 83 (-36) 83 (-36)
GET get_analysis_latest_cpe 260 (-100) 300 (-80) 330 (-60) 340 (-70) 420 (-280) 420 (-280) 572 (-128) 572 (-128)
GET get_analysis_status 6 (0) 6 (0) 38 (+30) 44 (+36) 59 (+10) 59 (+10) 59 (-2) 59 (-2)
GET get_purl_details[b00df2ca-df21-5…874-304e9c54e2bd] 700 (+100) 1,000 (+100) 1,000 (+100) 1,000 (+100) 1,000 (0) 1,000 (0) 1,000 (0) 1,000 (0)
GET get_sbom[sha256:720e4451…a939656247164447] 1,000 (+300) 2,000 (+1,000) 2,000 (+1,000) 2,000 (+1,000) 2,000 (+216) 2,000 (+216) 3,000 (+1,216) 3,000 (+1,216)
GET get_sbom_advisories[sha256:87fd06bc…9d7b8304c0d2d9b2] 58,000 (+1,000) 60,000 (+2,000) 63,000 (+4,000) 63,000 (0) 64,000 (+1,000) 64,000 (+1,000) 68,000 (+5,000) 68,000 (+5,000)
GET get_sbom_license_ids[urn:uuid:019731…104-331632a21144] 8,000 (0) 8,000 (0) 8,000 (0) 9,000 (-3,000) 11,000 (-2,000) 12,000 (-3,000) 12,000 (-3,000) 12,000 (-3,000)
GET list_advisory 1,000 (+300) 1,000 (+200) 1,000 (+200) 1,000 (-772) 1,000 (-772) 1,000 (-772) 1,000 (-772) 1,000 (-772)
GET list_advisory_labels 15,000 (+4,000) 15,000 (+3,000) 19,000 (+6,000) 20,000 (+3,000) 21,000 (+2,000) 21,000 (+2,000) 21,799 (+821) 21,799 (+821)
GET list_advisory_paginated 700 (+100) 700 (+100) 700 (+100) 700 (0) 800 (+100) 1,000 (+300) 1,000 (+300) 1,000 (+300)
GET list_importer 3 (0) 3 (-1) 3 (-1) 3 (-3) 4 (-4) 4 (-4) 4 (-4) 4 (-4)
GET list_organizations 5 (-5) 7 (-6) 7 (-14) 7 (-37) 36 (-13) 48 (-4) 48 (-4) 48 (-4)
GET list_packages 410 (-10) 450 (-50) 490 (-110) 500 (-100) 590 (-10) 590 (-10) 590 (-310) 590 (-310)
GET list_packages_paginated 400 (+70) 480 (+110) 490 (+110) 500 (+120) 600 (+200) 600 (+200) 700 (+201) 700 (+201)
GET list_products 8 (-4) 9 (-3) 9 (-5) 9 (-8) 10 (-8) 10 (-8) 17 (-9) 17 (-9)
GET list_sboms 900 (0) 900 (-100) 2,000 (+1,000) 2,000 (0) 2,681 (+681) 2,681 (+681) 2,681 (-1,045) 2,681 (-1,045)
GET list_sboms_paginated 1,000 (-4,000) 1,000 (-4,000) 1,000 (-5,000) 2,000 (-5,000) 2,000 (-5,000) 2,000 (-5,000) 2,506 (-6,494) 2,506 (-6,494)
GET list_vulnerabilities 290 (-120) 290 (-120) 320 (-100) 430 (-570) 430 (-570) 430 (-570) 792 (-208) 792 (-208)
GET list_vulnerabilities_paginated 140 (-150) 190 (-110) 270 (-40) 290 (-20) 290 (-30) 290 (-30) 290 (-30) 290 (-30)
GET sbom_by_package[pkg:maven/io.qu…dhat.com%2fga%2f] 51 (+11) 53 (+7) 64 (-26) 99 (+8) 120 (+10) 120 (+4) 120 (+4) 120 (+4)
GET search_advisory 500 (-1,496) 600 (-1,396) 800 (-1,196) 1,000 (-996) 1,682 (-314) 1,682 (-314) 1,682 (-314) 1,682 (-314)
GET search_exact_purl 15 (-63) 45 (-33) 52 (-28) 54 (-41) 55 (-44) 55 (-44) 56 (-43) 56 (-43)
GET search_licenses 99,012 (+55,012) 99,012 (+55,012) 99,012 (+55,012) 99,012 (+42,012) 99,012 (+42,012) 99,012 (+42,012) 99,012 (+42,012) 99,012 (+42,012)
GET search_purls 15,000 (-19,000) 16,000 (-18,000) 23,000 (-17,000) 24,953 (-15,047) 24,953 (-15,715) 24,953 (-15,715) 24,953 (-15,715) 24,953 (-15,715)
GET search_purls_by_license 158,926 (+39,600) 158,926 (+39,600) 158,926 (+39,600) 158,926 (+39,600) 158,926 (+39,600) 158,926 (+39,600) 158,926 (+39,600) 158,926 (+39,600)
GET search_sboms_by_license 63,630 (+27,147) 63,630 (+27,147) 63,630 (+27,147) 63,630 (-6,370) 63,630 (-6,370) 63,630 (-6,370) 63,630 (-6,370) 63,630 (-6,370)
POST get_recommendations[pkg:rpm/redhat/…[email protected]] 52 (-58) 98 (-12) 99 (-21) 100 (-170) 110 (-168) 120 (-158) 120 (-158) 120 (-158)
POST post_vulnerability_analyze[pkg:rpm/redhat/…h=noarch&epoch=1] 600 (+300) 600 (+260) 600 (0) 800 (0) 800 (-200) 800 (-200) 800 (-200) 800 (-200)
Aggregated 420 (+10) 600 (-100) 1,000 (0) 2,000 (0) 15,000 (+2,000) 25,000 (-15,000) 64,000 (+1,000) 158,926 (+39,926)

Status Code Metrics

Method Name Status Codes
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 38 [200]
GET download_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 [404]
GET get_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 [404]
GET get_advisory_by_doc_id 10 [200]
GET get_analysis_latest_cpe 15 [200]
GET get_analysis_status 15 [200]
GET get_purl_details[b00df2ca-df21-5…874-304e9c54e2bd] 10 [200]
GET get_sbom[sha256:720e4451…a939656247164447] 15 [200]
GET get_sbom_advisories[sha256:87fd06bc…9d7b8304c0d2d9b2] 15 [200]
GET get_sbom_license_ids[urn:uuid:019731…104-331632a21144] 10 [200]
GET list_advisory 10 [200]
GET list_advisory_labels 15 [200]
GET list_advisory_paginated 10 [200]
GET list_importer 11 [200]
GET list_organizations 10 [200]
GET list_packages 11 [200]
GET list_packages_paginated 11 [200]
GET list_products 15 [200]
GET list_sboms 15 [200]
GET list_sboms_paginated 15 [200]
GET list_vulnerabilities 11 [200]
GET list_vulnerabilities_paginated 11 [200]
GET sbom_by_package[pkg:maven/io.qu…dhat.com%2fga%2f] 10 [200]
GET search_advisory 10 [200]
GET search_exact_purl 15 [200]
GET search_licenses 1 [200]
GET search_purls 15 [200]
GET search_purls_by_license 1 [200]
GET search_sboms_by_license 1 [200]
POST get_recommendations[pkg:rpm/redhat/…[email protected]] 10 [200]
POST post_vulnerability_analyze[pkg:rpm/redhat/…h=noarch&epoch=1] 10 [200]
Aggregated 346 [200], 20 [404]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
WebsiteUser
0.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.1 website_index 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.2 website_openapi 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.3 website_sboms 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.4 website_packages 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.5 website_advisories 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.6 website_importers 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUser
1.0 logon 10 (0) 0 (0) 14.40 (+1.30) 8 (-1) 19 (-3) 0.03 (+0.00) 0.00 (+0.00)
1.1 list_organizations 10 (0) 0 (0) 12.40 (-8.90) 2 (0) 48 (-4) 0.03 (+0.00) 0.00 (+0.00)
1.2 list_advisory 10 (0) 0 (0) 915.80 (-68.50) 169 (-103) 1480 (-293) 0.03 (+0.00) 0.00 (+0.00)
1.3 list_advisory_paginated 10 (0) 0 (0) 605.20 (+69.70) 141 (-84) 1072 (+356) 0.03 (+0.00) 0.00 (+0.00)
1.4 get_advisory_by_doc_id 10 (0) 0 (0) 16.20 (-16.00) 3 (-2) 83 (-36) 0.03 (+0.00) 0.00 (+0.00)
1.5 search_advisory 10 (0) 0 (0) 828.00 (-641.50) 170 (-223) 1682 (-314) 0.03 (+0.00) 0.00 (+0.00)
1.6 list_vulnerabilities 11 (+1) 0 (0) 327.55 (-194.85) 93 (-45) 792 (-217) 0.04 (+0.00) 0.00 (+0.00)
1.7 list_vulnerabilities_paginated 11 (0) 0 (0) 183.36 (-58.73) 47 (-9) 292 (-29) 0.04 (+0.00) 0.00 (+0.00)
1.8 list_importer 11 (0) 0 (0) 2.82 (-1.00) 1 (0) 5 (-3) 0.04 (+0.00) 0.00 (+0.00)
1.9 list_packages 11 (0) 0 (0) 390.55 (-54.55) 160 (+53) 590 (-320) 0.04 (+0.00) 0.00 (+0.00)
1.10 list_packages_paginated 11 (0) 0 (0) 413.36 (+118.27) 179 (+49) 710 (+211) 0.04 (+0.00) 0.00 (+0.00)
1.11 search_purls 15 (0) 0 (0) 17705.80 (-16936.20) 9755 (-16076) 24953 (-15715) 0.05 (+0.00) 0.00 (+0.00)
1.12 search_exact_purl 15 (0) 0 (0) 28.87 (-31.60) 4 (-3) 56 (-43) 0.05 (+0.00) 0.00 (+0.00)
1.13 list_products 15 (0) 0 (0) 8.33 (-4.47) 4 (0) 17 (-9) 0.05 (+0.00) 0.00 (+0.00)
1.14 list_sboms 15 (0) 0 (0) 1326.93 (-13.47) 550 (-159) 2681 (-1045) 0.05 (+0.00) 0.00 (+0.00)
1.15 list_sboms_paginated 15 (0) 0 (0) 1346.73 (-3719.60) 332 (-203) 2506 (-6561) 0.05 (+0.00) 0.00 (+0.00)
1.16 get_analysis_status 15 (+1) 0 (0) 20.07 (+7.78) 2 (+1) 59 (-2) 0.05 (+0.00) 0.00 (+0.00)
1.17 get_analysis_latest_cpe 15 (+1) 0 (0) 292.13 (-89.80) 183 (+56) 572 (-129) 0.05 (+0.00) 0.00 (+0.00)
1.18 list_advisory_labels 15 (+1) 0 (0) 15801.20 (+2192.91) 11491 (+1506) 21799 (+820) 0.05 (+0.00) 0.00 (+0.00)
1.19 get_sbom[sha256:720e4451…a939656247164447] 15 (+5) 0 (0) 1350.87 (+299.17) 344 (-277) 3013 (+1229) 0.05 (+0.02) 0.00 (+0.00)
1.20 get_sbom_advisories[sha256:87fd06bc…9d7b8304c0d2d9b2] 15 (+5) 0 (0) 58112.54 (+907.84) 46884 (-1711) 68147 (+4714) 0.05 (+0.02) 0.00 (+0.00)
1.21 sbom_by_package[pkg:maven/io.qu…dhat.com%2fga%2f] 10 (0) 0 (0) 56.90 (-0.50) 9 (-6) 122 (+6) 0.03 (+0.00) 0.00 (+0.00)
1.22 get_sbom_license_ids[urn:uuid:019731…104-331632a21144] 10 (0) 0 (0) 8187.90 (-1168.80) 4567 (-2116) 12131 (-3080) 0.03 (+0.00) 0.00 (+0.00)
1.23 post_vulnerability_analyze[pkg:rpm/redhat/…h=noarch&epoch=1] 10 (0) 0 (0) 489.20 (-21.80) 50 (-94) 801 (-410) 0.03 (+0.00) 0.00 (+0.00)
1.24 get_purl_details[b00df2ca-df21-5…874-304e9c54e2bd] 10 (0) 0 (0) 811.50 (+73.40) 98 (+20) 1288 (-134) 0.03 (+0.00) 0.00 (+0.00)
1.25 get_recommendations[pkg:rpm/redhat/…[email protected]] 10 (0) 0 (0) 68.10 (-68.20) 7 (0) 122 (-156) 0.03 (+0.00) 0.00 (+0.00)
1.26 download_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 (0) 0 (0) 20.80 (-0.50) 2 (0) 62 (-36) 0.03 (+0.00) 0.00 (+0.00)
1.27 get_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 (0) 0 (0) 17.30 (+11.30) 1 (0) 119 (+102) 0.03 (+0.00) 0.00 (+0.00)
RestAPIUserSlow
2.0 logon 0 (-1) 0 (0) 0.00 (-18.00) 0 (-18) 0 (-18) 0.00 (-0.00) 0.00 (+0.00)
2.1 search_licenses 1 (-1) 0 (0) 99012.00 (+48417.00) 99012 (+55275) 99012 (+41559) 0.00 (-0.00) 0.00 (+0.00)
2.2 search_sboms_by_license 1 (-1) 0 (0) 63630.00 (+10214.50) 63630 (+27147) 63630 (-6718) 0.00 (-0.00) 0.00 (+0.00)
2.3 search_purls_by_license 1 (0) 0 (0) 158926.00 (+39600.00) 158926 (+39600) 158926 (+39600) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUserDelete
3.0 logon 38 (+1) 0 (0) 9.71 (+0.60) 6 (0) 18 (0) 0.13 (+0.00) 0.00 (+0.00)
3.1 delete_sbom_from_pool_sequential[100 SBOMs] 38 (0) 0 (0) 933.50 (-65.87) 117 (+12) 2684 (-461) 0.13 (+0.00) 0.00 (+0.00)
Aggregated 414 (+12) 0 (0) 4665.94 (-98.97) 1 (0) 158926 (+39600) 1.38 (+0.04) 0.00 (+0.00)

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
WebsiteUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUser 5 (0) 10 (0) 106926.90 (-21637.20) 99641 (-19054) 112212 (-27048) 0.03 (+0.00) 2.00 (+0.00)
RestAPIUserSlow 0 (-1) 0 (-1) 0.00 (-247136.00) 0 (-247136) 0 (-247136) 0.00 (-0.00) 0.00 (-1.00)
RestAPIUserDelete 1 (0) 38 (+1) 7979.97 (-13.84) 6786 (+399) 9765 (-594) 0.13 (+0.00) 38.00 (+1.00)
Aggregated 6 (-1) 48 (0) 28593.92 (-9500.83) 6786 (+399) 112212 (-134924) 0.16 (+0.00) 40.00 (+0.00)

Error Metrics

Method Name # Error
GET download_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 (0) 404 Not Found: download_advisory[24ae57c3-4b57-4…2c1-83ae26059a89]
GET get_advisory[24ae57c3-4b57-4…2c1-83ae26059a89] 10 (0) 404 Not Found: get_advisory[24ae57c3-4b57-4…2c1-83ae26059a89]

📄 Full Report (Go to "Artifacts" and download report)

Comment on lines 19 to 26
#[case( // purl partial search
Req { what: What::Q("pkg:oci/quay-builder-qemu-rhcos-rhel8"), ancestors: Some(10), ..Req::default() },
8
18
)]
#[case( // purl partial search latest
Req { what: What::Q("pkg:oci/quay-builder-qemu-rhcos-rhel8"), ancestors: Some(10), latest: true, ..Req::default() },
2
5
)]
Copy link
Contributor

Choose a reason for hiding this comment

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

@ctron @JimFuller-RedHat Before we merge this PR, I'd like you guys to confirm this change to expected results, given that we've restored the ability to find matches of PURL's in full-text searches. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do not think this is what we want. Testing for purl~ should be good enough. Also for performance reasons.

Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting. If I prefix the above queries with purl~ I get 16 for the first one and 5 for the second. Why do you expect 8 and 2 for full-text searches of a purl? Shouldn't both be 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because in the case of purl~, you're actually searching PURLs. While in the case of not providing any field, it's not searching PURLs. But finding "purl like content" in other fields (like name).

I think this shows that using q without a field is highly confusing, to all of us.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this shows that using q without a field is highly confusing, to all of us.

All of who? 'q' supports two types of searches: full-text and field. It's conceptually very simple and not confusing at all for a large number of use cases.

I would describe what you're asking for as a "partial text search". That's beyond the scope of 'q' and you should probably use something else.

Copy link
Contributor Author

@ctron ctron left a comment

Choose a reason for hiding this comment

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

As said before, I an against add this complexity for no reason. purl~ seems to work just fine. We advise anyway to go away from the default field search because it's to indeterministic for the user and has performance impacts. The ask is to align both implementation, which can also be done by just dropping purl from the default fields of the in-memory implementation.

Comment on lines 19 to 26
#[case( // purl partial search
Req { what: What::Q("pkg:oci/quay-builder-qemu-rhcos-rhel8"), ancestors: Some(10), ..Req::default() },
8
18
)]
#[case( // purl partial search latest
Req { what: What::Q("pkg:oci/quay-builder-qemu-rhcos-rhel8"), ancestors: Some(10), latest: true, ..Req::default() },
2
5
)]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do not think this is what we want. Testing for purl~ should be good enough. Also for performance reasons.

ctron and others added 9 commits December 11, 2025 13:13
TC-3286 is about the fact that processing of `q` works differently for
the DB implementation than it does for the in-memory implementation.
This lead to weird behavior in the past. Both implementations must be
aligned to prevent this in the future.

This test gives an example. The test is expected to fail with the
current codebase.
We can add whatever else we need to the context as the need arises
This fixes the alignment test, but it changed some expected results in
a couple of other tests.
Copy link
Contributor Author

@ctron ctron left a comment

Choose a reason for hiding this comment

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

I'm ok merging this. I can't approve as it's my own PR.

I'd also want @JimFuller-RedHat to perform a review.

This required allowing optional table name prefixes in field queries.

We also DRY'd up a bit more of the common CPE types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants