2026-03-30 00:54:20 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
2026-03-17 08:49:55 +00:00
|
|
|
|
|
|
|
|
package agentci
|
|
|
|
|
|
|
|
|
|
import (
|
2026-04-01 06:53:33 +00:00
|
|
|
"context"
|
2026-03-17 08:49:55 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestSanitizePath_Good(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
input string
|
|
|
|
|
want string
|
|
|
|
|
}{
|
|
|
|
|
{"simple", "simple"},
|
|
|
|
|
{"with-dash", "with-dash"},
|
|
|
|
|
{"with_underscore", "with_underscore"},
|
|
|
|
|
{"with.dot", "with.dot"},
|
|
|
|
|
{"CamelCase", "CamelCase"},
|
|
|
|
|
{"123", "123"},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
|
|
|
got, err := SanitizePath(tt.input)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Equal(t, tt.want, got)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSanitizePath_Bad(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
input string
|
|
|
|
|
}{
|
|
|
|
|
{"spaces", "has space"},
|
|
|
|
|
{"special chars", "file@name"},
|
|
|
|
|
{"backtick", "file`name"},
|
|
|
|
|
{"semicolon", "file;name"},
|
|
|
|
|
{"pipe", "file|name"},
|
|
|
|
|
{"ampersand", "file&name"},
|
|
|
|
|
{"dollar", "file$name"},
|
2026-03-29 23:59:48 +00:00
|
|
|
{"slash", "path/to/file.txt"},
|
|
|
|
|
{"backslash", `path\to\file.txt`},
|
2026-03-17 08:49:55 +00:00
|
|
|
{"parent traversal base", ".."},
|
|
|
|
|
{"root", "/"},
|
2026-03-29 23:59:48 +00:00
|
|
|
{"empty", ""},
|
2026-03-17 08:49:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
_, err := SanitizePath(tt.input)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestEscapeShellArg_Good(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
input string
|
|
|
|
|
want string
|
|
|
|
|
}{
|
|
|
|
|
{"simple", "'simple'"},
|
|
|
|
|
{"with spaces", "'with spaces'"},
|
|
|
|
|
{"it's", "'it'\\''s'"},
|
|
|
|
|
{"", "''"},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
|
|
|
assert.Equal(t, tt.want, EscapeShellArg(tt.input))
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSecureSSHCommand_Good(t *testing.T) {
|
|
|
|
|
cmd := SecureSSHCommand("host.example.com", "ls -la")
|
|
|
|
|
args := cmd.Args
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, "ssh", args[0])
|
|
|
|
|
assert.Contains(t, args, "-o")
|
|
|
|
|
assert.Contains(t, args, "StrictHostKeyChecking=yes")
|
|
|
|
|
assert.Contains(t, args, "BatchMode=yes")
|
|
|
|
|
assert.Contains(t, args, "ConnectTimeout=10")
|
|
|
|
|
assert.Equal(t, "host.example.com", args[len(args)-2])
|
|
|
|
|
assert.Equal(t, "ls -la", args[len(args)-1])
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-01 06:53:33 +00:00
|
|
|
func TestSecureSSHCommandContext_Good(t *testing.T) {
|
|
|
|
|
cmd := SecureSSHCommandContext(context.Background(), "host.example.com", "ls -la")
|
|
|
|
|
args := cmd.Args
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, "ssh", args[0])
|
|
|
|
|
assert.Contains(t, args, "-o")
|
|
|
|
|
assert.Contains(t, args, "StrictHostKeyChecking=yes")
|
|
|
|
|
assert.Contains(t, args, "BatchMode=yes")
|
|
|
|
|
assert.Contains(t, args, "ConnectTimeout=10")
|
|
|
|
|
assert.Equal(t, "host.example.com", args[len(args)-2])
|
|
|
|
|
assert.Equal(t, "ls -la", args[len(args)-1])
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-17 08:49:55 +00:00
|
|
|
func TestMaskToken_Good(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
input string
|
|
|
|
|
want string
|
|
|
|
|
}{
|
|
|
|
|
{"long token", "abcdefghijklmnop", "abcd****mnop"},
|
|
|
|
|
{"exactly 8", "12345678", "1234****5678"},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
assert.Equal(t, tt.want, MaskToken(tt.input))
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestMaskToken_Bad(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
input string
|
|
|
|
|
}{
|
|
|
|
|
{"short", "abc"},
|
|
|
|
|
{"empty", ""},
|
|
|
|
|
{"seven chars", "1234567"},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
assert.Equal(t, "*****", MaskToken(tt.input))
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|