@@ -22,6 +22,7 @@ import (
22
22
"github.com/stretchr/testify/assert"
23
23
"github.com/stretchr/testify/require"
24
24
"golang.org/x/xerrors"
25
+ "nhooyr.io/websocket"
25
26
26
27
"github.com/coder/coder/coderd/coderdtest"
27
28
"github.com/coder/coder/coderd/rbac"
@@ -46,43 +47,9 @@ func Run(t *testing.T, factory DeploymentFactory) {
46
47
t .Skip ("ConPTY appears to be inconsistent on Windows." )
47
48
}
48
49
49
- appDetails := setupProxyTest (t , nil )
50
-
51
- ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
52
- defer cancel ()
53
-
54
- // Run the test against the path app hostname since that's where the
55
- // reconnecting-pty proxy server we want to test is mounted.
56
- client := appDetails .AppClient (t )
57
- conn , err := client .WorkspaceAgentReconnectingPTY (ctx , appDetails .Agent .ID , uuid .New (), 80 , 80 , "/bin/bash" )
58
- require .NoError (t , err )
59
- defer conn .Close ()
60
-
61
- // First attempt to resize the TTY.
62
- // The websocket will close if it fails!
63
- data , err := json .Marshal (codersdk.ReconnectingPTYRequest {
64
- Height : 250 ,
65
- Width : 250 ,
66
- })
67
- require .NoError (t , err )
68
- _ , err = conn .Write (data )
69
- require .NoError (t , err )
70
- bufRead := bufio .NewReader (conn )
71
-
72
- // Brief pause to reduce the likelihood that we send keystrokes while
73
- // the shell is simultaneously sending a prompt.
74
- time .Sleep (100 * time .Millisecond )
75
-
76
- data , err = json .Marshal (codersdk.ReconnectingPTYRequest {
77
- Data : "echo test\r \n " ,
78
- })
79
- require .NoError (t , err )
80
- _ , err = conn .Write (data )
81
- require .NoError (t , err )
82
-
83
- expectLine := func (matcher func (string ) bool ) {
50
+ expectLine := func (r * bufio.Reader , matcher func (string ) bool ) {
84
51
for {
85
- line , err := bufRead .ReadString ('\n' )
52
+ line , err := r .ReadString ('\n' )
86
53
require .NoError (t , err )
87
54
if matcher (line ) {
88
55
break
@@ -96,8 +63,88 @@ func Run(t *testing.T, factory DeploymentFactory) {
96
63
return strings .Contains (line , "test" ) && ! strings .Contains (line , "echo" )
97
64
}
98
65
99
- expectLine (matchEchoCommand )
100
- expectLine (matchEchoOutput )
66
+ t .Run ("OK" , func (t * testing.T ) {
67
+ appDetails := setupProxyTest (t , nil )
68
+
69
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
70
+ defer cancel ()
71
+
72
+ // Run the test against the path app hostname since that's where the
73
+ // reconnecting-pty proxy server we want to test is mounted.
74
+ client := appDetails .AppClient (t )
75
+ conn , err := client .WorkspaceAgentReconnectingPTY (ctx , appDetails .Agent .ID , uuid .New (), 80 , 80 , "/bin/bash" )
76
+ require .NoError (t , err )
77
+ defer conn .Close ()
78
+
79
+ // First attempt to resize the TTY.
80
+ // The websocket will close if it fails!
81
+ data , err := json .Marshal (codersdk.ReconnectingPTYRequest {
82
+ Height : 250 ,
83
+ Width : 250 ,
84
+ })
85
+ require .NoError (t , err )
86
+ _ , err = conn .Write (data )
87
+ require .NoError (t , err )
88
+ bufRead := bufio .NewReader (conn )
89
+
90
+ // Brief pause to reduce the likelihood that we send keystrokes while
91
+ // the shell is simultaneously sending a prompt.
92
+ time .Sleep (100 * time .Millisecond )
93
+
94
+ data , err = json .Marshal (codersdk.ReconnectingPTYRequest {
95
+ Data : "echo test\r \n " ,
96
+ })
97
+ require .NoError (t , err )
98
+ _ , err = conn .Write (data )
99
+ require .NoError (t , err )
100
+
101
+ expectLine (bufRead , matchEchoCommand )
102
+ expectLine (bufRead , matchEchoOutput )
103
+ })
104
+
105
+ t .Run ("SignedTokenQueryParameter" , func (t * testing.T ) {
106
+ t .Parallel ()
107
+
108
+ appDetails := setupProxyTest (t , nil )
109
+ if appDetails .AppHostIsPrimary {
110
+ t .Skip ("Tickets are not used for terminal requests on the primary." )
111
+ }
112
+
113
+ u := * appDetails .PathAppBaseURL
114
+ u .Path = fmt .Sprintf ("/api/v2/workspaceagents/%s/pty" , appDetails .Agent .ID .String ())
115
+
116
+ ctx := testutil .Context (t , testutil .WaitLong )
117
+ issueRes , err := appDetails .SDKClient .IssueReconnectingPTYSignedToken (ctx , codersdk.IssueReconnectingPTYSignedTokenRequest {
118
+ URL : u .String (),
119
+ AgentID : appDetails .Agent .ID ,
120
+ })
121
+ require .NoError (t , err )
122
+
123
+ // Try to connect to the endpoint with the signed token and no other
124
+ // authentication.
125
+ q := u .Query ()
126
+ q .Set ("reconnect" , uuid .NewString ())
127
+ q .Set ("height" , strconv .Itoa (24 ))
128
+ q .Set ("width" , strconv .Itoa (80 ))
129
+ q .Set ("command" , `/bin/sh -c "echo test"` )
130
+ q .Set (codersdk .SignedAppTokenQueryParameter , issueRes .SignedToken )
131
+ u .RawQuery = q .Encode ()
132
+
133
+ //nolint:bodyclose
134
+ wsConn , res , err := websocket .Dial (ctx , u .String (), nil )
135
+ if ! assert .NoError (t , err ) {
136
+ dump , err := httputil .DumpResponse (res , true )
137
+ if err == nil {
138
+ t .Log (string (dump ))
139
+ }
140
+ return
141
+ }
142
+ defer wsConn .Close (websocket .StatusNormalClosure , "" )
143
+ conn := websocket .NetConn (ctx , wsConn , websocket .MessageBinary )
144
+ bufRead := bufio .NewReader (conn )
145
+
146
+ expectLine (bufRead , matchEchoOutput )
147
+ })
101
148
})
102
149
103
150
t .Run ("WorkspaceAppsProxyPath" , func (t * testing.T ) {
0 commit comments