mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
- shim: make system executable resolution injectable so tests pass under umask 002; skip the root-owner test when running as root - doctor: treat resolution into either the system or per-user shim dir as intercepted, and collapse the shim-in-PATH check to a single call site - setup: make remove (both --system and per-user) best-effort with errors.Join so one failed step no longer strands the other artifact - shim: allow a group-writable install parent dir (Debian/Ubuntu ship /usr/local/bin as root:staff 2775) while still rejecting world-writable and non-root-owned parents - audit: attribute cloud events to SUDO_USER when running under sudo - docs: drop the soft-fail event-logging claim (hard-fail is retained)
105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
package setup
|
|
|
|
import (
|
|
"os/exec"
|
|
"testing"
|
|
|
|
"github.com/safedep/pmg/internal/doctor"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestPathContainsDir(t *testing.T) {
|
|
assert.True(t, pathContainsDir([]string{"/usr/local/lib/pmg/bin/"}, "/usr/local/lib/pmg/bin"))
|
|
assert.False(t, pathContainsDir([]string{"/usr/local/bin"}, "/usr/local/lib/pmg/bin"))
|
|
assert.False(t, pathContainsDir([]string{"/usr/bin"}, ""))
|
|
}
|
|
|
|
func TestPathIsUnderDir(t *testing.T) {
|
|
assert.True(t, pathIsUnderDir("/usr/local/lib/pmg/bin/npm", "/usr/local/lib/pmg/bin"))
|
|
assert.False(t, pathIsUnderDir("/usr/local/bin/npm", "/usr/local/lib/pmg/bin"))
|
|
assert.False(t, pathIsUnderDir("/usr/local/lib/pmg/bin-extra/npm", "/usr/local/lib/pmg/bin"))
|
|
}
|
|
|
|
func TestSystemInstallAliasesPassDoesNotActivateInterception(t *testing.T) {
|
|
results := []doctor.CheckResult{
|
|
{Name: checkShellAliases, Status: doctor.StatusPass, Message: "No aliases (system install)"},
|
|
{Name: checkShimInPath, Status: doctor.StatusFail},
|
|
}
|
|
|
|
assert.False(t, isInterceptionActive(results))
|
|
}
|
|
|
|
func TestAliasesInstalledActivatesInterception(t *testing.T) {
|
|
results := []doctor.CheckResult{
|
|
{
|
|
Name: checkShellAliases,
|
|
Status: doctor.StatusPass,
|
|
Message: aliasesInstalledMessage,
|
|
ImpliesInterception: true,
|
|
},
|
|
{Name: checkShimInPath, Status: doctor.StatusFail},
|
|
}
|
|
|
|
assert.True(t, isInterceptionActive(results))
|
|
}
|
|
|
|
func TestShimInPathImpliesInterception(t *testing.T) {
|
|
results := []doctor.CheckResult{
|
|
{
|
|
Name: checkShimInPath,
|
|
Status: doctor.StatusPass,
|
|
Message: "Package managers resolve to System shim directory",
|
|
ImpliesInterception: true,
|
|
},
|
|
}
|
|
|
|
assert.True(t, isInterceptionActive(results))
|
|
}
|
|
|
|
func TestClassifyPackageManagerResolutions(t *testing.T) {
|
|
shimDir := "/usr/local/lib/pmg/bin"
|
|
lookPath := func(name string) (string, error) {
|
|
switch name {
|
|
case "npm":
|
|
return shimDir + "/npm", nil
|
|
case "pip":
|
|
return "/usr/bin/pip", nil
|
|
case "uv":
|
|
return "", exec.ErrNotFound
|
|
default:
|
|
return "", exec.ErrNotFound
|
|
}
|
|
}
|
|
|
|
under, shadowed := classifyPackageManagerResolutions(
|
|
[]string{"npm", "pip", "uv"},
|
|
[]string{shimDir},
|
|
lookPath,
|
|
)
|
|
assert.Equal(t, []string{"npm"}, under)
|
|
assert.Equal(t, []string{"pip"}, shadowed)
|
|
}
|
|
|
|
func TestClassifyPackageManagerResolutionsAcceptsEitherShimDir(t *testing.T) {
|
|
systemDir := "/usr/local/lib/pmg/bin"
|
|
userDir := "/home/dev/.pmg/bin"
|
|
lookPath := func(name string) (string, error) {
|
|
switch name {
|
|
case "npm":
|
|
return systemDir + "/npm", nil
|
|
case "pip":
|
|
return userDir + "/pip", nil
|
|
default:
|
|
return "/usr/bin/" + name, nil
|
|
}
|
|
}
|
|
|
|
under, shadowed := classifyPackageManagerResolutions(
|
|
[]string{"npm", "pip", "yarn"},
|
|
[]string{systemDir, userDir},
|
|
lookPath,
|
|
)
|
|
assert.ElementsMatch(t, []string{"npm", "pip"}, under)
|
|
assert.Equal(t, []string{"yarn"}, shadowed)
|
|
}
|