Skip to content

Fixed issue where different variations of the same software weren't linked to the same software title. - #38926

Merged
getvictor merged 5 commits into
mainfrom
victor/36494-software-without-title
Jan 30, 2026
Merged

Fixed issue where different variations of the same software weren't linked to the same software title.#38926
getvictor merged 5 commits into
mainfrom
victor/36494-software-without-title

Conversation

@getvictor

@getvictor getvictor commented Jan 28, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #36494

Fixes:

  • Allow matching software to title solely by non-empty upgrade code
  • Match names case-insentive and trimmed whitespace and special unicode characters (in our osquery-perf dataset)
  • Match bundle ID case-insensitive

Checklist for submitter

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

  • Bug Fixes

    • Different variations/versions of the same software that share the same upgrade code are now unified under a single software title, preventing duplicate titles and improving linkage across releases.
  • Tests

    • Added a test verifying that entries with the same upgrade code but different names link to an existing shared title.

✏️ Tip: You can customize this high-level summary in your review settings.

@codecov

codecov Bot commented Jan 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.11%. Comparing base (5c11a9f) to head (92bd29a).
⚠️ Report is 108 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #38926      +/-   ##
==========================================
+ Coverage   66.10%   66.11%   +0.01%     
==========================================
  Files        2420     2421       +1     
  Lines      193439   193874     +435     
  Branches     8434     8434              
==========================================
+ Hits       127865   128186     +321     
- Misses      53970    54043      +73     
- Partials    11604    11645      +41     
Flag Coverage Δ
backend 67.95% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@getvictor getvictor changed the title Fixed issue where different versions of the same Windows software weren't linked to the same software title. Fixed issue where different variations of the same software weren't linked to the same software title. Jan 28, 2026
@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Collects non-empty Windows MSI upgrade_code values during pre-insert and extends software_title lookup/mapping to match titles by upgrade_code in addition to name/bundle_identifier/source/extension_for, allowing different-named variants sharing an upgrade_code to link to the same software_title.

Changes

Cohort / File(s) Summary
Changelog
changes/victor/36494-software-without-title
Adds changelog entry for the software title linking fix.
Core Logic
server/datastore/mysql/software.go
Collects non-empty upgrade_code values for Windows programs in pre-insert; extends title lookup to include upgrade_code arguments and query placeholders; maps incoming titles to existing titles by upgrade_code when both sides provide codes; trims Name during comparisons; preserves case-insensitive bundle_identifier handling.
Tests
server/datastore/mysql/software_upgrade_code_test.go
Adds testSameUpgradeCodeDifferentNames and a new case in TestSoftwareUpgradeCode to ensure entries with the same upgrade_code but different names link to a single shared software_title.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • sgress454
  • lucasmrod
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: fixing issue where different software variations weren't linked to the same title.
Linked Issues check ✅ Passed Code changes directly address issue #36494 by implementing upgrade_code-based matching to resolve software linking errors and reduce log noise.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the issue: upgrade_code matching logic, improved name/bundle_id comparison, related tests, and changes file.
Description check ✅ Passed The PR description is mostly complete with related issue, fixes explained, and relevant checklist items checked, though some sections could be more detailed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch victor/36494-software-without-title

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/datastore/mysql/software.go (1)

996-1071: Make upgrade_code matching case‑insensitive to avoid orphaned titles.

The new upgrade_code path compares raw strings. If hosts report GUIDs with different casing, MySQL’s case‑insensitive collation will still return the title, but the Go‑side comparison will fail and the software can be inserted with a NULL title_id (reintroducing the log noise this PR aims to fix). Normalize upgrade_code before comparison (and consider the same normalization in reconcileExistingTitleEmptyWindowsUpgradeCodes conflict checks).

🛠️ Suggested fix (normalize upgrade_code before comparing)
-					var titleSummaryUpgradeCode string
-					if titleSummary.UpgradeCode != nil {
-						titleSummaryUpgradeCode = *titleSummary.UpgradeCode
-					}
+					var titleSummaryUpgradeCode string
+					if titleSummary.UpgradeCode != nil {
+						titleSummaryUpgradeCode = strings.ToLower(*titleSummary.UpgradeCode)
+					}
 					for checksum, title := range newTitlesNeeded {
 						var titleBundleID string
 						if title.BundleIdentifier != nil {
 							titleBundleID = *title.BundleIdentifier
 						}
-						var titleUpgradeCode string
-						if title.UpgradeCode != nil {
-							titleUpgradeCode = *title.UpgradeCode
-						}
+						var titleUpgradeCode string
+						if title.UpgradeCode != nil {
+							titleUpgradeCode = strings.ToLower(*title.UpgradeCode)
+						}
 						// For apps with bundle_identifier, match by bundle_identifier (since we may have picked a different name)
 						// For Windows programs with upgrade_code, match by upgrade_code (names may differ between versions)
 						// For others, match by name (case-insensitive to match MySQL collation)
 						// We also trim whitespace to handle data quality issues (e.g., trailing spaces).
 						nameMatches := strings.EqualFold(strings.TrimSpace(titleSummary.Name), strings.TrimSpace(title.Name))
 						if bundleID != "" && titleBundleID != "" {
 							// Both have bundle_identifier - match by bundle_identifier instead of name
 							nameMatches = true
 						}
-						if titleUpgradeCode != "" && titleSummaryUpgradeCode != "" && titleUpgradeCode == titleSummaryUpgradeCode {
+						if titleUpgradeCode != "" && titleSummaryUpgradeCode != "" && titleUpgradeCode == titleSummaryUpgradeCode {
 							// Both have non-empty upgrade_code and they match: consider it a match
 							// This handles the case where different versions of Windows software have
 							// different names (e.g., "7-Zip 24.08 (x64)" vs "7-Zip 24.09 (x64 edition)") but share the same upgrade_code
 							nameMatches = true
 						}
🧹 Nitpick comments (1)
server/datastore/mysql/software_upgrade_code_test.go (1)

465-551: Consider covering case‑only upgrade_code differences.

This test validates identical upgrade_code values with the same casing. Adding a quick variant where the second host reports a differently cased GUID would guard against case‑sensitivity regressions.

// no-op code change
// TODO(jacob) - this var name is shadowing the one in the outer scope. Is this successfully
// adding titles-by-checksum for software with bundle ids?
incomingChecksumsToTitleSummaries = make(map[string]fleet.SoftwareTitleSummary, len(newSoftwareChecksums))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was clearing the values populated above.

@getvictor
getvictor marked this pull request as ready for review January 28, 2026 22:49
@getvictor
getvictor requested a review from a team as a code owner January 28, 2026 22:49

@ksykulev ksykulev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One quick question

Comment thread server/datastore/mysql/software.go Outdated
@getvictor
getvictor merged commit 2196a18 into main Jan 30, 2026
45 checks passed
@getvictor
getvictor deleted the victor/36494-software-without-title branch January 30, 2026 22:04
@coderabbitai coderabbitai Bot mentioned this pull request Mar 22, 2026
4 tasks
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.

error inserting software without title_id is logged for numerous software titles in the loadtest environment

2 participants