Path: blob/main/components/local-app/pkg/helper/workspace_test.go
2500 views
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package helper56import (7"context"8"fmt"9"net/http"10"net/http/httptest"11"testing"1213"github.com/bufbuild/connect-go"14"github.com/gitpod-io/gitpod/components/public-api/go/client"15v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1"16gitpod_experimental_v1connect "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1/v1connect"17"github.com/gitpod-io/local-app/pkg/prettyprint"18"github.com/google/go-cmp/cmp"19)2021func TestObserveWorkspaceUntilStarted(t *testing.T) {22workspaceWithStatus := func(id string, phase v1.WorkspaceInstanceStatus_Phase) *v1.Workspace {23return &v1.Workspace{24WorkspaceId: id,25Status: &v1.WorkspaceStatus{26Instance: &v1.WorkspaceInstance{27WorkspaceId: id,28Status: &v1.WorkspaceInstanceStatus{29Phase: phase,30},31},32},33}34}3536type Expectation struct {37Error string38SystemException bool39}40tests := []struct {41Name string42Expectation Expectation43PrepServer func(mux *http.ServeMux)44WorkspaceID string45}{46{47Name: "stream retry",48PrepServer: func(mux *http.ServeMux) {49mux.Handle(gitpod_experimental_v1connect.NewWorkspacesServiceHandler(&TestWorkspaceService{50Workspaces: []*v1.Workspace{51workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_PENDING),52workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_CREATING),53nil,54workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_RUNNING),55},56}))57},58},59{60Name: "stream ends early",61PrepServer: func(mux *http.ServeMux) {62mux.Handle(gitpod_experimental_v1connect.NewWorkspacesServiceHandler(&TestWorkspaceService{63Workspaces: []*v1.Workspace{64workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_CREATING),65},66}))67},68Expectation: Expectation{69Error: "workspace stream ended unexpectedly",70SystemException: true,71},72},73{74Name: "workspace starts",75PrepServer: func(mux *http.ServeMux) {76mux.Handle(gitpod_experimental_v1connect.NewWorkspacesServiceHandler(&TestWorkspaceService{77Workspaces: []*v1.Workspace{78workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_PENDING),79workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_CREATING),80workspaceWithStatus("workspaceID", v1.WorkspaceInstanceStatus_PHASE_RUNNING),81},82}))83},84},85}8687for _, test := range tests {88t.Run(test.Name, func(t *testing.T) {89var act Expectation9091mux := http.NewServeMux()92if test.PrepServer != nil {93test.PrepServer(mux)94}9596apisrv := httptest.NewServer(mux)97t.Cleanup(apisrv.Close)9899clnt, err := client.New(client.WithURL(apisrv.URL), client.WithCredentials("hello world"))100if err != nil {101t.Fatal(err)102}103104_, err = ObserveWorkspaceUntilStarted(context.Background(), clnt, test.WorkspaceID)105if err != nil {106act.Error = err.Error()107_, act.SystemException = err.(*prettyprint.ErrSystemException)108}109110if diff := cmp.Diff(test.Expectation, act); diff != "" {111t.Errorf("ObserveWorkspaceUntilStarted() mismatch (-want +got):\n%s", diff)112}113})114}115}116117type TestWorkspaceService struct {118gitpod_experimental_v1connect.WorkspacesServiceHandler119120Workspaces []*v1.Workspace121Pos int122}123124func (srv *TestWorkspaceService) GetWorkspace(context.Context, *connect.Request[v1.GetWorkspaceRequest]) (*connect.Response[v1.GetWorkspaceResponse], error) {125if srv.Pos >= len(srv.Workspaces) {126return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("not found"))127}128129resp := &connect.Response[v1.GetWorkspaceResponse]{130Msg: &v1.GetWorkspaceResponse{131Result: srv.Workspaces[srv.Pos],132},133}134srv.Pos++135return resp, nil136}137138func (srv *TestWorkspaceService) StreamWorkspaceStatus(ctx context.Context, req *connect.Request[v1.StreamWorkspaceStatusRequest], resp *connect.ServerStream[v1.StreamWorkspaceStatusResponse]) error {139if srv.Pos >= len(srv.Workspaces) {140return nil141}142if srv.Workspaces[srv.Pos] == nil {143srv.Pos++144return nil145}146147for ; srv.Pos < len(srv.Workspaces); srv.Pos++ {148ws := srv.Workspaces[srv.Pos]149if ws == nil {150return nil151}152err := resp.Send(&v1.StreamWorkspaceStatusResponse{153Result: ws.Status,154})155if err != nil {156return err157}158}159return nil160}161162163