Update CI pipeline to use Go 1.25.8, enhance Definition of Done with SonarQube checks, refactor SID allocation in Windows functions, and improve test coverage for JoiningSlash function.

This commit is contained in:
Stefan Goppelt 2026-03-29 14:54:31 +02:00
parent 1da053fb67
commit 8ace13074f
7 changed files with 38 additions and 31 deletions

View File

@ -4,7 +4,7 @@ name: go-lib/util
steps: steps:
- name: test - name: test
image: golang:1.18 image: golang:1.25.8
commands: commands:
- go get ./... - go get ./...
- go test ./... - go test ./...

View File

@ -69,6 +69,9 @@ The Definition of Done defines the minimum quality bar for every completed chang
- No new blocking errors are introduced. - No new blocking errors are introduced.
- Known non-blocking warnings are acceptable only if unrelated to the change or documented. - Known non-blocking warnings are acceptable only if unrelated to the change or documented.
1. SonarQube status
- No SonarQube errors are present.
1. Documentation structure 1. Documentation structure
- Links to moved or newly added docs are valid. - Links to moved or newly added docs are valid.
- Documentation structure remains consistent with project rules. - Documentation structure remains consistent with project rules.
@ -81,4 +84,5 @@ The Definition of Done defines the minimum quality bar for every completed chang
- [ ] Functionality is documented. - [ ] Functionality is documented.
- [ ] Documentation is in English. - [ ] Documentation is in English.
- [ ] Documentation is located under `docs/` (except `README.md` and `AGENTS.md`). - [ ] Documentation is located under `docs/` (except `README.md` and `AGENTS.md`).
- [ ] No SonarQube errors are present.
- [ ] No critical regressions found. - [ ] No critical regressions found.

View File

@ -32,6 +32,9 @@ This Definition of Done defines the minimum quality bar for every completed chan
- No new blocking errors are introduced. - No new blocking errors are introduced.
- Known non-blocking warnings are acceptable only if unrelated to the change or documented. - Known non-blocking warnings are acceptable only if unrelated to the change or documented.
1. SonarQube status
- No SonarQube errors are present.
1. Documentation links and structure 1. Documentation links and structure
- Links to moved or newly added docs are valid. - Links to moved or newly added docs are valid.
- Documentation structure remains consistent with project rules. - Documentation structure remains consistent with project rules.
@ -45,4 +48,5 @@ This Definition of Done defines the minimum quality bar for every completed chan
- [ ] Functionality is documented. - [ ] Functionality is documented.
- [ ] Documentation is in English. - [ ] Documentation is in English.
- [ ] Documentation is located under `docs/` (except `README.md` and `AGENTS.md`). - [ ] Documentation is located under `docs/` (except `README.md` and `AGENTS.md`).
- [ ] No SonarQube errors are present.
- [ ] No critical regressions found. - [ ] No critical regressions found.

View File

