mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
ff9ed91811
This makes it so we can test it directly without having to go through Tailnet, which appears to be causing flakes in CI where the requests time out and never make it to the agent. Takes inspiration from the container-related API endpoints. Would probably make sense to refactor the ls tests to also go through the API (rather than be internal tests like they are currently) but I left those alone for now to keep the diff minimal.
247 lines
5.6 KiB
Go
247 lines
5.6 KiB
Go
package agentfiles
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/spf13/afero"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/codersdk/workspacesdk"
|
|
)
|
|
|
|
type testFs struct {
|
|
afero.Fs
|
|
}
|
|
|
|
func newTestFs(base afero.Fs) *testFs {
|
|
return &testFs{
|
|
Fs: base,
|
|
}
|
|
}
|
|
|
|
func (*testFs) Open(name string) (afero.File, error) {
|
|
return nil, os.ErrPermission
|
|
}
|
|
|
|
func TestListFilesWithQueryParam(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
query := workspacesdk.LSRequest{}
|
|
_, err := listFiles(fs, "not-relative", query)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "must be absolute")
|
|
|
|
tmpDir := t.TempDir()
|
|
err = fs.MkdirAll(tmpDir, 0o755)
|
|
require.NoError(t, err)
|
|
|
|
res, err := listFiles(fs, tmpDir, query)
|
|
require.NoError(t, err)
|
|
require.Len(t, res.Contents, 0)
|
|
}
|
|
|
|
func TestListFilesNonExistentDirectory(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
query := workspacesdk.LSRequest{
|
|
Path: []string{"idontexist"},
|
|
Relativity: workspacesdk.LSRelativityHome,
|
|
}
|
|
_, err := listFiles(fs, "", query)
|
|
require.ErrorIs(t, err, os.ErrNotExist)
|
|
}
|
|
|
|
func TestListFilesPermissionDenied(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := newTestFs(afero.NewMemMapFs())
|
|
home, err := os.UserHomeDir()
|
|
require.NoError(t, err)
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
reposDir := filepath.Join(tmpDir, "repos")
|
|
err = fs.MkdirAll(reposDir, 0o000)
|
|
require.NoError(t, err)
|
|
|
|
rel, err := filepath.Rel(home, reposDir)
|
|
require.NoError(t, err)
|
|
|
|
query := workspacesdk.LSRequest{
|
|
Path: pathToArray(rel),
|
|
Relativity: workspacesdk.LSRelativityHome,
|
|
}
|
|
_, err = listFiles(fs, "", query)
|
|
require.ErrorIs(t, err, os.ErrPermission)
|
|
}
|
|
|
|
func TestListFilesNotADirectory(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
home, err := os.UserHomeDir()
|
|
require.NoError(t, err)
|
|
|
|
tmpDir := t.TempDir()
|
|
err = fs.MkdirAll(tmpDir, 0o755)
|
|
require.NoError(t, err)
|
|
|
|
filePath := filepath.Join(tmpDir, "file.txt")
|
|
err = afero.WriteFile(fs, filePath, []byte("content"), 0o600)
|
|
require.NoError(t, err)
|
|
|
|
rel, err := filepath.Rel(home, filePath)
|
|
require.NoError(t, err)
|
|
|
|
query := workspacesdk.LSRequest{
|
|
Path: pathToArray(rel),
|
|
Relativity: workspacesdk.LSRelativityHome,
|
|
}
|
|
_, err = listFiles(fs, "", query)
|
|
require.ErrorContains(t, err, "is not a directory")
|
|
}
|
|
|
|
func TestListFilesSuccess(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tc := []struct {
|
|
name string
|
|
baseFunc func(t *testing.T) string
|
|
relativity workspacesdk.LSRelativity
|
|
}{
|
|
{
|
|
name: "home",
|
|
baseFunc: func(t *testing.T) string {
|
|
home, err := os.UserHomeDir()
|
|
require.NoError(t, err)
|
|
return home
|
|
},
|
|
relativity: workspacesdk.LSRelativityHome,
|
|
},
|
|
{
|
|
name: "root",
|
|
baseFunc: func(*testing.T) string {
|
|
if runtime.GOOS == "windows" {
|
|
return ""
|
|
}
|
|
return "/"
|
|
},
|
|
relativity: workspacesdk.LSRelativityRoot,
|
|
},
|
|
}
|
|
|
|
// nolint:paralleltest // Not since Go v1.22.
|
|
for _, tc := range tc {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
base := tc.baseFunc(t)
|
|
tmpDir := t.TempDir()
|
|
|
|
reposDir := filepath.Join(tmpDir, "repos")
|
|
err := fs.MkdirAll(reposDir, 0o755)
|
|
require.NoError(t, err)
|
|
|
|
downloadsDir := filepath.Join(tmpDir, "Downloads")
|
|
err = fs.MkdirAll(downloadsDir, 0o755)
|
|
require.NoError(t, err)
|
|
|
|
textFile := filepath.Join(tmpDir, "file.txt")
|
|
err = afero.WriteFile(fs, textFile, []byte("content"), 0o600)
|
|
require.NoError(t, err)
|
|
|
|
var queryComponents []string
|
|
// We can't get an absolute path relative to empty string on Windows.
|
|
if runtime.GOOS == "windows" && base == "" {
|
|
queryComponents = pathToArray(tmpDir)
|
|
} else {
|
|
rel, err := filepath.Rel(base, tmpDir)
|
|
require.NoError(t, err)
|
|
queryComponents = pathToArray(rel)
|
|
}
|
|
|
|
query := workspacesdk.LSRequest{
|
|
Path: queryComponents,
|
|
Relativity: tc.relativity,
|
|
}
|
|
resp, err := listFiles(fs, "", query)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tmpDir, resp.AbsolutePathString)
|
|
// Output is sorted
|
|
require.Equal(t, []workspacesdk.LSFile{
|
|
{
|
|
Name: "Downloads",
|
|
AbsolutePathString: downloadsDir,
|
|
IsDir: true,
|
|
},
|
|
{
|
|
Name: "repos",
|
|
AbsolutePathString: reposDir,
|
|
IsDir: true,
|
|
},
|
|
{
|
|
Name: "file.txt",
|
|
AbsolutePathString: textFile,
|
|
IsDir: false,
|
|
},
|
|
}, resp.Contents)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListFilesListDrives(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if runtime.GOOS != "windows" {
|
|
t.Skip("skipping test on non-Windows OS")
|
|
}
|
|
|
|
fs := afero.NewOsFs()
|
|
query := workspacesdk.LSRequest{
|
|
Path: []string{},
|
|
Relativity: workspacesdk.LSRelativityRoot,
|
|
}
|
|
resp, err := listFiles(fs, "", query)
|
|
require.NoError(t, err)
|
|
require.Contains(t, resp.Contents, workspacesdk.LSFile{
|
|
Name: "C:\\",
|
|
AbsolutePathString: "C:\\",
|
|
IsDir: true,
|
|
})
|
|
|
|
query = workspacesdk.LSRequest{
|
|
Path: []string{"C:\\"},
|
|
Relativity: workspacesdk.LSRelativityRoot,
|
|
}
|
|
resp, err = listFiles(fs, "", query)
|
|
require.NoError(t, err)
|
|
|
|
query = workspacesdk.LSRequest{
|
|
Path: resp.AbsolutePath,
|
|
Relativity: workspacesdk.LSRelativityRoot,
|
|
}
|
|
resp, err = listFiles(fs, "", query)
|
|
require.NoError(t, err)
|
|
// System directory should always exist
|
|
require.Contains(t, resp.Contents, workspacesdk.LSFile{
|
|
Name: "Windows",
|
|
AbsolutePathString: "C:\\Windows",
|
|
IsDir: true,
|
|
})
|
|
|
|
query = workspacesdk.LSRequest{
|
|
// Network drives are not supported.
|
|
Path: []string{"\\sshfs\\work"},
|
|
Relativity: workspacesdk.LSRelativityRoot,
|
|
}
|
|
resp, err = listFiles(fs, "", query)
|
|
require.ErrorContains(t, err, "drive")
|
|
}
|