2023-10-03 10:47:09 +00:00
|
|
|
//go:build unix
|
|
|
|
|
|
|
|
package python
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestAtLeastOnePythonInstalled(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
all, err := DetectInterpreters(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
a := all.Latest()
|
|
|
|
t.Logf("latest is: %s", a)
|
|
|
|
assert.True(t, len(all) > 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNoInterpretersFound(t *testing.T) {
|
|
|
|
t.Setenv("PATH", t.TempDir())
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
all, err := DetectInterpreters(ctx)
|
|
|
|
assert.Nil(t, all)
|
|
|
|
assert.Equal(t, ErrNoPythonInterpreters, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFilteringInterpreters(t *testing.T) {
|
|
|
|
rogueBin := filepath.Join(t.TempDir(), "rogue-bin")
|
|
|
|
err := os.Mkdir(rogueBin, 0o777)
|
|
|
|
assert.NoError(t, err)
|
2024-12-09 12:56:41 +00:00
|
|
|
err = os.Chmod(rogueBin, 0o777)
|
|
|
|
assert.NoError(t, err)
|
2023-10-03 10:47:09 +00:00
|
|
|
|
|
|
|
raw, err := os.ReadFile("testdata/world-writeable/python8.4")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
injectedBinary := filepath.Join(rogueBin, "python8.4")
|
|
|
|
err = os.WriteFile(injectedBinary, raw, 00777)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
t.Setenv("PATH", "testdata/other-binaries-filtered:"+rogueBin)
|
|
|
|
|
|
|
|
roguePath, err := exec.LookPath("python8.4")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, injectedBinary, roguePath)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
all, err := DetectInterpreters(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Len(t, all, 3)
|
|
|
|
assert.Equal(t, "v2.7.18", all[0].Version)
|
|
|
|
assert.Equal(t, "v3.10.5", all[1].Version)
|
|
|
|
assert.Equal(t, "testdata/other-binaries-filtered/python3.10", all[1].Path)
|
|
|
|
assert.Equal(t, "v3.11.4", all[2].Version)
|
|
|
|
assert.Equal(t, "testdata/other-binaries-filtered/real-python3.11.4", all[2].Path)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpretersAtLeastInvalidSemver(t *testing.T) {
|
|
|
|
t.Setenv("PATH", "testdata/other-binaries-filtered")
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
all, err := DetectInterpreters(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = all.AtLeast("v1.2.3.4")
|
|
|
|
assert.EqualError(t, err, "invalid SemVer: v1.2.3.4")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpretersAtLeast(t *testing.T) {
|
|
|
|
t.Setenv("PATH", "testdata/other-binaries-filtered")
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
all, err := DetectInterpreters(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
interpreter, err := all.AtLeast("3.10")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "testdata/other-binaries-filtered/python3.10", interpreter.Path)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpretersAtLeastNotSatisfied(t *testing.T) {
|
|
|
|
t.Setenv("PATH", "testdata/other-binaries-filtered")
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
all, err := DetectInterpreters(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = all.AtLeast("4.0.1")
|
|
|
|
assert.EqualError(t, err, "cannot find Python greater or equal to v4.0.1")
|
|
|
|
}
|