- Notifications
You must be signed in to change notification settings - Fork1k
feat: add coder_workspace_port_forward MCP tool#19863
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -3,6 +3,7 @@ package toolsdk_test | ||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"runtime" | ||
@@ -35,10 +36,10 @@ import ( | ||
// setupWorkspaceForAgent creates a workspace setup exactly like main SSH tests | ||
// nolint:gocritic // This is in a test package and does not end up in the build | ||
func setupWorkspaceForAgent(t *testing.T, opts *coderdtest.Options) (*codersdk.Client, database.WorkspaceTable, string) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This is a super minor nit: We could have left this function and its signature unchanged, added a new That way, all other code remains untouched, resulting in an even smaller diff. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I had the same thought but, I felt like I was trading diff size for dev experience. Because this is basically is a convenience wrapper around I do wish I could merge this in a separate commit though, without having to open a second PR. | ||
t.Helper() | ||
client, store := coderdtest.NewWithDatabase(t,opts) | ||
client.SetLogger(testutil.Logger(t).Named("client")) | ||
first := coderdtest.CreateFirstUser(t, client) | ||
userClient, user := coderdtest.CreateAnotherUserMutators(t, client, first.OrganizationID, nil, func(r *codersdk.CreateUserRequestWithOrgs) { | ||
@@ -405,7 +406,7 @@ func TestTools(t *testing.T) { | ||
t.Skip("WorkspaceSSHExec is not supported on Windows") | ||
} | ||
// Setup workspace exactly like main SSH tests | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, nil) | ||
// Start agent and wait for it to be ready (following main SSH test pattern) | ||
_ = agenttest.New(t, client.URL, agentToken) | ||
@@ -457,7 +458,7 @@ func TestTools(t *testing.T) { | ||
t.Run("WorkspaceLS", func(t *testing.T) { | ||
t.Parallel() | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, nil) | ||
fs := afero.NewMemMapFs() | ||
_ = agenttest.New(t, client.URL, agentToken, func(opts *agent.Options) { | ||
opts.Filesystem = fs | ||
@@ -503,7 +504,7 @@ func TestTools(t *testing.T) { | ||
t.Run("WorkspaceReadFile", func(t *testing.T) { | ||
t.Parallel() | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, nil) | ||
fs := afero.NewMemMapFs() | ||
_ = agenttest.New(t, client.URL, agentToken, func(opts *agent.Options) { | ||
opts.Filesystem = fs | ||
@@ -606,7 +607,7 @@ func TestTools(t *testing.T) { | ||
t.Run("WorkspaceWriteFile", func(t *testing.T) { | ||
t.Parallel() | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, nil) | ||
fs := afero.NewMemMapFs() | ||
_ = agenttest.New(t, client.URL, agentToken, func(opts *agent.Options) { | ||
opts.Filesystem = fs | ||
@@ -633,7 +634,7 @@ func TestTools(t *testing.T) { | ||
t.Run("WorkspaceEditFile", func(t *testing.T) { | ||
t.Parallel() | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, nil) | ||
fs := afero.NewMemMapFs() | ||
_ = agenttest.New(t, client.URL, agentToken, func(opts *agent.Options) { | ||
opts.Filesystem = fs | ||
@@ -673,7 +674,7 @@ func TestTools(t *testing.T) { | ||
t.Run("WorkspaceEditFiles", func(t *testing.T) { | ||
t.Parallel() | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, nil) | ||
fs := afero.NewMemMapFs() | ||
_ = agenttest.New(t, client.URL, agentToken, func(opts *agent.Options) { | ||
opts.Filesystem = fs | ||
@@ -730,6 +731,66 @@ func TestTools(t *testing.T) { | ||
require.NoError(t, err) | ||
require.Equal(t, "bar2 bar2", string(b)) | ||
}) | ||
t.Run("WorkspacePortForward", func(t *testing.T) { | ||
t.Parallel() | ||
tests := []struct { | ||
name string | ||
workspace string | ||
host string | ||
port int | ||
expect string | ||
error string | ||
}{ | ||
{ | ||
name: "OK", | ||
workspace: "myuser/myworkspace", | ||
port: 1234, | ||
host: "*.test.coder.com", | ||
expect: "%s://1234--dev--myworkspace--myuser.test.coder.com:%s", | ||
}, | ||
{ | ||
name: "NonExistentWorkspace", | ||
workspace: "doesnotexist", | ||
port: 1234, | ||
host: "*.test.coder.com", | ||
error: "failed to find workspace", | ||
}, | ||
{ | ||
name: "NoAppHost", | ||
host: "", | ||
workspace: "myuser/myworkspace", | ||
port: 1234, | ||
error: "no app host", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
t.Parallel() | ||
client, workspace, agentToken := setupWorkspaceForAgent(t, &coderdtest.Options{ | ||
AppHostname: tt.host, | ||
}) | ||
_ = agenttest.New(t, client.URL, agentToken) | ||
coderdtest.NewWorkspaceAgentWaiter(t, client, workspace.ID).Wait() | ||
tb, err := toolsdk.NewDeps(client) | ||
require.NoError(t, err) | ||
res, err := testTool(t, toolsdk.WorkspacePortForward, tb, toolsdk.WorkspacePortForwardArgs{ | ||
Workspace: tt.workspace, | ||
Port: tt.port, | ||
}) | ||
if tt.error != "" { | ||
require.Error(t, err) | ||
require.ErrorContains(t, err, tt.error) | ||
} else { | ||
require.NoError(t, err) | ||
require.Equal(t, fmt.Sprintf(tt.expect, client.URL.Scheme, client.URL.Port()), res.URL) | ||
} | ||
}) | ||
} | ||
}) | ||
} | ||
// TestedTools keeps track of which tools have been tested. | ||
Uh oh!
There was an error while loading.Please reload this page.