@ -13,6 +13,16 @@ import (
var ( var (
allocateAndInitializeSid = windows.AllocateAndInitializeSid allocateAndInitializeSid = windows.AllocateAndInitializeSid
allocateAdminGroupSid = func(sid **windows.SID) error {
return allocateAndInitializeSid(
&windows.SECURITY_NT_AUTHORITY,
2,
windows.SECURITY_BUILTIN_DOMAIN_RID,
windows.DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
sid,
)
}
freeSid = windows.FreeSid freeSid = windows.FreeSid
tokenIsMember = func(token windows.Token, sid *windows.SID) (bool, error) { return token.IsMember(sid) } tokenIsMember = func(token windows.Token, sid *windows.SID) (bool, error) { return token.IsMember(sid) }
fatalf = log.Fatalf fatalf = log.Fatalf
@ -27,13 +37,7 @@ func IsSuperUser() bool {
// official windows documentation. The Go API for this is a // official windows documentation. The Go API for this is a
// direct wrap around the official C++ API. // direct wrap around the official C++ API.
// See https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership // See https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership
err := allocateAndInitializeSid( err := allocateAdminGroupSid(&sid)
&windows.SECURITY_NT_AUTHORITY,
2,
windows.SECURITY_BUILTIN_DOMAIN_RID,
windows.DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&sid)
if err != nil { if err != nil {
fatalf("SID Error: %s", err) fatalf("SID Error: %s", err)
return false return false

View File

@ -13,31 +13,19 @@ import (
func TestIsSuperUser_SidAllocationError(t *testing.T) { func TestIsSuperUser_SidAllocationError(t *testing.T) {
Convey("IsSuperUser should return false when SID allocation fails", t, func() { Convey("IsSuperUser should return false when SID allocation fails", t, func() {
origAllocate := allocateAndInitializeSid origAllocate := allocateAdminGroupSid
origFatalf := fatalf origFatalf := fatalf
defer func() { defer func() {
allocateAndInitializeSid = origAllocate allocateAdminGroupSid = origAllocate
fatalf = origFatalf fatalf = origFatalf
}() }()
allocateAndInitializeSid = func( allocateAdminGroupSid = func(_ **windows.SID) error {
authority *windows.SidIdentifierAuthority,
subAuthorityCount byte,
subAuthority0 uint32,
subAuthority1 uint32,
subAuthority2 uint32,
subAuthority3 uint32,
subAuthority4 uint32,
subAuthority5 uint32,
subAuthority6 uint32,
subAuthority7 uint32,
sid **windows.SID,
) error {
return errors.New("forced sid allocation error") return errors.New("forced sid allocation error")
} }
fatalCalled := false fatalCalled := false
fatalf = func(format string, v ...interface{}) { fatalf = func(_ string, _ ...interface{}) {
fatalCalled = true fatalCalled = true
} }

View File

@ -34,7 +34,6 @@ func joiningSlash(elem []string) string {
} }
func singleJoiningSlash(a, b string) string { func singleJoiningSlash(a, b string) string {
filepath.Join(a, b)
aslash := strings.HasSuffix(a, "/") aslash := strings.HasSuffix(a, "/")
bslash := strings.HasPrefix(b, "/") bslash := strings.HasPrefix(b, "/")
switch { switch {

View File

@ -23,12 +23,20 @@ func TestFileExists(t *testing.T) {
func TestJoiningSlash(t *testing.T) { func TestJoiningSlash(t *testing.T) {
Convey("JoiningSlash should combine URL-like segments safely", t, func() { Convey("JoiningSlash should combine URL-like segments safely", t, func() {
So(JoiningSlash("http://my.tld/docs/", "bla/", "blub/"), ShouldEqual, "http://my.tld/docs/bla/blub/") const (
So(JoiningSlash("http://my.tld", "bla", "blub"), ShouldEqual, "http://my.tld/bla/blub") baseURL = "http://my.tld"
So(JoiningSlash("http://my.tld/", "bla", "blub"), ShouldEqual, "http://my.tld/bla/blub") docsURL = "http://my.tld/docs"
So(JoiningSlash("http://my.tld", "bla/", "blub"), ShouldEqual, "http://my.tld/bla/blub") expectedRoot = "http://my.tld/bla/blub"
So(JoiningSlash("http://my.tld/docs", "bla/", "blub"), ShouldEqual, "http://my.tld/docs/bla/blub") expectedDocs = "http://my.tld/docs/bla/blub"
So(JoiningSlash("http://my.tld/docs/", "bla/", "blub"), ShouldEqual, "http://my.tld/docs/bla/blub") expectedDocsS = "http://my.tld/docs/bla/blub/"
)
So(JoiningSlash(docsURL+"/", "bla/", "blub/"), ShouldEqual, expectedDocsS)
So(JoiningSlash(baseURL, "bla", "blub"), ShouldEqual, expectedRoot)
So(JoiningSlash(baseURL+"/", "bla", "blub"), ShouldEqual, expectedRoot)
So(JoiningSlash(baseURL, "bla/", "blub"), ShouldEqual, expectedRoot)
So(JoiningSlash(docsURL, "bla/", "blub"), ShouldEqual, expectedDocs)
So(JoiningSlash(docsURL+"/", "bla/", "blub"), ShouldEqual, expectedDocs)
So(JoiningSlash("", "api", "v1"), ShouldEqual, "api/v1") So(JoiningSlash("", "api", "v1"), ShouldEqual, "api/v1")
So(JoiningSlash("", "", ""), ShouldEqual, "") So(JoiningSlash("", "", ""), ShouldEqual, "")
}) })