Skip to content

Commit 0c082f1

Browse files
🟢 Add tests for sysInfoHeader and product overwrite fields
Add product name, version, and build fields to ClientSysInfo to allow callers to overwrite the default mql identity in upstream headers. Add comprehensive test coverage for sysInfoHeader including product overwrites, partial fields, and fallback behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f2644a0 commit 0c082f1

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

utils/ranger/plugins.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ type ClientSysInfo struct {
2121
IP string
2222
Hostname string
2323
PlatformID string
24+
// the product using the header. e.g. 'mql' or 'cnspec'. if not set,
25+
// defaults to 'mql'.
26+
ProductName string
27+
// the version of the product, e.g. '13.0.0'. if not set, defaults to the mql version.
28+
ProductVersion string
29+
// the build of the product, e.g. 'ab1f1'. if not set, defaults to the mql build.
30+
ProductBuild string
2431
}
2532

2633
func DefaultRangerPlugins(features mql.Features, si *ClientSysInfo) []ranger.ClientPlugin {
@@ -39,15 +46,23 @@ func sysInfoHeader(features mql.Features, si *ClientSysInfo) ranger.ClientPlugin
3946

4047
h := http.Header{}
4148
info := map[string]string{
49+
// these might get overwritten down below if details are provided
4250
"mql": mql.Version,
4351
"build": mql.Build,
4452
}
53+
4554
if si != nil {
4655
info["PN"] = si.PlatformName
4756
info["PR"] = si.PlatformVersion
4857
info["PA"] = si.PlatformArch
4958
info["IP"] = si.IP
5059
info["HN"] = si.Hostname
60+
if si.ProductName != "" && si.ProductVersion != "" {
61+
info[si.ProductName] = si.ProductVersion
62+
}
63+
if si.ProductBuild != "" {
64+
info["build"] = si.ProductBuild
65+
}
5166
h.Set(HttpHeaderPlatformID, si.PlatformID)
5267
}
5368

utils/ranger/plugins_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) Mondoo, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package ranger
5+
6+
import (
7+
"runtime"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
"go.mondoo.com/mql/v13"
13+
"go.mondoo.com/ranger-rpc/plugins/scope"
14+
)
15+
16+
func TestSysInfoHeader(t *testing.T) {
17+
t.Run("nil sysinfo defaults PN to GOOS", func(t *testing.T) {
18+
plugin := sysInfoHeader(mql.Features{}, nil)
19+
h := plugin.GetHeader(nil)
20+
21+
parsed, err := scope.ParseXInfoHeader(h.Get("User-Agent"))
22+
require.NoError(t, err)
23+
24+
assert.Equal(t, mql.Version, parsed["mql"])
25+
assert.Equal(t, mql.Build, parsed["build"])
26+
assert.Equal(t, runtime.GOOS, parsed["PN"])
27+
})
28+
29+
t.Run("populates all sysinfo fields", func(t *testing.T) {
30+
si := &ClientSysInfo{
31+
PlatformName: "ubuntu",
32+
PlatformVersion: "22.04",
33+
PlatformArch: "amd64",
34+
IP: "10.0.0.1",
35+
Hostname: "myhost",
36+
PlatformID: "platform-123",
37+
ProductName: "cnspec",
38+
ProductVersion: "9.1.0",
39+
ProductBuild: "deadbeef",
40+
}
41+
plugin := sysInfoHeader(mql.Features{}, si)
42+
h := plugin.GetHeader(nil)
43+
44+
parsed, err := scope.ParseXInfoHeader(h.Get("User-Agent"))
45+
require.NoError(t, err)
46+
47+
assert.Equal(t, "ubuntu", parsed["PN"])
48+
assert.Equal(t, "22.04", parsed["PR"])
49+
assert.Equal(t, "amd64", parsed["PA"])
50+
assert.Equal(t, "10.0.0.1", parsed["IP"])
51+
assert.Equal(t, "myhost", parsed["HN"])
52+
assert.Equal(t, mql.Version, parsed["mql"])
53+
assert.Equal(t, "9.1.0", parsed["cnspec"])
54+
assert.Equal(t, "deadbeef", parsed["build"])
55+
assert.Equal(t, "platform-123", h.Get("Mondoo-PlatformID"))
56+
})
57+
58+
t.Run("product name without version is ignored", func(t *testing.T) {
59+
si := &ClientSysInfo{
60+
PlatformName: "debian",
61+
ProductName: "cnspec",
62+
}
63+
plugin := sysInfoHeader(mql.Features{}, si)
64+
h := plugin.GetHeader(nil)
65+
66+
parsed, err := scope.ParseXInfoHeader(h.Get("User-Agent"))
67+
require.NoError(t, err)
68+
69+
_, hasProduct := parsed["cnspec"]
70+
assert.False(t, hasProduct, "product should not be added when version is empty")
71+
assert.Equal(t, mql.Version, parsed["mql"], "mql version should still be present")
72+
})
73+
74+
t.Run("product version without name is ignored", func(t *testing.T) {
75+
si := &ClientSysInfo{
76+
PlatformName: "debian",
77+
ProductVersion: "9.1.0",
78+
}
79+
plugin := sysInfoHeader(mql.Features{}, si)
80+
h := plugin.GetHeader(nil)
81+
82+
parsed, err := scope.ParseXInfoHeader(h.Get("User-Agent"))
83+
require.NoError(t, err)
84+
85+
_, hasEmpty := parsed[""]
86+
assert.False(t, hasEmpty, "empty product name should not be added as a key")
87+
assert.Equal(t, mql.Version, parsed["mql"], "mql version should still be present")
88+
})
89+
90+
t.Run("empty platform name defaults to GOOS", func(t *testing.T) {
91+
si := &ClientSysInfo{PlatformName: ""}
92+
plugin := sysInfoHeader(mql.Features{}, si)
93+
h := plugin.GetHeader(nil)
94+
95+
parsed, err := scope.ParseXInfoHeader(h.Get("User-Agent"))
96+
require.NoError(t, err)
97+
98+
assert.Equal(t, runtime.GOOS, parsed["PN"])
99+
})
100+
}

0 commit comments

Comments
 (0)