Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support file scheme in open and experimental fs #4513

Merged
merged 2 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions internal/js/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,11 @@ func TestOpen(t *testing.T) {
openPath: "/path/to/file.txt",
pwd: "/path",
},
{
name: "file scheme",
openPath: "file:///path/to/file.txt",
pwd: "/path",
},
{
name: "file is dir",
openPath: "/path/to/",
Expand Down Expand Up @@ -687,6 +692,10 @@ func TestOpen(t *testing.T) {
filePath := filepath.Join(prefix, "/path/to/file.txt")
require.NoError(t, fs.MkdirAll(filepath.Join(prefix, "/path/to"), 0o755))
require.NoError(t, fsext.WriteFile(fs, filePath, []byte(`hi`), 0o644))
fs = fsext.NewChangePathFs(fs, func(name string) (string, error) {
// Drop the prefix effectively building something like https://pkg.go.dev/os#DirFS
return filepath.Join(prefix, name), nil
})
if isWindows {
fs = fsext.NewTrimFilePathSeparatorFs(fs)
}
Expand All @@ -705,14 +714,11 @@ func TestOpen(t *testing.T) {

testFunc := func(t *testing.T) {
t.Parallel()
fs, prefix, cleanUp := fsInit()
fs, _, cleanUp := fsInit()
defer cleanUp()
fs = fsext.NewReadOnlyFs(fs)
openPath := tCase.openPath
// if fullpath prepend prefix
if openPath != "" && (openPath[0] == '/' || openPath[0] == '\\') {
openPath = filepath.Join(prefix, openPath)
}
if isWindows {
openPath = strings.ReplaceAll(openPath, `\`, `\\`)
}
Expand All @@ -724,7 +730,7 @@ func TestOpen(t *testing.T) {
export let file = open("` + openPath + `");
export default function() { return file };`

sourceBundle, err := getSimpleBundle(t, filepath.ToSlash(filepath.Join(prefix, pwd, "script.js")), data, fs)
sourceBundle, err := getSimpleBundle(t, filepath.ToSlash(filepath.Join(pwd, "script.js")), data, fs)
if tCase.isError {
require.Error(t, err)
return
Expand All @@ -749,6 +755,7 @@ func TestOpen(t *testing.T) {

t.Run(tCase.name, testFunc)
if isWindows {
tCase := tCase // copy test case before making modifications
// windowsify the testcase
tCase.openPath = strings.ReplaceAll(tCase.openPath, `/`, `\`)
tCase.pwd = strings.ReplaceAll(tCase.pwd, `/`, `\`)
Expand Down
3 changes: 3 additions & 0 deletions internal/js/initcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/url"
"strings"

"github.com/grafana/sobek"
"github.com/sirupsen/logrus"
Expand All @@ -19,6 +20,8 @@ const cantBeUsedOutsideInitContextMsg = `the "%s" function is only available in
// contents of a file. If the second argument is "b" it returns an ArrayBuffer
// instance, otherwise a string representation.
func openImpl(rt *sobek.Runtime, fs fsext.Fs, basePWD *url.URL, filename string, args ...string) (sobek.Value, error) {
// Strip file scheme if available as we should support only this scheme
filename = strings.TrimPrefix(filename, "file://")
data, err := readFile(fs, fsext.Abs(basePWD.Path, filename))
if err != nil {
return nil, err
Expand Down
3 changes: 3 additions & 0 deletions internal/js/modules/k6/experimental/fs/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"io"
"reflect"
"strings"

"go.k6.io/k6/lib/fsext"

Expand Down Expand Up @@ -102,6 +103,8 @@ func (mi *ModuleInstance) Open(path sobek.Value) *sobek.Promise {

func (mi *ModuleInstance) openImpl(path string) (*File, error) {
initEnv := mi.vu.InitEnv()
// Strip file scheme if available as we should support only this scheme
path = strings.TrimPrefix(path, "file://")

// We resolve the path relative to the entrypoint script, as opposed to
// the current working directory (the k6 command is called from).
Expand Down
5 changes: 5 additions & 0 deletions internal/js/modules/k6/experimental/fs/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ func TestOpen(t *testing.T) {
openPath: fsext.FilePathSeparator + testFileName,
wantPath: fsext.FilePathSeparator + testFileName,
},
{
name: "open file absolute path",
openPath: "file://" + fsext.FilePathSeparator + testFileName,
wantPath: fsext.FilePathSeparator + testFileName,
},
{
name: "open relative path",
openPath: filepath.Join(".", fsext.FilePathSeparator, testFileName),
Expand Down
5 changes: 5 additions & 0 deletions internal/js/modules/k6/grpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func (c *Client) Load(importPaths []string, filenames ...string) ([]MethodInfo,
importPaths = append(importPaths, initEnv.CWD.Path)
}

for i, s := range importPaths {
// Clean file scheme as it is the only supported scheme and the following APIs do not support them
importPaths[i] = strings.TrimPrefix(s, "file://")
}

parser := protoparse.Parser{
ImportPaths: importPaths,
InferImportPaths: false,
Expand Down
35 changes: 34 additions & 1 deletion internal/js/modules/k6/grpc/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,6 @@ func TestClientLoadProto(t *testing.T) {
ts := newTestState(t)

tt := testcase{
name: "LoadNestedTypesProto",
initString: codeBlock{
code: `
var client = new grpc.Client();
Expand Down Expand Up @@ -1402,6 +1401,40 @@ func TestClientLoadProto(t *testing.T) {
}
}

func TestClientLoadProtoAbsoluteRootWithFile(t *testing.T) {
t.Parallel()

ts := newTestState(t)
rootPath := ts.VU.InitEnvField.CWD.JoinPath("../..").String()

tt := testcase{
initString: codeBlock{
code: `
var client = new grpc.Client();
client.load(["` + rootPath + `"], "../../lib/testutils/httpmultibin/nested_types/nested_types.proto");`,
},
}

val, err := ts.Run(tt.initString.code)
assertResponse(t, tt.initString, err, val, ts)

expectedTypes := []string{
"grpc.testdata.nested.types.Outer",
"grpc.testdata.nested.types.Outer.MiddleAA",
"grpc.testdata.nested.types.Outer.MiddleAA.Inner",
"grpc.testdata.nested.types.Outer.MiddleBB",
"grpc.testdata.nested.types.Outer.MiddleBB.Inner",
"grpc.testdata.nested.types.MeldOuter",
}

for _, expected := range expectedTypes {
found, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(expected))

assert.NotNil(t, found, "Expected to find the message type %s, but an error occurred", expected)
assert.Nil(t, err, "It was not expected that there would be an error, but it got: %v", err)
}
}

func TestClientConnectionReflectMetadata(t *testing.T) {
t.Parallel()

Expand Down
3 changes: 2 additions & 1 deletion internal/js/modules/k6/grpc/teststate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io"
"net/url"
"os"
"path/filepath"
"runtime"
"sync"
"testing"
Expand Down Expand Up @@ -108,7 +109,7 @@ func newTestState(t *testing.T) testState {
if isWindows {
fs = fsext.NewTrimFilePathSeparatorFs(fs)
}
testRuntime.VU.InitEnvField.CWD = &url.URL{Path: cwd}
testRuntime.VU.InitEnvField.CWD = &url.URL{Scheme: "file", Path: filepath.ToSlash(cwd)}
testRuntime.VU.InitEnvField.FileSystems = map[string]fsext.Fs{"file": fs}

logger := logrus.New()
Expand Down
Loading