X Tutup
Skip to content

Commit ee34970

Browse files
committed
Checkin almost final impl but wrong direction
1 parent ca14d10 commit ee34970

File tree

5 files changed

+90
-49
lines changed

5 files changed

+90
-49
lines changed

pkg/cmd/codespace/ports.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,28 @@ func newPortsVisibilityCmd(app *App) *cobra.Command {
231231
}
232232
}
233233

234+
type ErrUpdatingPortVisibility struct {
235+
port int
236+
visibility string
237+
err error
238+
}
239+
240+
func newErrUpdatingPortVisibility(port int, visibility string, err error) *ErrUpdatingPortVisibility {
241+
return &ErrUpdatingPortVisibility{
242+
port: port,
243+
visibility: visibility,
244+
err: err,
245+
}
246+
}
247+
248+
func (e *ErrUpdatingPortVisibility) Error() string {
249+
return fmt.Sprintf("error waiting for port %d to update to %s: %s", e.port, e.visibility, e.err)
250+
}
251+
252+
func (e *ErrUpdatingPortVisibility) Unwrap() error {
253+
return e.err
254+
}
255+
234256
func (a *App) UpdatePortVisibility(ctx context.Context, codespaceName string, args []string) (err error) {
235257
ports, err := a.parsePortVisibilities(args)
236258
if err != nil {
@@ -251,6 +273,9 @@ func (a *App) UpdatePortVisibility(ctx context.Context, codespaceName string, ar
251273
}
252274
defer safeClose(session, &err)
253275

276+
success := session.RegisterEvent("sharingSucceeded")
277+
failure := session.RegisterEvent("sharingFailed")
278+
254279
// TODO: check if port visibility can be updated in parallel instead of sequentially
255280
for _, port := range ports {
256281
a.StartProgressIndicatorWithLabel(fmt.Sprintf("Updating port %d visibility to: %s", port.number, port.visibility))
@@ -264,8 +289,8 @@ func (a *App) UpdatePortVisibility(ctx context.Context, codespaceName string, ar
264289
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
265290
defer cancel()
266291

267-
if err := a.waitForPortUpdate(ctx, session, port.number); err != nil {
268-
return fmt.Errorf("error waiting for port %d to update to %s: %w", port.number, port.visibility, err)
292+
if err := a.waitForPortUpdate(ctx, success, failure, session, port.number); err != nil {
293+
return newErrUpdatingPortVisibility(port.number, port.visibility, err)
269294
}
270295

271296
a.StopProgressIndicator()
@@ -287,10 +312,9 @@ type portData struct {
287312
StatusCode int `json:"statusCode"`
288313
}
289314

290-
func (a *App) waitForPortUpdate(ctx context.Context, session *liveshare.Session, port int) error {
291-
success := session.WaitForEvent("sharingSucceeded")
292-
failure := session.WaitForEvent("sharingFailed")
315+
var errUpdatePortVisibilityForbidden = errors.New("organization admin has forbidden this privacy setting")
293316

317+
func (a *App) waitForPortUpdate(ctx context.Context, success, failure chan []byte, session *liveshare.Session, port int) error {
294318
for {
295319
var pd portData
296320
select {
@@ -309,7 +333,7 @@ func (a *App) waitForPortUpdate(ctx context.Context, session *liveshare.Session,
309333
}
310334
if pd.Port == port && pd.ChangeKind == portChangeKindUpdate {
311335
if pd.StatusCode == http.StatusForbidden {
312-
return errors.New("organization admin has forbidden this privacy setting")
336+
return errUpdatePortVisibilityForbidden
313337
}
314338
return errors.New(pd.ErrorDetail)
315339
}

pkg/cmd/codespace/ports_test.go

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package codespace
33
import (
44
"context"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"testing"
89

@@ -40,7 +41,7 @@ func TestPortsUpdateVisibilitySuccess(t *testing.T) {
4041
},
4142
}
4243

43-
err := RunUpdateVisibilityTest(t, portVisibilities, eventResponses, portsData)
44+
err := runUpdateVisibilityTest(portVisibilities, eventResponses, portsData)
4445

4546
if err != nil {
4647
t.Errorf("unexpected error: %v", err)
@@ -77,14 +78,13 @@ func TestPortsUpdateVisibilityFailure403(t *testing.T) {
7778
},
7879
}
7980

80-
err := RunUpdateVisibilityTest(t, portVisibilities, eventResponses, portsData)
81+
err := runUpdateVisibilityTest(portVisibilities, eventResponses, portsData)
8182
if err == nil {
8283
t.Errorf("unexpected error: %v", err)
8384
}
8485

85-
expectedErr := "error waiting for port 9999 to update to public: organization admin has forbidden this privacy setting"
86-
if err.Error() != expectedErr {
87-
t.Errorf("expected: %v, got: %v", expectedErr, err)
86+
if errors.Unwrap(err) != errUpdatePortVisibilityForbidden {
87+
t.Errorf("expected: %v, got: %v", errUpdatePortVisibilityForbidden, errors.Unwrap(err))
8888
}
8989
}
9090

@@ -117,13 +117,13 @@ func TestPortsUpdateVisibilityFailure(t *testing.T) {
117117
},
118118
}
119119

120-
err := RunUpdateVisibilityTest(t, portVisibilities, eventResponses, portsData)
120+
err := runUpdateVisibilityTest(portVisibilities, eventResponses, portsData)
121121
if err == nil {
122122
t.Errorf("unexpected error: %v", err)
123123
}
124124

125-
expectedErr := "error waiting for port 9999 to update to public: test error"
126-
if err.Error() != expectedErr {
125+
var expectedErr *ErrUpdatingPortVisibility
126+
if !errors.As(err, &expectedErr) {
127127
t.Errorf("expected: %v, got: %v", expectedErr, err)
128128
}
129129
}
@@ -132,7 +132,7 @@ type joinWorkspaceResult struct {
132132
SessionNumber int `json:"sessionNumber"`
133133
}
134134

135-
func RunUpdateVisibilityTest(t *testing.T, portVisibilities []portVisibility, eventResponses []string, portsData []portData) error {
135+
func runUpdateVisibilityTest(portVisibilities []portVisibility, eventResponses []string, portsData []portData) error {
136136
joinWorkspace := func(req *jsonrpc2.Request) (interface{}, error) {
137137
return joinWorkspaceResult{1}, nil
138138
}
@@ -158,29 +158,33 @@ func RunUpdateVisibilityTest(t *testing.T, portVisibilities []portVisibility, ev
158158
livesharetest.WithService("serverSharing.updateSharedServerPrivacy", updateSharedVisibility),
159159
)
160160
if err != nil {
161-
t.Fatal(err)
161+
return fmt.Errorf("unable to create test server: %w", err)
162162
}
163163

164164
type rpcMessage struct {
165165
Method string
166166
Params portData
167167
}
168168

169-
for index, pd := range portsData {
170-
go func(index int, pd portData) {
171-
for {
172-
select {
173-
case <-ctx.Done():
174-
return
175-
case <-ch:
176-
testServer.WriteToObjectStream(rpcMessage{
177-
Method: eventResponses[index],
178-
Params: pd,
179-
})
169+
go func() {
170+
var i int
171+
for ; ; i++ {
172+
select {
173+
case <-ctx.Done():
174+
return
175+
case <-ch:
176+
pd := portsData[i]
177+
// TODO: handle error
178+
err := testServer.WriteToObjectStream(rpcMessage{
179+
Method: eventResponses[i],
180+
Params: pd,
181+
})
182+
if err != nil {
183+
panic(err)
180184
}
181185
}
182-
}(index, pd)
183-
}
186+
}
187+
}()
184188

185189
mockApi := &apiClientMock{
186190
GetCodespaceFunc: func(ctx context.Context, codespaceName string, includeConnection bool) (*api.Codespace, error) {

pkg/liveshare/rpc.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,17 @@ import (
1313

1414
type rpcClient struct {
1515
*jsonrpc2.Conn
16-
conn io.ReadWriteCloser
17-
18-
eventHandlersMu sync.RWMutex
19-
eventHandlers map[string]chan []byte
16+
conn io.ReadWriteCloser
17+
requestHandler *requestHandler
2018
}
2119

2220
func newRPCClient(conn io.ReadWriteCloser) *rpcClient {
23-
return &rpcClient{conn: conn, eventHandlers: make(map[string]chan []byte)}
21+
return &rpcClient{conn: conn, requestHandler: newRequestHandler()}
2422
}
2523

2624
func (r *rpcClient) connect(ctx context.Context) {
2725
stream := jsonrpc2.NewBufferedStream(r.conn, jsonrpc2.VSCodeObjectCodec{})
28-
r.Conn = jsonrpc2.NewConn(ctx, stream, newRequestHandler(r))
26+
r.Conn = jsonrpc2.NewConn(ctx, stream, r.requestHandler)
2927
}
3028

3129
func (r *rpcClient) do(ctx context.Context, method string, args, result interface{}) error {
@@ -44,7 +42,16 @@ func (r *rpcClient) do(ctx context.Context, method string, args, result interfac
4442
return waiter.Wait(waitCtx, result)
4543
}
4644

47-
func (r *rpcClient) registerEventHandler(eventName string) chan []byte {
45+
type requestHandler struct {
46+
eventHandlersMu sync.RWMutex
47+
eventHandlers map[string]chan []byte
48+
}
49+
50+
func newRequestHandler() *requestHandler {
51+
return &requestHandler{eventHandlers: make(map[string]chan []byte)}
52+
}
53+
54+
func (r *requestHandler) registerEvent(eventName string) chan []byte {
4855
r.eventHandlersMu.Lock()
4956
defer r.eventHandlersMu.Unlock()
5057

@@ -57,23 +64,19 @@ func (r *rpcClient) registerEventHandler(eventName string) chan []byte {
5764
return ch
5865
}
5966

60-
func (r *rpcClient) eventHandler(eventName string) chan []byte {
67+
func (r *requestHandler) eventHandler(eventName string) chan []byte {
6168
r.eventHandlersMu.RLock()
6269
defer r.eventHandlersMu.RUnlock()
6370

6471
return r.eventHandlers[eventName]
6572
}
6673

67-
type requestHandler struct {
68-
rpcClient *rpcClient
69-
}
70-
71-
func newRequestHandler(rpcClient *rpcClient) *requestHandler {
72-
return &requestHandler{rpcClient: rpcClient}
73-
}
74-
75-
func (e *requestHandler) Handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
76-
handler := e.rpcClient.eventHandler(req.Method)
74+
func (r *requestHandler) Handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
75+
fmt.Println(req.Method)
76+
if req.Params != nil {
77+
fmt.Println(string(*req.Params))
78+
}
79+
handler := r.eventHandler(req.Method)
7780
if handler == nil {
7881
return // noop
7982
}

pkg/liveshare/session.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ func (s *Session) UpdateSharedServerPrivacy(ctx context.Context, port int, visib
7878
return nil
7979
}
8080

81-
func (s *Session) WaitForEvent(eventName string) chan []byte {
82-
return s.rpc.registerEventHandler(eventName)
81+
func (s *Session) RegisterEvent(eventName string) chan []byte {
82+
return s.rpc.requestHandler.registerEvent(eventName)
8383
}
8484

8585
// StartsSSHServer starts an SSH server in the container, installing sshd if necessary,

pkg/liveshare/ssh.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func (s *sshSession) connect(ctx context.Context) error {
5050
return fmt.Errorf("error creating ssh client connection: %w", err)
5151
}
5252
s.conn = sshClientConn
53+
go s.handleGlobalRequests(reqs)
5354

5455
sshClient := ssh.NewClient(sshClientConn, chans, reqs)
5556
s.Session, err = sshClient.NewSession()
@@ -70,6 +71,15 @@ func (s *sshSession) connect(ctx context.Context) error {
7071
return nil
7172
}
7273

74+
func (s *sshSession) handleGlobalRequests(incoming <-chan *ssh.Request) {
75+
for r := range incoming {
76+
fmt.Println(r.Type)
77+
// This handles keepalive messages and matches
78+
// the behaviour of OpenSSH.
79+
r.Reply(false, nil)
80+
}
81+
}
82+
7383
func (s *sshSession) Read(p []byte) (n int, err error) {
7484
return s.reader.Read(p)
7585
}

0 commit comments

Comments
 (0)
X Tutup