From 8b7f61902db49b1bd0732cd439eda8a899060cd8 Mon Sep 17 00:00:00 2001 From: Mihail Stoykov Date: Wed, 19 Apr 2023 18:53:24 +0300 Subject: [PATCH] Hide afero behind fsext package This is mostly so that no other part by `fsext` knows anything about afero. In the future we can replace the actual implementation. Updates #1079 --- cmd/archive_test.go | 16 +++---- cmd/config.go | 6 +-- cmd/config_consolidation_test.go | 12 ++--- cmd/convert.go | 10 ++--- cmd/convert_test.go | 12 ++--- cmd/panic_integration_test.go | 4 +- cmd/run.go | 4 +- cmd/run_test.go | 17 ++++--- cmd/runtime_options_test.go | 10 ++--- cmd/state/state.go | 6 +-- cmd/test_load.go | 8 ++-- cmd/tests/cmd_cloud_test.go | 4 +- cmd/tests/cmd_run_test.go | 24 +++++----- cmd/tests/test_state.go | 4 +- cmd/tests/tracing_module_test.go | 20 ++++----- js/bundle.go | 8 ++-- js/bundle_test.go | 33 +++++++------- js/common/initenv.go | 8 ++-- js/console_test.go | 8 ++-- js/init_and_modules_test.go | 4 +- js/initcontext.go | 19 ++++---- js/initcontext_test.go | 74 +++++++++++++++---------------- js/module_loading_test.go | 56 +++++++++++------------ js/modules/k6/grpc/client_test.go | 5 +-- js/path_resolution_test.go | 38 ++++++++-------- js/runner.go | 4 +- js/runner_test.go | 53 +++++++++++----------- lib/archive.go | 20 ++++----- lib/archive_test.go | 61 ++++++++++++------------- lib/fsext/afero_links.go | 56 +++++++++++++++++++++++ lib/old_archive_test.go | 11 +++-- loader/cdnjs_test.go | 6 +-- loader/filesystems.go | 10 ++--- loader/github_test.go | 10 ++--- loader/loader.go | 14 +++--- loader/loader_test.go | 24 +++++----- loader/readsource.go | 10 ++--- loader/readsource_test.go | 37 ++++++++-------- log/file.go | 6 +-- log/file_test.go | 4 +- output/csv/output_test.go | 12 ++--- output/json/benchmark_test.go | 4 +- output/json/json_test.go | 8 ++-- output/types.go | 4 +- 44 files changed, 403 insertions(+), 361 deletions(-) create mode 100644 lib/fsext/afero_links.go diff --git a/cmd/archive_test.go b/cmd/archive_test.go index 7a68f168868..29d34a559e5 100644 --- a/cmd/archive_test.go +++ b/cmd/archive_test.go @@ -12,10 +12,10 @@ import ( "syscall" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/require" "go.k6.io/k6/cmd/tests" "go.k6.io/k6/errext/exitcodes" + "go.k6.io/k6/lib/fsext" ) func TestArchiveThresholds(t *testing.T) { @@ -81,7 +81,7 @@ func TestArchiveThresholds(t *testing.T) { require.NoError(t, err) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, testCase.testFilename), testScript, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, testCase.testFilename), testScript, 0o644)) ts.CmdArgs = []string{"k6", "archive", testCase.testFilename} if testCase.noThresholds { ts.CmdArgs = append(ts.CmdArgs, "--no-thresholds") @@ -102,7 +102,7 @@ func TestArchiveContainsEnv(t *testing.T) { fileName := "script.js" testScript := []byte(`export default function () {}`) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, fileName), testScript, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, fileName), testScript, 0o644)) // when we do archiving and passing the `--env` flags ts.CmdArgs = []string{"k6", "--env", "ENV1=lorem", "--env", "ENV2=ipsum", "archive", fileName} @@ -110,7 +110,7 @@ func TestArchiveContainsEnv(t *testing.T) { newRootCommand(ts.GlobalState).execute() require.NoError(t, untar(t, ts.FS, "archive.tar", "tmp/")) - data, err := afero.ReadFile(ts.FS, "tmp/metadata.json") + data, err := fsext.ReadFile(ts.FS, "tmp/metadata.json") require.NoError(t, err) metadata := struct { @@ -135,7 +135,7 @@ func TestArchiveNotContainsEnv(t *testing.T) { fileName := "script.js" testScript := []byte(`export default function () {}`) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, fileName), testScript, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, fileName), testScript, 0o644)) // when we do archiving and passing the `--env` flags altogether with `--exclude-env-vars` flag ts.CmdArgs = []string{"k6", "--env", "ENV1=lorem", "--env", "ENV2=ipsum", "archive", "--exclude-env-vars", fileName} @@ -143,7 +143,7 @@ func TestArchiveNotContainsEnv(t *testing.T) { newRootCommand(ts.GlobalState).execute() require.NoError(t, untar(t, ts.FS, "archive.tar", "tmp/")) - data, err := afero.ReadFile(ts.FS, "tmp/metadata.json") + data, err := fsext.ReadFile(ts.FS, "tmp/metadata.json") require.NoError(t, err) metadata := struct { @@ -156,10 +156,10 @@ func TestArchiveNotContainsEnv(t *testing.T) { } // untar untars a `fileName` file to a `destination` path -func untar(t *testing.T, fileSystem afero.Fs, fileName string, destination string) error { +func untar(t *testing.T, fileSystem fsext.Fs, fileName string, destination string) error { t.Helper() - archiveFile, err := afero.ReadFile(fileSystem, fileName) + archiveFile, err := fsext.ReadFile(fileSystem, fileName) if err != nil { return err } diff --git a/cmd/config.go b/cmd/config.go index 8ba12e66ecb..3aa6237450c 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -11,7 +11,6 @@ import ( "github.com/mstoykov/envconfig" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/spf13/pflag" "gopkg.in/guregu/null.v3" @@ -20,6 +19,7 @@ import ( "go.k6.io/k6/errext/exitcodes" "go.k6.io/k6/lib" "go.k6.io/k6/lib/executor" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/types" "go.k6.io/k6/metrics" ) @@ -116,7 +116,7 @@ func readDiskConfig(gs *state.GlobalState) (Config, error) { return Config{}, err } - data, err := afero.ReadFile(gs.FS, gs.Flags.ConfigFilePath) + data, err := fsext.ReadFile(gs.FS, gs.Flags.ConfigFilePath) if err != nil { return Config{}, fmt.Errorf("couldn't load the configuration from %q: %w", gs.Flags.ConfigFilePath, err) } @@ -140,7 +140,7 @@ func writeDiskConfig(gs *state.GlobalState, conf Config) error { return err } - return afero.WriteFile(gs.FS, gs.Flags.ConfigFilePath, data, 0o644) + return fsext.WriteFile(gs.FS, gs.Flags.ConfigFilePath, data, 0o644) } // Reads configuration variables from the environment. diff --git a/cmd/config_consolidation_test.go b/cmd/config_consolidation_test.go index d82fb66d28c..a4211cfeef1 100644 --- a/cmd/config_consolidation_test.go +++ b/cmd/config_consolidation_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" @@ -14,6 +13,7 @@ import ( "go.k6.io/k6/cmd/tests" "go.k6.io/k6/lib" "go.k6.io/k6/lib/executor" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/types" "go.k6.io/k6/metrics" ) @@ -109,10 +109,10 @@ type file struct { filepath, contents string } -func getFS(files []file) afero.Fs { - fs := afero.NewMemMapFs() +func getFS(files []file) fsext.Fs { + fs := fsext.NewMemMapFs() for _, f := range files { - must(afero.WriteFile(fs, f.filepath, []byte(f.contents), 0o644)) // modes don't matter in the afero.MemMapFs + must(fsext.WriteFile(fs, f.filepath, []byte(f.contents), 0o644)) // modes don't matter in the afero.MemMapFs } return fs } @@ -121,7 +121,7 @@ type opts struct { cli []string env []string runner *lib.Options - fs afero.Fs + fs fsext.Fs cmds []string } @@ -145,7 +145,7 @@ type configConsolidationTestCase struct { func getConfigConsolidationTestCases() []configConsolidationTestCase { defaultFlags := state.GetDefaultFlags(".config") - defaultConfig := func(jsonConfig string) afero.Fs { + defaultConfig := func(jsonConfig string) fsext.Fs { return getFS([]file{{defaultFlags.ConfigFilePath, jsonConfig}}) } I := null.IntFrom // shortcut for "Valid" (i.e. user-specified) ints diff --git a/cmd/convert.go b/cmd/convert.go index 9a3ecccb490..e3fc2ce6bea 100644 --- a/cmd/convert.go +++ b/cmd/convert.go @@ -4,13 +4,13 @@ import ( "encoding/json" "io" - "github.com/spf13/afero" "github.com/spf13/cobra" "gopkg.in/guregu/null.v3" "go.k6.io/k6/cmd/state" "go.k6.io/k6/converter/har" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" ) // TODO: split apart like `k6 run` and `k6 archive`? @@ -34,13 +34,13 @@ func getCmdConvert(gs *state.GlobalState) *cobra.Command { exampleText := getExampleText(gs, ` # Convert a HAR file to a k6 script. {{.}} convert -O har-session.js session.har - + # Convert a HAR file to a k6 script creating requests only for the given domain/s. {{.}} convert -O har-session.js --only yourdomain.com,additionaldomain.com session.har - + # Convert a HAR file. Batching requests together as long as idle time between requests <800ms {{.}} convert --batch-threshold 800 session.har - + # Run the k6 script. {{.}} run har-session.js`[1:]) @@ -69,7 +69,7 @@ func getCmdConvert(gs *state.GlobalState) *cobra.Command { options := lib.Options{MaxRedirects: null.IntFrom(0)} if optionsFilePath != "" { - optionsFileContents, readErr := afero.ReadFile(gs.FS, optionsFilePath) + optionsFileContents, readErr := fsext.ReadFile(gs.FS, optionsFilePath) if readErr != nil { return readErr } diff --git a/cmd/convert_test.go b/cmd/convert_test.go index 57156ee8e93..94719043a7f 100644 --- a/cmd/convert_test.go +++ b/cmd/convert_test.go @@ -6,10 +6,10 @@ import ( "testing" "github.com/pmezard/go-difflib/difflib" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/cmd/tests" + "go.k6.io/k6/lib/fsext" ) const testHAR = ` @@ -109,7 +109,7 @@ func TestConvertCmdCorrelate(t *testing.T) { require.NoError(t, err) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, "correlate.har", har, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, "correlate.har", har, 0o644)) ts.CmdArgs = []string{ "k6", "convert", "--output=result.js", "--correlate=true", "--no-batch=true", "--enable-status-code-checks=true", "--return-on-failed-check=true", "correlate.har", @@ -117,7 +117,7 @@ func TestConvertCmdCorrelate(t *testing.T) { newRootCommand(ts.GlobalState).execute() - result, err := afero.ReadFile(ts.FS, "result.js") + result, err := fsext.ReadFile(ts.FS, "result.js") require.NoError(t, err) // Sanitizing to avoid windows problems with carriage returns @@ -144,7 +144,7 @@ func TestConvertCmdCorrelate(t *testing.T) { func TestConvertCmdStdout(t *testing.T) { t.Parallel() ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, "stdout.har", []byte(testHAR), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, "stdout.har", []byte(testHAR), 0o644)) ts.CmdArgs = []string{"k6", "convert", "stdout.har"} newRootCommand(ts.GlobalState).execute() @@ -155,12 +155,12 @@ func TestConvertCmdOutputFile(t *testing.T) { t.Parallel() ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, "output.har", []byte(testHAR), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, "output.har", []byte(testHAR), 0o644)) ts.CmdArgs = []string{"k6", "convert", "--output", "result.js", "output.har"} newRootCommand(ts.GlobalState).execute() - output, err := afero.ReadFile(ts.FS, "result.js") + output, err := fsext.ReadFile(ts.FS, "result.js") assert.NoError(t, err) assert.Equal(t, testHARConvertResult, string(output)) } diff --git a/cmd/panic_integration_test.go b/cmd/panic_integration_test.go index 03a4bf2258c..40fc9468276 100644 --- a/cmd/panic_integration_test.go +++ b/cmd/panic_integration_test.go @@ -7,12 +7,12 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/cmd/tests" "go.k6.io/k6/errext/exitcodes" "go.k6.io/k6/js/modules" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" ) @@ -86,7 +86,7 @@ func TestRunScriptPanicsErrorsAndAbort(t *testing.T) { testFilename := "script.js" ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, testFilename), []byte(tc.testScript), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, testFilename), []byte(tc.testScript), 0o644)) ts.CmdArgs = []string{"k6", "run", testFilename} ts.ExpectedExitCode = int(exitcodes.ScriptAborted) diff --git a/cmd/run.go b/cmd/run.go index 426bcf9ccc4..8d8c1da5a0f 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -16,7 +16,6 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -28,6 +27,7 @@ import ( "go.k6.io/k6/js/common" "go.k6.io/k6/lib" "go.k6.io/k6/lib/consts" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/metrics" "go.k6.io/k6/metrics/engine" "go.k6.io/k6/output" @@ -422,7 +422,7 @@ func reportUsage(ctx context.Context, execScheduler *execution.Scheduler) error return err } -func handleSummaryResult(fs afero.Fs, stdOut, stdErr io.Writer, result map[string]io.Reader) error { +func handleSummaryResult(fs fsext.Fs, stdOut, stdErr io.Writer, result map[string]io.Reader) error { var errs []error getWriter := func(path string) (io.Writer, error) { diff --git a/cmd/run_test.go b/cmd/run_test.go index 7120fda3f2d..7d8cf91ebad 100644 --- a/cmd/run_test.go +++ b/cmd/run_test.go @@ -13,7 +13,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -38,20 +37,20 @@ func (fw mockWriter) Write(p []byte) (n int, err error) { var _ io.Writer = mockWriter{} -func getFiles(t *testing.T, fileSystem afero.Fs) map[string]*bytes.Buffer { +func getFiles(t *testing.T, fileSystem fsext.Fs) map[string]*bytes.Buffer { result := map[string]*bytes.Buffer{} walkFn := func(filePath string, _ fs.FileInfo, err error) error { if filePath == "/" || filePath == "\\" { return nil } require.NoError(t, err) - contents, err := afero.ReadFile(fileSystem, filePath) + contents, err := fsext.ReadFile(fileSystem, filePath) require.NoError(t, err) result[filePath] = bytes.NewBuffer(contents) return nil } - err := fsext.Walk(fileSystem, afero.FilePathSeparator, filepath.WalkFunc(walkFn)) + err := fsext.Walk(fileSystem, fsext.FilePathSeparator, filepath.WalkFunc(walkFn)) require.NoError(t, err) return result @@ -64,9 +63,9 @@ func assertEqual(t *testing.T, exp string, actual io.Reader) { } func initVars() ( - content map[string]io.Reader, stdout *bytes.Buffer, stderr *bytes.Buffer, fs afero.Fs, + content map[string]io.Reader, stdout *bytes.Buffer, stderr *bytes.Buffer, fs fsext.Fs, ) { - return map[string]io.Reader{}, bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{}), afero.NewMemMapFs() + return map[string]io.Reader{}, bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{}), fsext.NewMemMapFs() } func TestHandleSummaryResultSimple(t *testing.T) { @@ -201,7 +200,7 @@ func TestRunScriptErrorsAndAbort(t *testing.T) { require.NoError(t, err) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, tc.testFilename), testScript, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, tc.testFilename), testScript, 0o644)) ts.CmdArgs = append([]string{"k6", "run", tc.testFilename}, tc.extraArgs...) ts.ExpectedExitCode = int(tc.expExitCode) @@ -256,7 +255,7 @@ func TestInvalidOptionsThresholdErrExitCode(t *testing.T) { require.NoError(t, err) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, tc.testFilename), testScript, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, tc.testFilename), testScript, 0o644)) ts.CmdArgs = append([]string{"k6", "run", tc.testFilename}, tc.extraArgs...) ts.ExpectedExitCode = int(tc.expExitCode) @@ -306,7 +305,7 @@ func TestThresholdsRuntimeBehavior(t *testing.T) { require.NoError(t, err) ts := tests.NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, tc.testFilename), testScript, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, tc.testFilename), testScript, 0o644)) ts.CmdArgs = []string{"k6", "run", tc.testFilename} ts.ExpectedExitCode = int(tc.expExitCode) diff --git a/cmd/runtime_options_test.go b/cmd/runtime_options_test.go index 02fb1b08137..222ab51aafe 100644 --- a/cmd/runtime_options_test.go +++ b/cmd/runtime_options_test.go @@ -6,13 +6,13 @@ import ( "net/url" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" "go.k6.io/k6/cmd/tests" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/loader" "go.k6.io/k6/metrics" ) @@ -56,15 +56,15 @@ func testRuntimeOptionsCase(t *testing.T, tc runtimeOptionsTestCase) { } fmt.Fprint(jsCode, "}") - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/script.js", jsCode.Bytes(), 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/script.js", jsCode.Bytes(), 0o644)) ts := tests.NewGlobalTestState(t) // TODO: move upwards, make this into an almost full integration test registry := metrics.NewRegistry() test := &loadedTest{ sourceRootPath: "script.js", source: &loader.SourceData{Data: jsCode.Bytes(), URL: &url.URL{Path: "/script.js", Scheme: "file"}}, - fileSystems: map[string]afero.Fs{"file": fs}, + fileSystems: map[string]fsext.Fs{"file": fs}, preInitState: &lib.TestPreInitState{ Logger: ts.Logger, RuntimeOptions: rtOpts, @@ -83,7 +83,7 @@ func testRuntimeOptionsCase(t *testing.T, tc runtimeOptionsTestCase) { return &loadedTest{ sourceRootPath: "script.tar", source: &loader.SourceData{Data: archiveBuf.Bytes(), URL: &url.URL{Path: "/script.tar", Scheme: "file"}}, - fileSystems: map[string]afero.Fs{"file": fs}, + fileSystems: map[string]fsext.Fs{"file": fs}, preInitState: &lib.TestPreInitState{ Logger: ts.Logger, RuntimeOptions: rtOpts, diff --git a/cmd/state/state.go b/cmd/state/state.go index 1fb92268398..f0595d7770e 100644 --- a/cmd/state/state.go +++ b/cmd/state/state.go @@ -11,8 +11,8 @@ import ( "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "github.com/sirupsen/logrus" - "github.com/spf13/afero" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/ui/console" ) @@ -34,7 +34,7 @@ const defaultConfigFileName = "config.json" type GlobalState struct { Ctx context.Context - FS afero.Fs + FS fsext.Fs Getwd func() (string, error) BinaryName string CmdArgs []string @@ -105,7 +105,7 @@ func NewGlobalState(ctx context.Context) *GlobalState { return &GlobalState{ Ctx: ctx, - FS: afero.NewOsFs(), + FS: fsext.NewOsFs(), Getwd: os.Getwd, BinaryName: filepath.Base(binary), CmdArgs: os.Args, diff --git a/cmd/test_load.go b/cmd/test_load.go index 18085609ac7..bf7378dda74 100644 --- a/cmd/test_load.go +++ b/cmd/test_load.go @@ -11,7 +11,6 @@ import ( "syscall" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/spf13/pflag" "go.k6.io/k6/cmd/state" @@ -19,6 +18,7 @@ import ( "go.k6.io/k6/errext/exitcodes" "go.k6.io/k6/js" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/loader" "go.k6.io/k6/metrics" ) @@ -34,8 +34,8 @@ type loadedTest struct { sourceRootPath string // contains the raw string the user supplied pwd string source *loader.SourceData - fs afero.Fs - fileSystems map[string]afero.Fs + fs fsext.Fs + fileSystems map[string]fsext.Fs preInitState *lib.TestPreInitState initRunner lib.Runner // TODO: rename to something more appropriate keyLogger io.Closer @@ -159,7 +159,7 @@ func (lt *loadedTest) initializeFirstRunner(gs *state.GlobalState) error { // readSource is a small wrapper around loader.ReadSource returning // result of the load and filesystems map -func readSource(gs *state.GlobalState, filename string) (*loader.SourceData, map[string]afero.Fs, string, error) { +func readSource(gs *state.GlobalState, filename string) (*loader.SourceData, map[string]fsext.Fs, string, error) { pwd, err := gs.Getwd() if err != nil { return nil, nil, "", err diff --git a/cmd/tests/cmd_cloud_test.go b/cmd/tests/cmd_cloud_test.go index 10bbc71fa93..b06202733cf 100644 --- a/cmd/tests/cmd_cloud_test.go +++ b/cmd/tests/cmd_cloud_test.go @@ -8,11 +8,11 @@ import ( "path/filepath" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/cloudapi" "go.k6.io/k6/cmd" + "go.k6.io/k6/lib/fsext" ) func cloudTestStartSimple(tb testing.TB, testRunID int) http.Handler { @@ -72,7 +72,7 @@ func getSimpleCloudTestState( srv := getMockCloud(t, 123, archiveUpload, progressCallback) ts := NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "test.js"), script, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "test.js"), script, 0o644)) ts.CmdArgs = append(append([]string{"k6", "cloud"}, cliFlags...), "test.js") ts.Env["K6_SHOW_CLOUD_LOGS"] = "false" // no mock for the logs yet ts.Env["K6_CLOUD_HOST"] = srv.URL diff --git a/cmd/tests/cmd_run_test.go b/cmd/tests/cmd_run_test.go index 595e2bc229a..b218af73416 100644 --- a/cmd/tests/cmd_run_test.go +++ b/cmd/tests/cmd_run_test.go @@ -18,7 +18,6 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" @@ -26,6 +25,7 @@ import ( "go.k6.io/k6/cmd" "go.k6.io/k6/errext/exitcodes" "go.k6.io/k6/lib/consts" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/lib/testutils/httpmultibin" ) @@ -166,7 +166,7 @@ func TestStdoutAndStderrAreEmptyWithQuietAndLogsForwarded(t *testing.T) { assert.Empty(t, ts.Stdout.Bytes()) // Instead it should be in the log file - logContents, err := afero.ReadFile(ts.FS, logFilePath) + logContents, err := fsext.ReadFile(ts.FS, logFilePath) require.NoError(t, err) assert.Equal(t, "init\ninit\nfoo\n", string(logContents)) //nolint:dupword } @@ -192,7 +192,7 @@ func TestRelativeLogPathWithSetupAndTeardown(t *testing.T) { assert.True(t, testutils.LogContains(logEntries, logrus.InfoLevel, `baz`)) // And check that the log file also contains everything - logContents, err := afero.ReadFile(ts.FS, filepath.Join(ts.Cwd, "test.log")) + logContents, err := fsext.ReadFile(ts.FS, filepath.Join(ts.Cwd, "test.log")) require.NoError(t, err) assert.Equal(t, "init\ninit\ninit\nbar\nfoo\nfoo\ninit\nbaz\ninit\n", string(logContents)) //nolint:dupword } @@ -233,7 +233,7 @@ func getSingleFileTestState(tb testing.TB, script string, cliFlags []string, exp } ts := NewGlobalTestState(tb) - require.NoError(tb, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "test.js"), []byte(script), 0o644)) + require.NoError(tb, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "test.js"), []byte(script), 0o644)) ts.CmdArgs = append(append([]string{"k6", "run"}, cliFlags...), "test.js") ts.ExpectedExitCode = int(expExitCode) @@ -369,7 +369,7 @@ func testSSLKEYLOGFILE(t *testing.T, ts *GlobalTestState, filePath string) { assert.True(t, testutils.LogContains(ts.LoggerHook.Drain(), logrus.WarnLevel, "SSLKEYLOGFILE was specified")) - sslloglines, err := afero.ReadFile(ts.FS, filepath.Join(ts.Cwd, "ssl.log")) + sslloglines, err := fsext.ReadFile(ts.FS, filepath.Join(ts.Cwd, "ssl.log")) require.NoError(t, err) // TODO maybe have multiple depending on the ciphers used as that seems to change it assert.Regexp(t, "^CLIENT_[A-Z_]+ [0-9a-f]+ [0-9a-f]+\n", string(sslloglines)) @@ -918,8 +918,8 @@ func TestAbortedByScriptSetupErrorWithDependency(t *testing.T) { srv := getCloudTestEndChecker(t, 123, nil, cloudapi.RunStatusAbortedScriptError, cloudapi.ResultStatusPassed) ts := NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "test.js"), []byte(mainScript), 0o644)) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "bar.js"), []byte(depScript), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "test.js"), []byte(mainScript), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "bar.js"), []byte(depScript), 0o644)) ts.Env["K6_CLOUD_HOST"] = srv.URL ts.CmdArgs = []string{"k6", "run", "-v", "--out", "cloud", "--log-output=stdout", "test.js"} @@ -1487,7 +1487,7 @@ func TestActiveVUsCount(t *testing.T) { stdout := ts.Stdout.String() t.Log(stdout) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) // t.Log(string(jsonResults)) assert.Equal(t, float64(10), max(getSampleValues(t, jsonResults, "vus_max", nil))) @@ -1615,7 +1615,7 @@ func TestRunTags(t *testing.T) { stdout := ts.Stdout.String() t.Log(stdout) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) expTags := map[string]string{"foo": "bar", "test": "mest", "over": "written", "scenario": "default"} @@ -1741,7 +1741,7 @@ func BenchmarkReadResponseBody(b *testing.B) { duration: '10s', vus: 10 }; - + export default function () { let bytes = randomIntBetween(100 * 1024, 5 * 1024 * 1024) @@ -1760,7 +1760,7 @@ func BenchmarkReadResponseBody(b *testing.B) { responses.forEach(res => check(res, statusCheck)) sleep(0.1) }; - + function randomIntBetween(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } @@ -1908,7 +1908,7 @@ func TestRunStaticArchives(t *testing.T) { data, err := os.ReadFile(filepath.Join("testdata/archives", tc.archive)) //nolint:forbidigo // it's a test require.NoError(t, err) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "archive.tar"), data, 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "archive.tar"), data, 0o644)) ts.CmdArgs = []string{"k6", "run", "--log-output=stdout", "archive.tar"} diff --git a/cmd/tests/test_state.go b/cmd/tests/test_state.go index 760833dc60b..54e5be13a0e 100644 --- a/cmd/tests/test_state.go +++ b/cmd/tests/test_state.go @@ -12,10 +12,10 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/cmd/state" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/ui/console" ) @@ -39,7 +39,7 @@ func NewGlobalTestState(tb testing.TB) *GlobalTestState { ctx, cancel := context.WithCancel(context.Background()) tb.Cleanup(cancel) - fs := &afero.MemMapFs{} + fs := fsext.NewMemMapFs() cwd := "/test/" // TODO: Make this relative to the test? if runtime.GOOS == "windows" { cwd = "c:\\test\\" diff --git a/cmd/tests/tracing_module_test.go b/cmd/tests/tracing_module_test.go index 524f530329b..84c980719af 100644 --- a/cmd/tests/tracing_module_test.go +++ b/cmd/tests/tracing_module_test.go @@ -9,10 +9,10 @@ import ( "sync/atomic" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/cmd" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils/httpmultibin" "go.k6.io/k6/metrics" ) @@ -56,7 +56,7 @@ func TestTracingModuleClient(t *testing.T) { assert.Equal(t, int64(9), atomic.LoadInt64(&gotRequests)) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) assertHasTraceIDMetadata(t, jsonResults, 9, tb.Replacer.Replace("HTTPBIN_IP_URL/tracing")) @@ -148,7 +148,7 @@ func TestTracingModuleClient_HundredPercentSampling(t *testing.T) { assert.Equal(t, int64(100), atomic.LoadInt64(&gotSampleFlags)) assert.Equal(t, int64(100), atomic.LoadInt64(&gotRequests)) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) assertHasTraceIDMetadata(t, jsonResults, 100, tb.Replacer.Replace("HTTPBIN_IP_URL/tracing")) @@ -240,7 +240,7 @@ func TestTracingInstrumentHTTP_W3C(t *testing.T) { assert.Equal(t, int64(9), atomic.LoadInt64(&gotRequests)) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) assertHasTraceIDMetadata(t, jsonResults, 9, tb.Replacer.Replace("HTTPBIN_IP_URL/tracing")) @@ -284,7 +284,7 @@ func TestTracingInstrumentHTTP_Jaeger(t *testing.T) { assert.Equal(t, int64(8), atomic.LoadInt64(&gotRequests)) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) assertHasTraceIDMetadata(t, jsonResults, 8, tb.Replacer.Replace("HTTPBIN_IP_URL/tracing")) @@ -335,7 +335,7 @@ func TestTracingInstrumentHTTP_FillsParams(t *testing.T) { assert.Equal(t, int64(8), atomic.LoadInt64(&gotRequests)) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) assertHasTraceIDMetadata(t, jsonResults, 8, tb.Replacer.Replace("HTTPBIN_IP_URL/tracing")) @@ -359,7 +359,7 @@ func TestTracingInstrummentHTTP_SupportsMultipleTestScripts(t *testing.T) { import tracing from "k6/experimental/tracing"; import { iShouldBeInstrumented } from "./imported.js"; - + tracing.instrumentHTTP({ propagator: "w3c", }) @@ -378,15 +378,15 @@ func TestTracingInstrummentHTTP_SupportsMultipleTestScripts(t *testing.T) { `) ts := NewGlobalTestState(t) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "main.js"), []byte(mainScript), 0o644)) - require.NoError(t, afero.WriteFile(ts.FS, filepath.Join(ts.Cwd, "imported.js"), []byte(importedScript), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "main.js"), []byte(mainScript), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "imported.js"), []byte(importedScript), 0o644)) ts.CmdArgs = []string{"k6", "run", "--out", "json=results.json", "main.js"} ts.ExpectedExitCode = 0 cmd.ExecuteWithGlobalState(ts.GlobalState) - jsonResults, err := afero.ReadFile(ts.FS, "results.json") + jsonResults, err := fsext.ReadFile(ts.FS, "results.json") require.NoError(t, err) assert.Equal(t, int64(1), atomic.LoadInt64(&gotRequests)) diff --git a/js/bundle.go b/js/bundle.go index 258cbae69dd..27009191660 100644 --- a/js/bundle.go +++ b/js/bundle.go @@ -12,7 +12,6 @@ import ( "github.com/dop251/goja" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "gopkg.in/guregu/null.v3" "go.k6.io/k6/js/common" @@ -20,6 +19,7 @@ import ( "go.k6.io/k6/js/eventloop" "go.k6.io/k6/lib" "go.k6.io/k6/lib/consts" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/loader" ) @@ -32,7 +32,7 @@ type Bundle struct { CompatibilityMode lib.CompatibilityMode // parsed value preInitState *lib.TestPreInitState - filesystems map[string]afero.Fs + filesystems map[string]fsext.Fs pwd *url.URL callableExports map[string]struct{} @@ -62,13 +62,13 @@ func (bi *BundleInstance) getExported(name string) goja.Value { // NewBundle creates a new bundle from a source file and a filesystem. func NewBundle( - piState *lib.TestPreInitState, src *loader.SourceData, filesystems map[string]afero.Fs, + piState *lib.TestPreInitState, src *loader.SourceData, filesystems map[string]fsext.Fs, ) (*Bundle, error) { return newBundle(piState, src, filesystems, lib.Options{}, true) } func newBundle( - piState *lib.TestPreInitState, src *loader.SourceData, filesystems map[string]afero.Fs, + piState *lib.TestPreInitState, src *loader.SourceData, filesystems map[string]fsext.Fs, options lib.Options, updateOptions bool, // TODO: try to figure out a way to not need both ) (*Bundle, error) { compatMode, err := lib.ValidateCompatibilityMode(piState.RuntimeOptions.CompatibilityMode.String) diff --git a/js/bundle_test.go b/js/bundle_test.go index 035105b0e9c..66552c90ee8 100644 --- a/js/bundle_test.go +++ b/js/bundle_test.go @@ -16,7 +16,6 @@ import ( "github.com/dop251/goja" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" @@ -49,12 +48,12 @@ func getTestPreInitState(tb testing.TB, logger logrus.FieldLogger, rtOpts *lib.R } func getSimpleBundle(tb testing.TB, filename, data string, opts ...interface{}) (*Bundle, error) { - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() var rtOpts *lib.RuntimeOptions var logger logrus.FieldLogger for _, o := range opts { switch opt := o.(type) { - case afero.Fs: + case fsext.Fs: fs = opt case lib.RuntimeOptions: rtOpts = &opt @@ -71,7 +70,7 @@ func getSimpleBundle(tb testing.TB, filename, data string, opts ...interface{}) URL: &url.URL{Path: filename, Scheme: "file"}, Data: []byte(data), }, - map[string]afero.Fs{"file": fs, "https": afero.NewMemMapFs()}, + map[string]fsext.Fs{"file": fs, "https": fsext.NewMemMapFs()}, ) } @@ -652,20 +651,20 @@ func TestOpen(t *testing.T) { isError: true, }, } - fss := map[string]func() (afero.Fs, string, func()){ - "MemMapFS": func() (afero.Fs, string, func()) { - fs := afero.NewMemMapFs() + fss := map[string]func() (fsext.Fs, string, func()){ + "MemMapFS": func() (fsext.Fs, string, func()) { + fs := fsext.NewMemMapFs() require.NoError(t, fs.MkdirAll("/path/to", 0o755)) - require.NoError(t, afero.WriteFile(fs, "/path/to/file.txt", []byte(`hi`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/file.txt", []byte(`hi`), 0o644)) return fs, "", func() {} }, - "OsFS": func() (afero.Fs, string, func()) { + "OsFS": func() (fsext.Fs, string, func()) { prefix, err := ioutil.TempDir("", "k6_open_test") require.NoError(t, err) - fs := afero.NewOsFs() + fs := fsext.NewOsFs() filePath := filepath.Join(prefix, "/path/to/file.txt") require.NoError(t, fs.MkdirAll(filepath.Join(prefix, "/path/to"), 0o755)) - require.NoError(t, afero.WriteFile(fs, filePath, []byte(`hi`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, filePath, []byte(`hi`), 0o644)) if isWindows { fs = fsext.NewTrimFilePathSeparatorFs(fs) } @@ -686,7 +685,7 @@ func TestOpen(t *testing.T) { t.Parallel() fs, prefix, cleanUp := fsInit() defer cleanUp() - fs = afero.NewReadOnlyFs(fs) + fs = fsext.NewReadOnlyFs(fs) openPath := tCase.openPath // if fullpath prepend prefix if openPath != "" && (openPath[0] == '/' || openPath[0] == '\\') { @@ -896,10 +895,10 @@ func TestBundleMakeArchive(t *testing.T) { tc := tc t.Run(tc.cm.String(), func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() _ = fs.MkdirAll("/path/to", 0o755) - _ = afero.WriteFile(fs, "/path/to/file.txt", []byte(`hi`), 0o644) - _ = afero.WriteFile(fs, "/path/to/exclaim.js", []byte(tc.exclaim), 0o644) + _ = fsext.WriteFile(fs, "/path/to/file.txt", []byte(`hi`), 0o644) + _ = fsext.WriteFile(fs, "/path/to/exclaim.js", []byte(tc.exclaim), 0o644) rtOpts := lib.RuntimeOptions{CompatibilityMode: null.StringFrom(tc.cm.String())} b, err := getSimpleBundle(t, "/path/to/script.js", tc.script, fs, rtOpts) @@ -913,11 +912,11 @@ func TestBundleMakeArchive(t *testing.T) { assert.Equal(t, tc.script, string(arc.Data)) assert.Equal(t, "file:///path/to/", arc.PwdURL.String()) - exclaimData, err := afero.ReadFile(arc.Filesystems["file"], "/path/to/exclaim.js") + exclaimData, err := fsext.ReadFile(arc.Filesystems["file"], "/path/to/exclaim.js") require.NoError(t, err) assert.Equal(t, tc.exclaim, string(exclaimData)) - fileData, err := afero.ReadFile(arc.Filesystems["file"], "/path/to/file.txt") + fileData, err := fsext.ReadFile(arc.Filesystems["file"], "/path/to/file.txt") require.NoError(t, err) assert.Equal(t, `hi`, string(fileData)) assert.Equal(t, consts.Version, arc.K6Version) diff --git a/js/common/initenv.go b/js/common/initenv.go index 2733f69d1b5..73630897930 100644 --- a/js/common/initenv.go +++ b/js/common/initenv.go @@ -4,15 +4,15 @@ import ( "net/url" "path/filepath" - "github.com/spf13/afero" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" ) // InitEnvironment contains properties that can be accessed by Go code executed // in the k6 init context. It can be accessed by calling common.GetInitEnv(). type InitEnvironment struct { *lib.TestPreInitState - FileSystems map[string]afero.Fs + FileSystems map[string]fsext.Fs CWD *url.URL // TODO: get rid of this type altogether? we won't need it if we figure out // how to handle .tar archive vs regular JS script differences in FileSystems @@ -34,8 +34,8 @@ func (ie *InitEnvironment) GetAbsFilePath(filename string) string { filename = filepath.Join(ie.CWD.Path, filename) } filename = filepath.Clean(filename) - if filename[0:1] != afero.FilePathSeparator { - filename = afero.FilePathSeparator + filename + if filename[0:1] != fsext.FilePathSeparator { + filename = fsext.FilePathSeparator + filename } return filename } diff --git a/js/console_test.go b/js/console_test.go index 63fd376e758..a786ef6fed0 100644 --- a/js/console_test.go +++ b/js/console_test.go @@ -12,13 +12,13 @@ import ( "github.com/dop251/goja" "github.com/sirupsen/logrus" logtest "github.com/sirupsen/logrus/hooks/test" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" "go.k6.io/k6/js/common" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/loader" "go.k6.io/k6/metrics" @@ -49,13 +49,13 @@ func getSimpleRunner(tb testing.TB, filename, data string, opts ...interface{}) var ( rtOpts = lib.RuntimeOptions{CompatibilityMode: null.NewString("base", true)} logger = testutils.NewLogger(tb) - fsResolvers = map[string]afero.Fs{"file": afero.NewMemMapFs(), "https": afero.NewMemMapFs()} + fsResolvers = map[string]fsext.Fs{"file": fsext.NewMemMapFs(), "https": fsext.NewMemMapFs()} ) for _, o := range opts { switch opt := o.(type) { - case afero.Fs: + case fsext.Fs: fsResolvers["file"] = opt - case map[string]afero.Fs: + case map[string]fsext.Fs: fsResolvers = opt case lib.RuntimeOptions: rtOpts = opt diff --git a/js/init_and_modules_test.go b/js/init_and_modules_test.go index bd993c6a1bb..82a6a9bf6bf 100644 --- a/js/init_and_modules_test.go +++ b/js/init_and_modules_test.go @@ -8,7 +8,6 @@ import ( "testing" "time" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" @@ -16,6 +15,7 @@ import ( "go.k6.io/k6/js" "go.k6.io/k6/js/modules" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/loader" "go.k6.io/k6/metrics" @@ -69,7 +69,7 @@ func TestNewJSRunnerWithCustomModule(t *testing.T) { URL: &url.URL{Path: "blah", Scheme: "file"}, Data: []byte(script), }, - map[string]afero.Fs{"file": afero.NewMemMapFs(), "https": afero.NewMemMapFs()}, + map[string]fsext.Fs{"file": fsext.NewMemMapFs(), "https": fsext.NewMemMapFs()}, ) require.NoError(t, err) assert.Equal(t, checkModule.initCtxCalled, 1) diff --git a/js/initcontext.go b/js/initcontext.go index ca00a7fd9ae..aeebe97a58a 100644 --- a/js/initcontext.go +++ b/js/initcontext.go @@ -9,7 +9,6 @@ import ( "github.com/dop251/goja" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "go.k6.io/k6/js/modules" "go.k6.io/k6/lib/fsext" @@ -22,7 +21,7 @@ const cantBeUsedOutsideInitContextMsg = `the "%s" function is only available in // openImpl implements openImpl() in the init context and will read and return the // contents of a file. If the second argument is "b" it returns an ArrayBuffer // instance, otherwise a string representation. -func openImpl(rt *goja.Runtime, fs afero.Fs, basePWD *url.URL, filename string, args ...string) (goja.Value, error) { +func openImpl(rt *goja.Runtime, fs fsext.Fs, basePWD *url.URL, filename string, args ...string) (goja.Value, error) { // Here IsAbs should be enough but unfortunately it doesn't handle absolute paths starting from // the current drive on windows like `\users\noname\...`. Also it makes it more easy to test and // will probably be need for archive execution under windows if always consider '/...' as an @@ -32,8 +31,8 @@ func openImpl(rt *goja.Runtime, fs afero.Fs, basePWD *url.URL, filename string, } filename = filepath.Clean(filename) - if filename[0:1] != afero.FilePathSeparator { - filename = afero.FilePathSeparator + filename + if filename[0:1] != fsext.FilePathSeparator { + filename = fsext.FilePathSeparator + filename } data, err := readFile(fs, filename) @@ -48,7 +47,7 @@ func openImpl(rt *goja.Runtime, fs afero.Fs, basePWD *url.URL, filename string, return rt.ToValue(string(data)), nil } -func readFile(fileSystem afero.Fs, filename string) (data []byte, err error) { +func readFile(fileSystem fsext.Fs, filename string) (data []byte, err error) { defer func() { if errors.Is(err, fsext.ErrPathNeverRequestedBefore) { // loading different files per VU is not supported, so all files should are going @@ -60,18 +59,18 @@ func readFile(fileSystem afero.Fs, filename string) (data []byte, err error) { } }() - // Workaround for https://github.com/spf13/afero/issues/201 - if isDir, err := afero.IsDir(fileSystem, filename); err != nil { + // Workaround for https://github.com/spf13/fsext/issues/201 + if isDir, err := fsext.IsDir(fileSystem, filename); err != nil { return nil, err } else if isDir { return nil, fmt.Errorf("open() can't be used with directories, path: %q", filename) } - return afero.ReadFile(fileSystem, filename) + return fsext.ReadFile(fileSystem, filename) } // allowOnlyOpenedFiles enables seen only files -func allowOnlyOpenedFiles(fs afero.Fs) { +func allowOnlyOpenedFiles(fs fsext.Fs) { alreadyOpenedFS, ok := fs.(fsext.OnlyCachedEnabler) if !ok { return @@ -122,7 +121,7 @@ func (r *requireImpl) require(specifier string) (*goja.Object, error) { return r.modules.Require(currentPWD, specifier) } -func generateSourceMapLoader(logger logrus.FieldLogger, filesystems map[string]afero.Fs, +func generateSourceMapLoader(logger logrus.FieldLogger, filesystems map[string]fsext.Fs, ) func(path string) ([]byte, error) { return func(path string) ([]byte, error) { u, err := url.Parse(path) diff --git a/js/initcontext_test.go b/js/initcontext_test.go index 2845142e451..3a8489edbaf 100644 --- a/js/initcontext_test.go +++ b/js/initcontext_test.go @@ -13,12 +13,12 @@ import ( "github.com/dop251/goja" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/lib" "go.k6.io/k6/lib/consts" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/netext" "go.k6.io/k6/lib/types" "go.k6.io/k6/metrics" @@ -90,16 +90,16 @@ func TestRequire(t *testing.T) { }) t.Run("Invalid", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/file.js", []byte{0x00}, 0o755)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/file.js", []byte{0x00}, 0o755)) _, err := getSimpleBundle(t, "/script.js", `import "/file.js"; export default function() {}`, fs) require.Error(t, err) assert.Contains(t, err.Error(), "SyntaxError: file:///file.js: Unexpected character '\x00' (1:0)\n> 1 | \x00\n") }) t.Run("Error", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/file.js", []byte(`throw new Error("aaaa")`), 0o755)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/file.js", []byte(`throw new Error("aaaa")`), 0o755)) _, err := getSimpleBundle(t, "/script.js", `import "/file.js"; export default function() {}`, fs) assert.EqualError(t, err, "Error: aaaa\n\tat file:///file.js:2:7(3)\n\tat go.k6.io/k6/js.(*requireImpl).require-fm (native)\n\tat file:///script.js:1:0(15)\n") @@ -146,7 +146,7 @@ func TestRequire(t *testing.T) { } t.Run(name, func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() jsLib := `export default function() { return 12345; }` if constName != "" { @@ -157,11 +157,11 @@ func TestRequire(t *testing.T) { constsrc := `export let c = 12345;` require.NoError(t, fs.MkdirAll(filepath.Dir(constPath), 0o755)) - require.NoError(t, afero.WriteFile(fs, constPath, []byte(constsrc), 0o644)) + require.NoError(t, fsext.WriteFile(fs, constPath, []byte(constsrc), 0o644)) } require.NoError(t, fs.MkdirAll(filepath.Dir(data.LibPath), 0o755)) - require.NoError(t, afero.WriteFile(fs, data.LibPath, []byte(jsLib), 0o644)) + require.NoError(t, fsext.WriteFile(fs, data.LibPath, []byte(jsLib), 0o644)) data := fmt.Sprintf(` import fn from "%s"; @@ -180,9 +180,9 @@ func TestRequire(t *testing.T) { t.Run("Isolation", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/a.js", []byte(`const myvar = "a";`), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/b.js", []byte(`const myvar = "b";`), 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/a.js", []byte(`const myvar = "a";`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/b.js", []byte(`const myvar = "b";`), 0o644)) data := ` import "./a.js"; import "./b.js"; @@ -204,9 +204,9 @@ func TestRequire(t *testing.T) { func createAndReadFile(t *testing.T, file string, content []byte, expectedLength int, binary string) (*BundleInstance, error) { t.Helper() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() require.NoError(t, fs.MkdirAll("/path/to", 0o755)) - require.NoError(t, afero.WriteFile(fs, "/path/to/"+file, content, 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/"+file, content, 0o644)) data := fmt.Sprintf(` let binArg = "%s"; @@ -286,7 +286,7 @@ func TestInitContextOpen(t *testing.T) { t.Run("Directory", func(t *testing.T) { t.Parallel() path := filepath.FromSlash("/some/dir") - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() require.NoError(t, fs.MkdirAll(path, 0o755)) _, err := getSimpleBundle(t, "/script.js", `open("/some/dir"); export default function() {}`, fs) require.Error(t, err) @@ -320,9 +320,9 @@ func TestRequestWithBinaryFile(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(h)) defer srv.Close() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() require.NoError(t, fs.MkdirAll("/path/to", 0o755)) - require.NoError(t, afero.WriteFile(fs, "/path/to/file.bin", []byte("hi!"), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/file.bin", []byte("hi!"), 0o644)) b, err := getSimpleBundle(t, "/path/to/script.js", fmt.Sprintf(` @@ -413,10 +413,10 @@ func TestRequestWithMultipleBinaryFiles(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(h)) defer srv.Close() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() require.NoError(t, fs.MkdirAll("/path/to", 0o755)) - require.NoError(t, afero.WriteFile(fs, "/path/to/file1.bin", []byte("file1"), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/to/file2.bin", []byte("file2"), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/file1.bin", []byte("file1"), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/file2.bin", []byte("file2"), 0o644)) b, err := getSimpleBundle(t, "/path/to/script.js", fmt.Sprintf(` @@ -546,8 +546,8 @@ func Test__VU(t *testing.T) { func TestSourceMaps(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/module1.js", []byte(` + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/module1.js", []byte(` export function f2(){ throw "exception in line 2" console.log("in f2") @@ -580,13 +580,13 @@ export default function(){ func TestSourceMapsExternal(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() // This example is created through the template-typescript - require.NoError(t, afero.WriteFile(fs, "/test1.js", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/test1.js", []byte(` (()=>{"use strict";var e={};(()=>{var o=e;Object.defineProperty(o,"__esModule",{value:!0}),o.default=function(){!function(e){throw"cool is cool"}()}})();var o=exports;for(var r in e)o[r]=e[r];e.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})(); //# sourceMappingURL=test1.js.map `[1:]), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/test1.js.map", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/test1.js.map", []byte(` {"version":3,"sources":["webpack:///./test1.ts"],"names":["s","coolThrow"],"mappings":"2FAGA,sBAHA,SAAmBA,GACf,KAAM,eAGNC,K","file":"test1.js","sourcesContent":["function coolThrow(s: string) {\n throw \"cool \"+ s\n}\nexport default () => {\n coolThrow(\"is cool\")\n};\n"],"sourceRoot":""} `[1:]), 0o644)) data := ` @@ -610,14 +610,14 @@ export default function () { func TestSourceMapsExternalExtented(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() // This example is created through the template-typescript // but was exported to use import/export syntax so it has to go through babel - require.NoError(t, afero.WriteFile(fs, "/test1.js", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/test1.js", []byte(` var o={d:(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o:(o,e)=>Object.prototype.hasOwnProperty.call(o,e)},e={};o.d(e,{Z:()=>r});const r=()=>{!function(o){throw"cool is cool"}()};var t=e.Z;export{t as default}; //# sourceMappingURL=test1.js.map `[1:]), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/test1.js.map", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/test1.js.map", []byte(` {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./test1.ts"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","s","coolThrow"],"mappings":"AACA,IAAIA,EAAsB,CCA1B,EAAwB,CAACC,EAASC,KACjC,IAAI,IAAIC,KAAOD,EACXF,EAAoBI,EAAEF,EAAYC,KAASH,EAAoBI,EAAEH,EAASE,IAC5EE,OAAOC,eAAeL,EAASE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3E,EAAwB,CAACM,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,I,sBCGlF,cAHA,SAAmBI,GACf,KAAM,eAGNC,I","file":"test1.js","sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","function coolThrow(s: string) {\n throw \"cool \"+ s\n}\nexport default () => {\n coolThrow(\"is cool\")\n};\n"],"sourceRoot":""} `[1:]), 0o644)) data := ` @@ -643,10 +643,10 @@ export default function () { func TestSourceMapsExternalExtentedInlined(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() // This example is created through the template-typescript // but was exported to use import/export syntax so it has to go through babel - require.NoError(t, afero.WriteFile(fs, "/test1.js", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/test1.js", []byte(` var o={d:(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o:(o,e)=>Object.prototype.hasOwnProperty.call(o,e)},e={};o.d(e,{Z:()=>r});const r=()=>{!function(o){throw"cool is cool"}()};var t=e.Z;export{t as default}; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly8vd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly8vLi90ZXN0MS50cyJdLCJuYW1lcyI6WyJfX3dlYnBhY2tfcmVxdWlyZV9fIiwiZXhwb3J0cyIsImRlZmluaXRpb24iLCJrZXkiLCJvIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJlbnVtZXJhYmxlIiwiZ2V0Iiwib2JqIiwicHJvcCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInMiLCJjb29sVGhyb3ciXSwibWFwcGluZ3MiOiJBQUNBLElBQUlBLEVBQXNCLENDQTFCLEVBQXdCLENBQUNDLEVBQVNDLEtBQ2pDLElBQUksSUFBSUMsS0FBT0QsRUFDWEYsRUFBb0JJLEVBQUVGLEVBQVlDLEtBQVNILEVBQW9CSSxFQUFFSCxFQUFTRSxJQUM1RUUsT0FBT0MsZUFBZUwsRUFBU0UsRUFBSyxDQUFFSSxZQUFZLEVBQU1DLElBQUtOLEVBQVdDLE1DSjNFLEVBQXdCLENBQUNNLEVBQUtDLElBQVVMLE9BQU9NLFVBQVVDLGVBQWVDLEtBQUtKLEVBQUtDLEksc0JDR2xGLGNBSEEsU0FBbUJJLEdBQ2YsS0FBTSxlQUdOQyxJIiwiZmlsZSI6InRlc3QxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhlIHJlcXVpcmUgc2NvcGVcbnZhciBfX3dlYnBhY2tfcmVxdWlyZV9fID0ge307XG5cbiIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18ubyA9IChvYmosIHByb3ApID0+IChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkiLCJmdW5jdGlvbiBjb29sVGhyb3coczogc3RyaW5nKSB7XG4gICAgdGhyb3cgXCJjb29sIFwiKyBzXG59XG5leHBvcnQgZGVmYXVsdCAoKSA9PiB7XG4gICAgY29vbFRocm93KFwiaXMgY29vbFwiKVxufTtcbiJdLCJzb3VyY2VSb290IjoiIn0= `[1:]), 0o644)) @@ -673,9 +673,9 @@ export default function () { func TestImportModificationsAreConsistentBetweenFiles(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/notk6.js", []byte(`export default {group}; function group() {}`), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/instrument.js", []byte(` + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/notk6.js", []byte(`export default {group}; function group() {}`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/instrument.js", []byte(` import k6 from "k6"; k6.newKey = 5; k6.group = 3; @@ -703,12 +703,12 @@ func TestImportModificationsAreConsistentBetweenFiles(t *testing.T) { func TestCacheAbsolutePathsNotRelative(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/a/interesting.js", []byte(`export default "a.interesting"`), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/a/import.js", []byte(`export { default as default} from "./interesting.js"`), 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/a/interesting.js", []byte(`export default "a.interesting"`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/a/import.js", []byte(`export { default as default} from "./interesting.js"`), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/b/interesting.js", []byte(`export default "b.interesting"`), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/b/import.js", []byte(`export { default as default} from "./interesting.js"`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/b/interesting.js", []byte(`export default "b.interesting"`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/b/import.js", []byte(`export { default as default} from "./interesting.js"`), 0o644)) b, err := getSimpleBundle(t, "/script.js", ` import a from "/a/import.js" diff --git a/js/module_loading_test.go b/js/module_loading_test.go index 86b72e784cb..a82a910d5aa 100644 --- a/js/module_loading_test.go +++ b/js/module_loading_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/types" - "github.com/spf13/afero" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" @@ -58,16 +58,16 @@ func TestLoadOnceGlobalVars(t *testing.T) { cData := data t.Run(name, func(t *testing.T) { t.Parallel() - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/C.js", []byte(cData), fs.ModePerm)) + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/C.js", []byte(cData), fs.ModePerm)) - require.NoError(t, afero.WriteFile(fileSystem, "/A.js", []byte(` + require.NoError(t, fsext.WriteFile(fileSystem, "/A.js", []byte(` import { C } from "./C.js"; export function A() { return C(); } `), fs.ModePerm)) - require.NoError(t, afero.WriteFile(fileSystem, "/B.js", []byte(` + require.NoError(t, fsext.WriteFile(fileSystem, "/B.js", []byte(` var c = require("./C.js"); export function B() { return c.C(); @@ -121,8 +121,8 @@ func TestLoadOnceGlobalVars(t *testing.T) { func TestLoadExportsIsUsableInModule(t *testing.T) { t.Parallel() - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/A.js", []byte(` + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/A.js", []byte(` export function A() { return "A"; } @@ -179,8 +179,8 @@ func TestLoadDoesntBreakHTTPGet(t *testing.T) { // inside script that is imported tb := httpmultibin.NewHTTPMultiBin(t) - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/A.js", []byte(tb.Replacer.Replace(` + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/A.js", []byte(tb.Replacer.Replace(` import http from "k6/http"; export function A() { return http.get("HTTPBIN_URL/get"); @@ -229,8 +229,8 @@ func TestLoadDoesntBreakHTTPGet(t *testing.T) { func TestLoadGlobalVarsAreNotSharedBetweenVUs(t *testing.T) { t.Parallel() - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/A.js", []byte(` + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/A.js", []byte(` var globalVar = 0; export function A() { globalVar += 1 @@ -290,8 +290,8 @@ func TestLoadGlobalVarsAreNotSharedBetweenVUs(t *testing.T) { func TestLoadCycle(t *testing.T) { t.Parallel() // This is mostly the example from https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/ - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/counter.js", []byte(` + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/counter.js", []byte(` let main = require("./main.js"); exports.count = 5; export function a() { @@ -299,7 +299,7 @@ func TestLoadCycle(t *testing.T) { } `), fs.ModePerm)) - require.NoError(t, afero.WriteFile(fileSystem, "/main.js", []byte(` + require.NoError(t, fsext.WriteFile(fileSystem, "/main.js", []byte(` let counter = require("./counter.js"); let count = counter.count; let a = counter.a; @@ -316,7 +316,7 @@ func TestLoadCycle(t *testing.T) { } } `), fs.ModePerm)) - data, err := afero.ReadFile(fileSystem, "/main.js") + data, err := fsext.ReadFile(fileSystem, "/main.js") require.NoError(t, err) r1, err := getSimpleRunner(t, "/main.js", string(data), fileSystem, lib.RuntimeOptions{CompatibilityMode: null.StringFrom("extended")}) require.NoError(t, err) @@ -353,8 +353,8 @@ func TestLoadCycleBinding(t *testing.T) { t.Parallel() // This is mostly the example from // http://2ality.com/2015/07/es6-module-exports.html#why-export-bindings - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/a.js", []byte(` + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/a.js", []byte(` import {bar} from './b.js'; export function foo(a) { if (a !== undefined) { @@ -364,7 +364,7 @@ func TestLoadCycleBinding(t *testing.T) { } `), fs.ModePerm)) - require.NoError(t, afero.WriteFile(fileSystem, "/b.js", []byte(` + require.NoError(t, fsext.WriteFile(fileSystem, "/b.js", []byte(` import {foo} from './a.js'; export function bar(a) { if (a !== undefined) { @@ -420,8 +420,8 @@ func TestLoadCycleBinding(t *testing.T) { func TestBrowserified(t *testing.T) { t.Parallel() - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/browserified.js", []byte(` + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/browserified.js", []byte(` (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.npmlibs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i open("./../data.txt"); // Here the path is relative to this module but to the one calling `), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/to/script/script.js", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/path/to/script/script.js", []byte(` module.exports = require("./../../another/script/script.js")(); `), 0o644)) data := ` @@ -80,8 +80,8 @@ func TestRequirePathResolution(t *testing.T) { t.Parallel() t.Run("simple", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/path/to/data.js", []byte("module.exports='export content'"), 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/path/to/data.js", []byte("module.exports='export content'"), 0o644)) data := ` let data = require("../to/data.js"); if (data != "export content") { @@ -98,9 +98,9 @@ func TestRequirePathResolution(t *testing.T) { t.Run("intermediate", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/path/to/data.js", []byte("module.exports='export content'"), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/another/script/script.js", []byte(` + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/path/to/data.js", []byte("module.exports='export content'"), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/another/script/script.js", []byte(` module.exports = require("../../to/data.js"); `), 0o644)) data := ` @@ -119,12 +119,12 @@ func TestRequirePathResolution(t *testing.T) { t.Run("complex", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/path/to/data.js", []byte("module.exports='export content'"), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/another/script/script.js", []byte(` + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/path/to/data.js", []byte("module.exports='export content'"), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/another/script/script.js", []byte(` module.exports = () => require("./../data.js"); // Here the path is relative to this module but to the one calling `), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/to/script/script.js", []byte(` + require.NoError(t, fsext.WriteFile(fs, "/path/to/script/script.js", []byte(` module.exports = require("./../../another/script/script.js")(); `), 0o644)) data := ` diff --git a/js/runner.go b/js/runner.go index 4c9634eac84..f604c4e4f89 100644 --- a/js/runner.go +++ b/js/runner.go @@ -18,7 +18,6 @@ import ( "github.com/dop251/goja" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "golang.org/x/net/http2" "golang.org/x/time/rate" @@ -28,6 +27,7 @@ import ( "go.k6.io/k6/js/eventloop" "go.k6.io/k6/lib" "go.k6.io/k6/lib/consts" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/netext" "go.k6.io/k6/lib/types" "go.k6.io/k6/loader" @@ -61,7 +61,7 @@ type Runner struct { } // New returns a new Runner for the provided source -func New(piState *lib.TestPreInitState, src *loader.SourceData, filesystems map[string]afero.Fs) (*Runner, error) { +func New(piState *lib.TestPreInitState, src *loader.SourceData, filesystems map[string]fsext.Fs) (*Runner, error) { bundle, err := NewBundle(piState, src, filesystems) if err != nil { return nil, err diff --git a/js/runner_test.go b/js/runner_test.go index 73c80a2361a..c70ae3c2de2 100644 --- a/js/runner_test.go +++ b/js/runner_test.go @@ -27,7 +27,6 @@ import ( "github.com/sirupsen/logrus" logtest "github.com/sirupsen/logrus/hooks/test" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/time/rate" @@ -599,9 +598,9 @@ func TestRunnerIntegrationImports(t *testing.T) { name, data := name, data t.Run(name, func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() require.NoError(t, fs.MkdirAll("/path/to", 0o755)) - require.NoError(t, afero.WriteFile(fs, "/path/to/lib.js", []byte(`exports.default = "hi!";`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/lib.js", []byte(`exports.default = "hi!";`), 0o644)) r1, err := getSimpleRunner(t, data.filename, fmt.Sprintf(` var hi = require("%s").default; exports.default = function() { @@ -1491,7 +1490,7 @@ func TestVUIntegrationOpenFunctionErrorWhenSneaky(t *testing.T) { func TestVUDoesOpenUnderV0Condition(t *testing.T) { t.Parallel() - baseFS := afero.NewMemMapFs() + baseFS := fsext.NewMemMapFs() data := ` if (__VU == 0) { let data = open("/home/somebody/test.json"); @@ -1500,10 +1499,10 @@ func TestVUDoesOpenUnderV0Condition(t *testing.T) { console.log("hey") } ` - require.NoError(t, afero.WriteFile(baseFS, "/home/somebody/test.json", []byte(`42`), fs.ModePerm)) - require.NoError(t, afero.WriteFile(baseFS, "/script.js", []byte(data), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(baseFS, "/home/somebody/test.json", []byte(`42`), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(baseFS, "/script.js", []byte(data), fs.ModePerm)) - fs := fsext.NewCacheOnReadFs(baseFS, afero.NewMemMapFs(), 0) + fs := fsext.NewCacheOnReadFs(baseFS, fsext.NewMemMapFs(), 0) r, err := getSimpleRunner(t, "/script.js", data, fs) require.NoError(t, err) @@ -1515,7 +1514,7 @@ func TestVUDoesOpenUnderV0Condition(t *testing.T) { func TestVUDoesNotOpenUnderConditions(t *testing.T) { t.Parallel() - baseFS := afero.NewMemMapFs() + baseFS := fsext.NewMemMapFs() data := ` if (__VU > 0) { let data = open("/home/somebody/test.json"); @@ -1524,10 +1523,10 @@ func TestVUDoesNotOpenUnderConditions(t *testing.T) { console.log("hey") } ` - require.NoError(t, afero.WriteFile(baseFS, "/home/somebody/test.json", []byte(`42`), fs.ModePerm)) - require.NoError(t, afero.WriteFile(baseFS, "/script.js", []byte(data), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(baseFS, "/home/somebody/test.json", []byte(`42`), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(baseFS, "/script.js", []byte(data), fs.ModePerm)) - fs := fsext.NewCacheOnReadFs(baseFS, afero.NewMemMapFs(), 0) + fs := fsext.NewCacheOnReadFs(baseFS, fsext.NewMemMapFs(), 0) r, err := getSimpleRunner(t, "/script.js", data, fs) require.NoError(t, err) @@ -1540,7 +1539,7 @@ func TestVUDoesNotOpenUnderConditions(t *testing.T) { func TestVUDoesNonExistingPathnUnderConditions(t *testing.T) { t.Parallel() - baseFS := afero.NewMemMapFs() + baseFS := fsext.NewMemMapFs() data := ` if (__VU == 1) { let data = open("/home/nobody"); @@ -1549,9 +1548,9 @@ func TestVUDoesNonExistingPathnUnderConditions(t *testing.T) { console.log("hey") } ` - require.NoError(t, afero.WriteFile(baseFS, "/script.js", []byte(data), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(baseFS, "/script.js", []byte(data), fs.ModePerm)) - fs := fsext.NewCacheOnReadFs(baseFS, afero.NewMemMapFs(), 0) + fs := fsext.NewCacheOnReadFs(baseFS, fsext.NewMemMapFs(), 0) r, err := getSimpleRunner(t, "/script.js", data, fs) require.NoError(t, err) @@ -1987,7 +1986,7 @@ func TestInitContextForbidden(t *testing.T) { func TestArchiveRunningIntegrity(t *testing.T) { t.Parallel() - fileSystem := afero.NewMemMapFs() + fileSystem := fsext.NewMemMapFs() data := ` var fput = open("/home/somebody/test.json"); exports.options = { setupTimeout: "10s", teardownTimeout: "10s" }; @@ -2000,8 +1999,8 @@ func TestArchiveRunningIntegrity(t *testing.T) { } } ` - require.NoError(t, afero.WriteFile(fileSystem, "/home/somebody/test.json", []byte(`42`), fs.ModePerm)) - require.NoError(t, afero.WriteFile(fileSystem, "/script.js", []byte(data), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(fileSystem, "/home/somebody/test.json", []byte(`42`), fs.ModePerm)) + require.NoError(t, fsext.WriteFile(fileSystem, "/script.js", []byte(data), fs.ModePerm)) r1, err := getSimpleRunner(t, "/script.js", data, fileSystem) require.NoError(t, err) @@ -2045,8 +2044,8 @@ func TestArchiveRunningIntegrity(t *testing.T) { func TestArchiveNotPanicking(t *testing.T) { t.Parallel() - fileSystem := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fileSystem, "/non/existent", []byte(`42`), fs.ModePerm)) + fileSystem := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fileSystem, "/non/existent", []byte(`42`), fs.ModePerm)) r1, err := getSimpleRunner(t, "/script.js", ` var fput = open("/non/existent"); exports.default = function(data) {} @@ -2054,7 +2053,7 @@ func TestArchiveNotPanicking(t *testing.T) { require.NoError(t, err) arc := r1.MakeArchive() - arc.Filesystems = map[string]afero.Fs{"file": afero.NewMemMapFs()} + arc.Filesystems = map[string]fsext.Fs{"file": fsext.NewMemMapFs()} registry := metrics.NewRegistry() builtinMetrics := metrics.RegisterBuiltinMetrics(registry) r2, err := NewFromArchive( @@ -2327,7 +2326,7 @@ func TestVUPanic(t *testing.T) { } type multiFileTestCase struct { - fses map[string]afero.Fs + fses map[string]fsext.Fs rtOpts lib.RuntimeOptions cwd string script string @@ -2408,17 +2407,17 @@ func TestComplicatedFileImportsForGRPC(t *testing.T) { }, nil } - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() protoFile, err := ioutil.ReadFile("../vendor/google.golang.org/grpc/test/grpc_testing/test.proto") require.NoError(t, err) - require.NoError(t, afero.WriteFile(fs, "/path/to/service.proto", protoFile, 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/to/same-dir.proto", []byte( + require.NoError(t, fsext.WriteFile(fs, "/path/to/service.proto", protoFile, 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/path/to/same-dir.proto", []byte( `syntax = "proto3";package whatever;import "service.proto";`, ), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/subdir.proto", []byte( + require.NoError(t, fsext.WriteFile(fs, "/path/subdir.proto", []byte( `syntax = "proto3";package whatever;import "to/service.proto";`, ), 0o644)) - require.NoError(t, afero.WriteFile(fs, "/path/to/abs.proto", []byte( + require.NoError(t, fsext.WriteFile(fs, "/path/to/abs.proto", []byte( `syntax = "proto3";package whatever;import "/path/to/service.proto";`, ), 0o644)) @@ -2443,7 +2442,7 @@ func TestComplicatedFileImportsForGRPC(t *testing.T) { `, loadCode)) return multiFileTestCase{ - fses: map[string]afero.Fs{"file": fs, "https": afero.NewMemMapFs()}, + fses: map[string]fsext.Fs{"file": fs, "https": fsext.NewMemMapFs()}, rtOpts: lib.RuntimeOptions{CompatibilityMode: null.NewString("base", true)}, samples: make(chan metrics.SampleContainer, 100), cwd: cwd, expInitErr: expInitErr, expVUErr: expVUErr, script: script, diff --git a/lib/archive.go b/lib/archive.go index 3718689b252..2de180d5f47 100644 --- a/lib/archive.go +++ b/lib/archive.go @@ -15,8 +15,6 @@ import ( "strings" "time" - "github.com/spf13/afero" - "go.k6.io/k6/lib/fsext" "go.k6.io/k6/loader" ) @@ -37,7 +35,7 @@ func NormalizeAndAnonymizePath(path string) string { return homeDirRE.ReplaceAllString(p, `$1/$2/nobody`) } -func newNormalizedFs(fs afero.Fs) afero.Fs { +func newNormalizedFs(fs fsext.Fs) fsext.Fs { return fsext.NewChangePathFs(fs, fsext.ChangePathFunc(func(name string) (string, error) { return NormalizeAndAnonymizePath(name), nil })) @@ -62,7 +60,7 @@ type Archive struct { Pwd string `json:"pwd"` // only for json PwdURL *url.URL `json:"-"` - Filesystems map[string]afero.Fs `json:"-"` + Filesystems map[string]fsext.Fs `json:"-"` // Environment variables Env map[string]string `json:"env"` @@ -73,10 +71,10 @@ type Archive struct { Goos string `json:"goos"` } -func (arc *Archive) getFs(name string) afero.Fs { +func (arc *Archive) getFs(name string) fsext.Fs { fs, ok := arc.Filesystems[name] if !ok { - fs = afero.NewMemMapFs() + fs = fsext.NewMemMapFs() if name == "file" { fs = newNormalizedFs(fs) } @@ -110,7 +108,7 @@ func (arc *Archive) loadMetadataJSON(data []byte) (err error) { // ReadArchive reads an archive created by Archive.Write from a reader. func ReadArchive(in io.Reader) (*Archive, error) { r := tar.NewReader(in) - arc := &Archive{Filesystems: make(map[string]afero.Fs, 2)} + arc := &Archive{Filesystems: make(map[string]fsext.Fs, 2)} // initialize both fses _ = arc.getFs("https") _ = arc.getFs("file") @@ -163,7 +161,7 @@ func ReadArchive(in io.Reader) (*Archive, error) { case "https", "file": fileSystem := arc.getFs(pfx) name = filepath.FromSlash(name) - err = afero.WriteFile(fileSystem, name, data, fs.FileMode(hdr.Mode)) + err = fsext.WriteFile(fileSystem, name, data, fs.FileMode(hdr.Mode)) if err != nil { return nil, err } @@ -181,7 +179,7 @@ func ReadArchive(in io.Reader) (*Archive, error) { if err != nil { return nil, err } - err = afero.WriteFile(arc.getFs(scheme), pathOnFs, arc.Data, 0o644) // TODO fix the mode ? + err = fsext.WriteFile(arc.getFs(scheme), pathOnFs, arc.Data, 0o644) // TODO fix the mode ? if err != nil { return nil, err } @@ -293,11 +291,11 @@ func (arc *Archive) Write(out io.Writer) error { } paths = append(paths, normalizedPath) - files[normalizedPath], err = afero.ReadFile(filesystem, filePath) + files[normalizedPath], err = fsext.ReadFile(filesystem, filePath) return err }) - if err = fsext.Walk(filesystem, afero.FilePathSeparator, walkFunc); err != nil { + if err = fsext.Walk(filesystem, fsext.FilePathSeparator, walkFunc); err != nil { return err } if len(files) == 0 { diff --git a/lib/archive_test.go b/lib/archive_test.go index e185ee62dd6..96036de086c 100644 --- a/lib/archive_test.go +++ b/lib/archive_test.go @@ -10,7 +10,6 @@ import ( "runtime" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v3" @@ -53,15 +52,15 @@ func TestNormalizeAndAnonymizePath(t *testing.T) { } } -func makeMemMapFs(t *testing.T, input map[string][]byte) afero.Fs { - fs := afero.NewMemMapFs() +func makeMemMapFs(t *testing.T, input map[string][]byte) fsext.Fs { + fs := fsext.NewMemMapFs() for path, data := range input { - require.NoError(t, afero.WriteFile(fs, path, data, 0o644)) + require.NoError(t, fsext.WriteFile(fs, path, data, 0o644)) } return fs } -func getMapKeys(m map[string]afero.Fs) []string { +func getMapKeys(m map[string]fsext.Fs) []string { keys := make([]string, 0, len(m)) for key := range m { keys = append(keys, key) @@ -70,18 +69,16 @@ func getMapKeys(m map[string]afero.Fs) []string { return keys } -func diffMapFilesystems(t *testing.T, first, second map[string]afero.Fs) bool { +func diffMapFilesystems(t *testing.T, first, second map[string]fsext.Fs) { require.ElementsMatch(t, getMapKeys(first), getMapKeys(second), "fs map keys don't match %s, %s", getMapKeys(first), getMapKeys(second)) for key, fs := range first { secondFs := second[key] diffFilesystems(t, fs, secondFs) } - - return true } -func diffFilesystems(t *testing.T, first, second afero.Fs) { +func diffFilesystems(t *testing.T, first, second fsext.Fs) { diffFilesystemsDir(t, first, second, "/") } @@ -93,11 +90,11 @@ func getInfoNames(infos []fs.FileInfo) []string { return names } -func diffFilesystemsDir(t *testing.T, first, second afero.Fs, dirname string) { - firstInfos, err := afero.ReadDir(first, dirname) +func diffFilesystemsDir(t *testing.T, first, second fsext.Fs, dirname string) { + firstInfos, err := fsext.ReadDir(first, dirname) require.NoError(t, err, dirname) - secondInfos, err := afero.ReadDir(first, dirname) + secondInfos, err := fsext.ReadDir(first, dirname) require.NoError(t, err, dirname) require.ElementsMatch(t, getInfoNames(firstInfos), getInfoNames(secondInfos), "directory: "+dirname) @@ -107,10 +104,10 @@ func diffFilesystemsDir(t *testing.T, first, second afero.Fs, dirname string) { diffFilesystemsDir(t, first, second, path) continue } - firstData, err := afero.ReadFile(first, path) + firstData, err := fsext.ReadFile(first, path) require.NoError(t, err, path) - secondData, err := afero.ReadFile(second, path) + secondData, err := fsext.ReadFile(second, path) require.NoError(t, err, path) assert.Equal(t, firstData, secondData, path) @@ -131,7 +128,7 @@ func TestArchiveReadWrite(t *testing.T) { FilenameURL: &url.URL{Scheme: "file", Path: "/path/to/a.js"}, Data: []byte(`// a contents`), PwdURL: &url.URL{Scheme: "file", Path: "/path/to"}, - Filesystems: map[string]afero.Fs{ + Filesystems: map[string]fsext.Fs{ "file": makeMemMapFs(t, map[string][]byte{ "/path/to/a.js": []byte(`// a contents`), "/path/to/b.js": []byte(`// b contents`), @@ -183,7 +180,7 @@ func TestArchiveReadWrite(t *testing.T) { K6Version: consts.Version, Data: []byte(`// a contents`), PwdURL: &url.URL{Scheme: "file", Path: entry.Pwd}, - Filesystems: map[string]afero.Fs{ + Filesystems: map[string]fsext.Fs{ "file": makeMemMapFs(t, map[string][]byte{ fmt.Sprintf("%s/a.js", entry.Pwd): []byte(`// a contents`), fmt.Sprintf("%s/b.js", entry.Pwd): []byte(`// b contents`), @@ -207,7 +204,7 @@ func TestArchiveReadWrite(t *testing.T) { Data: []byte(`// a contents`), PwdURL: &url.URL{Scheme: "file", Path: entry.PwdNormAnon}, - Filesystems: map[string]afero.Fs{ + Filesystems: map[string]fsext.Fs{ "file": makeMemMapFs(t, map[string][]byte{ fmt.Sprintf("%s/a.js", entry.PwdNormAnon): []byte(`// a contents`), fmt.Sprintf("%s/b.js", entry.PwdNormAnon): []byte(`// b contents`), @@ -253,11 +250,11 @@ func TestArchiveJSONEscape(t *testing.T) { func TestUsingCacheFromCacheOnReadFs(t *testing.T) { t.Parallel() - base := afero.NewMemMapFs() - cached := afero.NewMemMapFs() + base := fsext.NewMemMapFs() + cached := fsext.NewMemMapFs() // we specifically have different contents in both places - require.NoError(t, afero.WriteFile(base, "/wrong", []byte(`ooops`), 0o644)) - require.NoError(t, afero.WriteFile(cached, "/correct", []byte(`test`), 0o644)) + require.NoError(t, fsext.WriteFile(base, "/wrong", []byte(`ooops`), 0o644)) + require.NoError(t, fsext.WriteFile(cached, "/correct", []byte(`test`), 0o644)) arc := &Archive{ Type: "js", @@ -265,7 +262,7 @@ func TestUsingCacheFromCacheOnReadFs(t *testing.T) { K6Version: consts.Version, Data: []byte(`test`), PwdURL: &url.URL{Scheme: "file", Path: "/"}, - Filesystems: map[string]afero.Fs{ + Filesystems: map[string]fsext.Fs{ "file": fsext.NewCacheOnReadFs(base, cached, 0), }, } @@ -276,11 +273,11 @@ func TestUsingCacheFromCacheOnReadFs(t *testing.T) { newArc, err := ReadArchive(buf) require.NoError(t, err) - data, err := afero.ReadFile(newArc.Filesystems["file"], "/correct") + data, err := fsext.ReadFile(newArc.Filesystems["file"], "/correct") require.NoError(t, err) require.Equal(t, string(data), "test") - data, err = afero.ReadFile(newArc.Filesystems["file"], "/wrong") + data, err = fsext.ReadFile(newArc.Filesystems["file"], "/wrong") require.Error(t, err) require.Nil(t, data) } @@ -305,8 +302,8 @@ func TestArchiveWithDataNotInFS(t *testing.T) { func TestMalformedMetadata(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/metadata.json", []byte("{,}"), 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/metadata.json", []byte("{,}"), 0o644)) b, err := dumpMemMapFsToBuf(fs) require.NoError(t, err) _, err = ReadArchive(b) @@ -337,7 +334,7 @@ func TestStrangePaths(t *testing.T) { FilenameURL: &url.URL{Scheme: "file", Path: pathToChange}, Data: []byte(`// ` + pathToChange + ` contents`), PwdURL: &url.URL{Scheme: "file", Path: path.Dir(pathToChange)}, - Filesystems: map[string]afero.Fs{ + Filesystems: map[string]fsext.Fs{ "file": makeMemMapFs(t, otherMap), }, } @@ -358,16 +355,16 @@ func TestStrangePaths(t *testing.T) { assert.Equal(t, arc1, arc2, pathToChange) - arc1Filesystems["https"] = afero.NewMemMapFs() + arc1Filesystems["https"] = fsext.NewMemMapFs() diffMapFilesystems(t, arc1Filesystems, arc2Filesystems) } } func TestStdinArchive(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() // we specifically have different contents in both places - require.NoError(t, afero.WriteFile(fs, "/-", []byte(`test`), 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/-", []byte(`test`), 0o644)) arc := &Archive{ Type: "js", @@ -375,7 +372,7 @@ func TestStdinArchive(t *testing.T) { K6Version: consts.Version, Data: []byte(`test`), PwdURL: &url.URL{Scheme: "file", Path: "/"}, - Filesystems: map[string]afero.Fs{ + Filesystems: map[string]fsext.Fs{ "file": fs, }, } @@ -386,7 +383,7 @@ func TestStdinArchive(t *testing.T) { newArc, err := ReadArchive(buf) require.NoError(t, err) - data, err := afero.ReadFile(newArc.Filesystems["file"], "/-") + data, err := fsext.ReadFile(newArc.Filesystems["file"], "/-") require.NoError(t, err) require.Equal(t, string(data), "test") } diff --git a/lib/fsext/afero_links.go b/lib/fsext/afero_links.go new file mode 100644 index 00000000000..266a0242037 --- /dev/null +++ b/lib/fsext/afero_links.go @@ -0,0 +1,56 @@ +package fsext + +import ( + "io/fs" + + "github.com/spf13/afero" +) + +// TODO: reimplement this while tackling https://github.com/grafana/k6/issues/1079 + +// Fs represents a file system +type Fs = afero.Fs + +// FilePathSeparator is the FilePathSeparator to be used within a file system +const FilePathSeparator = afero.FilePathSeparator + +// NewMemMapFs returns a Fs that is in memory +func NewMemMapFs() Fs { + return afero.NewMemMapFs() +} + +// NewReadOnlyFs returns a Fs wrapping the provided one and returning error on any not read operation. +func NewReadOnlyFs(fs Fs) Fs { + return afero.NewReadOnlyFs(fs) +} + +// WriteFile writes the provided data to the provided fs in the provided filename +func WriteFile(fs Fs, filename string, data []byte, perm fs.FileMode) error { + return afero.WriteFile(fs, filename, data, perm) +} + +// ReadFile reads the whole file from the filesystem +func ReadFile(fs Fs, filename string) ([]byte, error) { + return afero.ReadFile(fs, filename) +} + +// ReadDir reads the info for each file in the provided dirname +func ReadDir(fs Fs, dirname string) ([]fs.FileInfo, error) { + return afero.ReadDir(fs, dirname) +} + +// NewOsFs returns a new wrapps os.Fs +func NewOsFs() Fs { + return afero.NewOsFs() +} + +// Exists checks if the provided path exists on the filesystem +func Exists(fs Fs, path string) (bool, error) { + return afero.Exists(fs, path) +} + +// IsDir checks if the provided path is a directory +func IsDir(fs Fs, path string) (bool, error) { + // TODO move fix here + return afero.IsDir(fs, path) +} diff --git a/lib/old_archive_test.go b/lib/old_archive_test.go index b0802baed2a..f235f92ca6d 100644 --- a/lib/old_archive_test.go +++ b/lib/old_archive_test.go @@ -9,18 +9,17 @@ import ( "path/filepath" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/require" "go.k6.io/k6/lib/fsext" ) -func dumpMemMapFsToBuf(fileSystem afero.Fs) (*bytes.Buffer, error) { +func dumpMemMapFsToBuf(fileSystem fsext.Fs) (*bytes.Buffer, error) { b := bytes.NewBuffer(nil) w := tar.NewWriter(b) - err := fsext.Walk(fileSystem, afero.FilePathSeparator, + err := fsext.Walk(fileSystem, fsext.FilePathSeparator, filepath.WalkFunc(func(filePath string, info fs.FileInfo, err error) error { - if filePath == afero.FilePathSeparator { + if filePath == fsext.FilePathSeparator { return nil // skip the root } if err != nil { @@ -34,7 +33,7 @@ func dumpMemMapFsToBuf(fileSystem afero.Fs) (*bytes.Buffer, error) { }) } var data []byte - data, err = afero.ReadFile(fileSystem, filePath) + data, err = fsext.ReadFile(fileSystem, filePath) if err != nil { return err } @@ -94,7 +93,7 @@ func TestOldArchive(t *testing.T) { buf, err := dumpMemMapFsToBuf(fs) require.NoError(t, err) - expectedFilesystems := map[string]afero.Fs{ + expectedFilesystems := map[string]fsext.Fs{ "file": makeMemMapFs(t, map[string][]byte{ "/C:/something/path": []byte(`windows file`), "/absolulte/path": []byte(`unix file`), diff --git a/loader/cdnjs_test.go b/loader/cdnjs_test.go index 87b56b2d9c3..0a0fc50e44f 100644 --- a/loader/cdnjs_test.go +++ b/loader/cdnjs_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" ) @@ -70,7 +70,7 @@ func TestCDNJS(t *testing.T) { require.Empty(t, resolvedURL.Scheme) require.Equal(t, path, resolvedURL.Opaque) - data, err := Load(logger, map[string]afero.Fs{"https": afero.NewMemMapFs()}, resolvedURL, path) + data, err := Load(logger, map[string]fsext.Fs{"https": fsext.NewMemMapFs()}, resolvedURL, path) require.NoError(t, err) assert.Equal(t, resolvedURL, data.URL) assert.NotEmpty(t, data.Data) @@ -100,7 +100,7 @@ func TestCDNJS(t *testing.T) { pathURL, err := url.Parse(src) require.NoError(t, err) - _, err = Load(logger, map[string]afero.Fs{"https": afero.NewMemMapFs()}, pathURL, path) + _, err = Load(logger, map[string]fsext.Fs{"https": fsext.NewMemMapFs()}, pathURL, path) require.Error(t, err) assert.Contains(t, err.Error(), "not found: https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/nonexistent.js") }) diff --git a/loader/filesystems.go b/loader/filesystems.go index ed65d114d12..043d298a111 100644 --- a/loader/filesystems.go +++ b/loader/filesystems.go @@ -3,13 +3,11 @@ package loader import ( "runtime" - "github.com/spf13/afero" - "go.k6.io/k6/lib/fsext" ) // CreateFilesystems creates the correct filesystem map for the current OS -func CreateFilesystems(osfs afero.Fs) map[string]afero.Fs { +func CreateFilesystems(osfs fsext.Fs) map[string]fsext.Fs { // We want to eliminate disk access at runtime, so we set up a memory mapped cache that's // written every time something is read from the real filesystem. This cache is then used for // successive spawns to read from (they have no access to the real disk). @@ -20,8 +18,8 @@ func CreateFilesystems(osfs afero.Fs) map[string]afero.Fs { // volumes osfs = fsext.NewTrimFilePathSeparatorFs(osfs) } - return map[string]afero.Fs{ - "file": fsext.NewCacheOnReadFs(osfs, afero.NewMemMapFs(), 0), - "https": afero.NewMemMapFs(), + return map[string]fsext.Fs{ + "file": fsext.NewCacheOnReadFs(osfs, fsext.NewMemMapFs(), 0), + "https": fsext.NewMemMapFs(), } } diff --git a/loader/github_test.go b/loader/github_test.go index 44eabeb4dd4..a420c6c9a5e 100644 --- a/loader/github_test.go +++ b/loader/github_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" ) @@ -32,7 +32,7 @@ func TestGithub(t *testing.T) { require.Equal(t, path, resolvedURL.Opaque) t.Run("not cached", func(t *testing.T) { t.Parallel() - data, err := Load(logger, map[string]afero.Fs{"https": afero.NewMemMapFs()}, resolvedURL, path) + data, err := Load(logger, map[string]fsext.Fs{"https": fsext.NewMemMapFs()}, resolvedURL, path) require.NoError(t, err) assert.Equal(t, data.URL, resolvedURL) assert.Equal(t, path, data.URL.String()) @@ -41,13 +41,13 @@ func TestGithub(t *testing.T) { t.Run("cached", func(t *testing.T) { t.Parallel() - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() testData := []byte("test data") - err := afero.WriteFile(fs, "/github.com/github/gitignore/Go.gitignore", testData, 0o644) + err := fsext.WriteFile(fs, "/github.com/github/gitignore/Go.gitignore", testData, 0o644) require.NoError(t, err) - data, err := Load(logger, map[string]afero.Fs{"https": fs}, resolvedURL, path) + data, err := Load(logger, map[string]fsext.Fs{"https": fs}, resolvedURL, path) require.NoError(t, err) assert.Equal(t, path, data.URL.String()) assert.Equal(t, data.Data, testData) diff --git a/loader/loader.go b/loader/loader.go index a623c20b25d..534764968cc 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -16,7 +16,7 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/spf13/afero" + "go.k6.io/k6/lib/fsext" ) // SourceData wraps a source file; data and filename. @@ -149,11 +149,11 @@ func Dir(old *url.URL) *url.URL { return old.ResolveReference(&url.URL{Path: "./"}) } -// Load loads the provided moduleSpecifier from the given filesystems which are map of afero.Fs +// Load loads the provided moduleSpecifier from the given filesystems which are map of fsext.Fs // for a given scheme which is they key of the map. If the scheme is https then a request will // be made if the files is not found in the map and written to the map. func Load( - logger logrus.FieldLogger, filesystems map[string]afero.Fs, moduleSpecifier *url.URL, originalModuleSpecifier string, + logger logrus.FieldLogger, filesystems map[string]fsext.Fs, moduleSpecifier *url.URL, originalModuleSpecifier string, ) (*SourceData, error) { logger.WithFields( logrus.Fields{ @@ -164,7 +164,7 @@ func Load( var pathOnFs string switch { case moduleSpecifier.Opaque != "": // This is loader - pathOnFs = filepath.Join(afero.FilePathSeparator, moduleSpecifier.Opaque) + pathOnFs = filepath.Join(fsext.FilePathSeparator, moduleSpecifier.Opaque) case moduleSpecifier.Scheme == "": pathOnFs = path.Clean(moduleSpecifier.String()) default: @@ -180,7 +180,7 @@ func Load( return nil, err } - data, err := afero.ReadFile(filesystems[scheme], pathOnFs) + data, err := fsext.ReadFile(filesystems[scheme], pathOnFs) if err == nil { return &SourceData{URL: moduleSpecifier, Data: data}, nil @@ -210,9 +210,9 @@ func Load( result, err = loadRemoteURL(logger, finalModuleSpecifierURL) if err == nil { result.URL = moduleSpecifier - // TODO maybe make an afero.Fs which makes request directly and than use CacheOnReadFs + // TODO maybe make an fsext.Fs which makes request directly and than use CacheOnReadFs // on top of as with the `file` scheme fs - _ = afero.WriteFile(filesystems[scheme], pathOnFs, result.Data, 0o644) + _ = fsext.WriteFile(filesystems[scheme], pathOnFs, result.Data, 0o644) return result, nil } diff --git a/loader/loader_test.go b/loader/loader_test.go index d4b8c08ef8c..1e3aa109cf9 100644 --- a/loader/loader_test.go +++ b/loader/loader_test.go @@ -8,10 +8,10 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/lib/testutils/httpmultibin" "go.k6.io/k6/loader" @@ -138,10 +138,10 @@ func TestLoad(t *testing.T) { moduleURL, err := loader.Resolve(pwdURL, data.path) require.NoError(t, err) - filesystems := make(map[string]afero.Fs) - filesystems["file"] = afero.NewMemMapFs() + filesystems := make(map[string]fsext.Fs) + filesystems["file"] = fsext.NewMemMapFs() assert.NoError(t, filesystems["file"].MkdirAll("/path/to", 0o755)) - assert.NoError(t, afero.WriteFile(filesystems["file"], "/path/to/file.txt", []byte("hi"), 0o644)) + assert.NoError(t, fsext.WriteFile(filesystems["file"], "/path/to/file.txt", []byte("hi"), 0o644)) src, err := loader.Load(logger, filesystems, moduleURL, data.path) require.NoError(t, err) @@ -152,10 +152,10 @@ func TestLoad(t *testing.T) { t.Run("Nonexistent", func(t *testing.T) { t.Parallel() - filesystems := make(map[string]afero.Fs) - filesystems["file"] = afero.NewMemMapFs() + filesystems := make(map[string]fsext.Fs) + filesystems["file"] = fsext.NewMemMapFs() assert.NoError(t, filesystems["file"].MkdirAll("/path/to", 0o755)) - assert.NoError(t, afero.WriteFile(filesystems["file"], "/path/to/file.txt", []byte("hi"), 0o644)) + assert.NoError(t, fsext.WriteFile(filesystems["file"], "/path/to/file.txt", []byte("hi"), 0o644)) root, err := url.Parse("file:///") require.NoError(t, err) @@ -176,7 +176,7 @@ func TestLoad(t *testing.T) { t.Parallel() t.Run("From local", func(t *testing.T) { t.Parallel() - filesystems := map[string]afero.Fs{"https": afero.NewMemMapFs()} + filesystems := map[string]fsext.Fs{"https": fsext.NewMemMapFs()} root, err := url.Parse("file:///") require.NoError(t, err) @@ -192,7 +192,7 @@ func TestLoad(t *testing.T) { t.Run("Absolute", func(t *testing.T) { t.Parallel() - filesystems := map[string]afero.Fs{"https": afero.NewMemMapFs()} + filesystems := map[string]fsext.Fs{"https": fsext.NewMemMapFs()} pwdURL, err := url.Parse(sr("HTTPSBIN_URL")) require.NoError(t, err) @@ -208,7 +208,7 @@ func TestLoad(t *testing.T) { t.Run("Relative", func(t *testing.T) { t.Parallel() - filesystems := map[string]afero.Fs{"https": afero.NewMemMapFs()} + filesystems := map[string]fsext.Fs{"https": fsext.NewMemMapFs()} pwdURL, err := url.Parse(sr("HTTPSBIN_URL")) require.NoError(t, err) @@ -232,7 +232,7 @@ func TestLoad(t *testing.T) { moduleSpecifierURL, err := loader.Resolve(root, moduleSpecifier) require.NoError(t, err) - filesystems := map[string]afero.Fs{"https": afero.NewMemMapFs()} + filesystems := map[string]fsext.Fs{"https": fsext.NewMemMapFs()} src, err := loader.Load(logger, filesystems, moduleSpecifierURL, moduleSpecifier) require.NoError(t, err) @@ -259,7 +259,7 @@ func TestLoad(t *testing.T) { {"HOST", "some-path-that-doesnt-exist.js"}, } - filesystems := map[string]afero.Fs{"https": afero.NewMemMapFs()} + filesystems := map[string]fsext.Fs{"https": fsext.NewMemMapFs()} for _, data := range testData { moduleSpecifier := data.moduleSpecifier t.Run(data.name, func(t *testing.T) { diff --git a/loader/readsource.go b/loader/readsource.go index 3d2e50aac5a..3c4f2c19a2b 100644 --- a/loader/readsource.go +++ b/loader/readsource.go @@ -8,14 +8,13 @@ import ( "path/filepath" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "go.k6.io/k6/lib/fsext" ) // ReadSource Reads a source file from any supported destination. func ReadSource( - logger logrus.FieldLogger, src, pwd string, filesystems map[string]afero.Fs, stdin io.Reader, + logger logrus.FieldLogger, src, pwd string, filesystems map[string]fsext.Fs, stdin io.Reader, ) (*SourceData, error) { if src == "-" { data, err := io.ReadAll(stdin) @@ -23,7 +22,8 @@ func ReadSource( return nil, err } // TODO: don't do it in this way ... - err = afero.WriteFile(filesystems["file"].(fsext.CacheLayerGetter).GetCachingFs(), "/-", data, 0o644) + //nolint:forcetypeassert + err = fsext.WriteFile(filesystems["file"].(fsext.CacheLayerGetter).GetCachingFs(), "/-", data, 0o644) if err != nil { return nil, fmt.Errorf("caching data read from -: %w", err) } @@ -37,8 +37,8 @@ func ReadSource( } // All paths should start with a / in all fses. This is mostly for windows where it will start // with a volume name : C:\something.js - srcLocalPath = filepath.Clean(afero.FilePathSeparator + srcLocalPath) - if ok, _ := afero.Exists(filesystems["file"], srcLocalPath); ok { + srcLocalPath = filepath.Clean(fsext.FilePathSeparator + srcLocalPath) + if ok, _ := fsext.Exists(filesystems["file"], srcLocalPath); ok { // there is file on the local disk ... lets use it :) return Load(logger, filesystems, &url.URL{Scheme: "file", Path: filepath.ToSlash(srcLocalPath)}, src) } diff --git a/loader/readsource_test.go b/loader/readsource_test.go index 96633b161dd..3451c992c2d 100644 --- a/loader/readsource_test.go +++ b/loader/readsource_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/require" "go.k6.io/k6/lib/fsext" @@ -38,15 +37,15 @@ func TestReadSourceSTDINCache(t *testing.T) { logger.SetOutput(testutils.NewTestOutput(t)) data := []byte(`test contents`) r := bytes.NewReader(data) - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() sourceData, err := ReadSource(logger, "-", "/path/to/pwd", - map[string]afero.Fs{"file": fsext.NewCacheOnReadFs(nil, fs, 0)}, r) + map[string]fsext.Fs{"file": fsext.NewCacheOnReadFs(nil, fs, 0)}, r) require.NoError(t, err) require.Equal(t, &SourceData{ URL: &url.URL{Scheme: "file", Path: "/-"}, Data: data, }, sourceData) - fileData, err := afero.ReadFile(fs, "/-") + fileData, err := fsext.ReadFile(fs, "/-") require.NoError(t, err) require.Equal(t, data, fileData) } @@ -56,9 +55,9 @@ func TestReadSourceRelative(t *testing.T) { logger := logrus.New() logger.SetOutput(testutils.NewTestOutput(t)) data := []byte(`test contents`) - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/path/to/somewhere/script.js", data, 0o644)) - sourceData, err := ReadSource(logger, "../somewhere/script.js", "/path/to/pwd", map[string]afero.Fs{"file": fs}, nil) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/path/to/somewhere/script.js", data, 0o644)) + sourceData, err := ReadSource(logger, "../somewhere/script.js", "/path/to/pwd", map[string]fsext.Fs{"file": fs}, nil) require.NoError(t, err) require.Equal(t, &SourceData{ URL: &url.URL{Scheme: "file", Path: "/path/to/somewhere/script.js"}, @@ -72,10 +71,10 @@ func TestReadSourceAbsolute(t *testing.T) { logger.SetOutput(testutils.NewTestOutput(t)) data := []byte(`test contents`) r := bytes.NewReader(data) - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/a/b", data, 0o644)) - require.NoError(t, afero.WriteFile(fs, "/c/a/b", []byte("wrong"), 0o644)) - sourceData, err := ReadSource(logger, "/a/b", "/c", map[string]afero.Fs{"file": fs}, r) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/a/b", data, 0o644)) + require.NoError(t, fsext.WriteFile(fs, "/c/a/b", []byte("wrong"), 0o644)) + sourceData, err := ReadSource(logger, "/a/b", "/c", map[string]fsext.Fs{"file": fs}, r) require.NoError(t, err) require.Equal(t, &SourceData{ URL: &url.URL{Scheme: "file", Path: "/a/b"}, @@ -88,10 +87,10 @@ func TestReadSourceHttps(t *testing.T) { logger := logrus.New() logger.SetOutput(testutils.NewTestOutput(t)) data := []byte(`test contents`) - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/github.com/something", data, 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/github.com/something", data, 0o644)) sourceData, err := ReadSource(logger, "https://github.com/something", "/c", - map[string]afero.Fs{"file": afero.NewMemMapFs(), "https": fs}, nil) + map[string]fsext.Fs{"file": fsext.NewMemMapFs(), "https": fs}, nil) require.NoError(t, err) require.Equal(t, &SourceData{ URL: &url.URL{Scheme: "https", Host: "github.com", Path: "/something"}, @@ -104,10 +103,10 @@ func TestReadSourceHttpError(t *testing.T) { logger := logrus.New() logger.SetOutput(testutils.NewTestOutput(t)) data := []byte(`test contents`) - fs := afero.NewMemMapFs() - require.NoError(t, afero.WriteFile(fs, "/github.com/something", data, 0o644)) + fs := fsext.NewMemMapFs() + require.NoError(t, fsext.WriteFile(fs, "/github.com/something", data, 0o644)) _, err := ReadSource(logger, "http://github.com/something", "/c", - map[string]afero.Fs{"file": afero.NewMemMapFs(), "https": fs}, nil) + map[string]fsext.Fs{"file": fsext.NewMemMapFs(), "https": fs}, nil) require.Error(t, err) require.Contains(t, err.Error(), `only supported schemes for imports are file and https`) } @@ -116,9 +115,9 @@ func TestReadSourceMissingFileError(t *testing.T) { t.Parallel() logger := logrus.New() logger.SetOutput(testutils.NewTestOutput(t)) - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() _, err := ReadSource(logger, "some file with spaces.js", "/c", - map[string]afero.Fs{"file": afero.NewMemMapFs(), "https": fs}, nil) + map[string]fsext.Fs{"file": fsext.NewMemMapFs(), "https": fs}, nil) require.Error(t, err) require.Contains(t, err.Error(), `The moduleSpecifier "some file with spaces.js" couldn't be found on local disk.`) } diff --git a/log/file.go b/log/file.go index 64ae4d30664..b03de9f50e2 100644 --- a/log/file.go +++ b/log/file.go @@ -12,7 +12,7 @@ import ( "syscall" "github.com/sirupsen/logrus" - "github.com/spf13/afero" + "go.k6.io/k6/lib/fsext" ) // fileHookBufferSize is a default size for the fileHook's loglines channel. @@ -20,7 +20,7 @@ const fileHookBufferSize = 100 // fileHook is a hook to handle writing to local files. type fileHook struct { - fs afero.Fs + fs fsext.Fs fallbackLogger logrus.FieldLogger loglines chan []byte path string @@ -31,7 +31,7 @@ type fileHook struct { // FileHookFromConfigLine returns new fileHook hook. func FileHookFromConfigLine( - fs afero.Fs, getCwd func() (string, error), + fs fsext.Fs, getCwd func() (string, error), fallbackLogger logrus.FieldLogger, line string, ) (AsyncHook, error) { hook := &fileHook{ diff --git a/log/file_test.go b/log/file_test.go index 6269fd2664e..449cb961598 100644 --- a/log/file_test.go +++ b/log/file_test.go @@ -9,9 +9,9 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.k6.io/k6/lib/fsext" ) type nopCloser struct { @@ -95,7 +95,7 @@ func TestFileHookFromConfigLine(t *testing.T) { } res, err := FileHookFromConfigLine( - afero.NewMemMapFs(), getCwd, logrus.New(), test.line) + fsext.NewMemMapFs(), getCwd, logrus.New(), test.line) if test.err { require.Error(t, err) diff --git a/output/csv/output_test.go b/output/csv/output_test.go index 971fdc18ecf..8e85d3b9592 100644 --- a/output/csv/output_test.go +++ b/output/csv/output_test.go @@ -11,11 +11,11 @@ import ( "testing" "time" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/metrics" "go.k6.io/k6/output" @@ -317,8 +317,8 @@ func TestSampleToRow(t *testing.T) { } } -func readUnCompressedFile(fileName string, fs afero.Fs) string { - csvbytes, err := afero.ReadFile(fs, fileName) +func readUnCompressedFile(fileName string, fs fsext.Fs) string { + csvbytes, err := fsext.ReadFile(fs, fileName) if err != nil { return err.Error() } @@ -326,7 +326,7 @@ func readUnCompressedFile(fileName string, fs afero.Fs) string { return fmt.Sprintf("%s", csvbytes) } -func readCompressedFile(fileName string, fs afero.Fs) string { +func readCompressedFile(fileName string, fs fsext.Fs) string { file, err := fs.Open(fileName) if err != nil { return err.Error() @@ -355,7 +355,7 @@ func TestRun(t *testing.T) { testData := []struct { samples []metrics.SampleContainer fileName string - fileReaderFunc func(fileName string, fs afero.Fs) string + fileReaderFunc func(fileName string, fs fsext.Fs) string timeFormat string outputContent string }{ @@ -475,7 +475,7 @@ func TestRun(t *testing.T) { data := data t.Run(name, func(t *testing.T) { t.Parallel() - mem := afero.NewMemMapFs() + mem := fsext.NewMemMapFs() env := make(map[string]string) if data.timeFormat != "" { env["K6_CSV_TIME_FORMAT"] = data.timeFormat diff --git a/output/json/benchmark_test.go b/output/json/benchmark_test.go index 6fcc6b12ca7..1273486a9fe 100644 --- a/output/json/benchmark_test.go +++ b/output/json/benchmark_test.go @@ -5,8 +5,8 @@ import ( "path" "testing" - "github.com/spf13/afero" "github.com/stretchr/testify/require" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/output" ) @@ -17,7 +17,7 @@ func BenchmarkFlushMetrics(b *testing.B) { out, err := New(output.Params{ Logger: testutils.NewLogger(b), StdOut: stdout, - FS: afero.NewOsFs(), + FS: fsext.NewOsFs(), ConfigArgument: path.Join(dir, "test.gz"), }) require.NoError(b, err) diff --git a/output/json/json_test.go b/output/json/json_test.go index 640627c228f..4f72da27191 100644 --- a/output/json/json_test.go +++ b/output/json/json_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/testutils" "go.k6.io/k6/metrics" "go.k6.io/k6/output" @@ -137,7 +137,7 @@ func TestJsonOutputFileError(t *testing.T) { t.Parallel() stdout := new(bytes.Buffer) - fs := afero.NewReadOnlyFs(afero.NewMemMapFs()) + fs := fsext.NewReadOnlyFs(fsext.NewMemMapFs()) out, err := New(output.Params{ Logger: testutils.NewLogger(t), StdOut: stdout, @@ -152,7 +152,7 @@ func TestJsonOutputFile(t *testing.T) { t.Parallel() stdout := new(bytes.Buffer) - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() out, err := New(output.Params{ Logger: testutils.NewLogger(t), StdOut: stdout, @@ -180,7 +180,7 @@ func TestJsonOutputFileGzipped(t *testing.T) { t.Parallel() stdout := new(bytes.Buffer) - fs := afero.NewMemMapFs() + fs := fsext.NewMemMapFs() out, err := New(output.Params{ Logger: testutils.NewLogger(t), StdOut: stdout, diff --git a/output/types.go b/output/types.go index 0d3ca08ec4e..a4223acb856 100644 --- a/output/types.go +++ b/output/types.go @@ -9,9 +9,9 @@ import ( "net/url" "github.com/sirupsen/logrus" - "github.com/spf13/afero" "go.k6.io/k6/lib" + "go.k6.io/k6/lib/fsext" "go.k6.io/k6/metrics" ) @@ -25,7 +25,7 @@ type Params struct { Environment map[string]string StdOut io.Writer StdErr io.Writer - FS afero.Fs + FS fsext.Fs ScriptPath *url.URL ScriptOptions lib.Options RuntimeOptions lib.RuntimeOptions