From 5505bb060bd614267a553bc3b43a49e8f6acbd54 Mon Sep 17 00:00:00 2001 From: Pavel Tumik <18602811+sagor999@users.noreply.github.com> Date: Fri, 20 May 2022 21:18:09 +0000 Subject: [PATCH] [ws-manager] add tests for createPVCForWorkspacePod --- components/ws-manager/pkg/manager/create.go | 2 +- .../ws-manager/pkg/manager/create_test.go | 121 ++++++++++++++++++ .../testdata/cpwp_custom_storage.golden | 21 +++ .../manager/testdata/cpwp_custom_storage.json | 40 ++++++ .../testdata/cpwp_default_storage.golden | 21 +++ .../testdata/cpwp_default_storage.json | 40 ++++++ .../pkg/manager/testdata/cpwp_no_class.golden | 21 +++ .../pkg/manager/testdata/cpwp_no_class.json | 28 ++++ .../pkg/manager/testdata/cpwp_no_pvc.golden | 21 +++ .../pkg/manager/testdata/cpwp_no_pvc.json | 35 +++++ 10 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.golden create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.json create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_default_storage.golden create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_default_storage.json create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_no_class.golden create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_no_class.json create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.golden create mode 100644 components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.json diff --git a/components/ws-manager/pkg/manager/create.go b/components/ws-manager/pkg/manager/create.go index 4a3dba1ea90dd5..3422a5ff677579 100644 --- a/components/ws-manager/pkg/manager/create.go +++ b/components/ws-manager/pkg/manager/create.go @@ -233,7 +233,7 @@ func (m *Manager) createPVCForWorkspacePod(startContext *startWorkspaceContext) prefix = "ws" } - PVCConfig := m.Config.WorkspaceClasses[""].PVC + PVCConfig := m.Config.WorkspaceClasses[config.DefaultWorkspaceClass].PVC if startContext.Class != nil { PVCConfig = startContext.Class.PVC } diff --git a/components/ws-manager/pkg/manager/create_test.go b/components/ws-manager/pkg/manager/create_test.go index 2d0e4a0ce7c6f4..586cd57ad127c7 100644 --- a/components/ws-manager/pkg/manager/create_test.go +++ b/components/ws-manager/pkg/manager/create_test.go @@ -177,3 +177,124 @@ func TestCreateDefiniteWorkspacePod(t *testing.T) { } test.Run() } + +func TestCreatePVCForWorkspacePod(t *testing.T) { + type WorkspaceClass struct { + PVCConfig *config.PVCConfiguration `json:"pvcConfig,omitempty"` + ResourceRequests *config.ResourceConfiguration `json:"resourceRequests,omitempty"` + ResourceLimits *config.ResourceConfiguration `json:"resourceLimits,omitempty"` + } + type fixture struct { + WorkspaceClass + + Spec *json.RawMessage `json:"spec,omitempty"` // *api.StartWorkspaceSpec + Request *json.RawMessage `json:"request,omitempty"` // *api.StartWorkspaceRequest + Context *startWorkspaceContext `json:"context,omitempty"` + CACertSecret string `json:"caCertSecret,omitempty"` + Classes map[string]WorkspaceClass `json:"classes,omitempty"` + + EnforceAffinity bool `json:"enforceAffinity,omitempty"` + } + type gold struct { + PVC corev1.PersistentVolumeClaim `json:"reason,omitempty"` + Error string `json:"error,omitempty"` + } + + test := ctesting.FixtureTest{ + T: t, + Path: "testdata/cpwp_*.json", + Test: func(t *testing.T, input interface{}) interface{} { + fixture := input.(*fixture) + + mgmtCfg := forTestingOnlyManagerConfig() + mgmtCfg.WorkspaceCACertSecret = fixture.CACertSecret + + if fixture.Classes == nil { + fixture.Classes = make(map[string]WorkspaceClass) + } + + if _, exists := fixture.Classes[config.DefaultWorkspaceClass]; !exists { + if fixture.WorkspaceClass.ResourceLimits != nil || fixture.WorkspaceClass.ResourceRequests != nil { + // there's no default class in the fixture. If there are limits configured, use those + fixture.Classes[config.DefaultWorkspaceClass] = fixture.WorkspaceClass + } + } + + for n, cls := range fixture.Classes { + var cfgCls config.WorkspaceClass + cfgCls.Container.Requests = cls.ResourceRequests + cfgCls.Container.Limits = cls.ResourceLimits + if cls.PVCConfig != nil { + cfgCls.PVC = *cls.PVCConfig + } + + mgmtCfg.WorkspaceClasses[n] = &cfgCls + } + + manager := &Manager{Config: mgmtCfg} + + if fixture.Context == nil { + var req api.StartWorkspaceRequest + if fixture.Request == nil { + if fixture.Spec == nil { + t.Errorf("fixture has neither context, nor request, nor spec") + return nil + } + + var spec api.StartWorkspaceSpec + err := protojson.Unmarshal([]byte(*fixture.Spec), &spec) + if err != nil { + t.Errorf("cannot unmarshal StartWorkspaceSpec: %v", err) + return nil + } + + req = api.StartWorkspaceRequest{ + Type: api.WorkspaceType_REGULAR, + Id: "test", + Metadata: &api.WorkspaceMetadata{ + Owner: "tester", + MetaId: "foobar", + }, + ServicePrefix: "foobarservice", + Spec: &spec, + } + } else { + err := protojson.Unmarshal([]byte(*fixture.Request), &req) + if err != nil { + t.Errorf("cannot unmarshal StartWorkspaceReq: %v", err) + return nil + } + } + + if req.Spec.Class == "" { + fmt.Println() + } + + ctx, err := manager.newStartWorkspaceContext(context.Background(), &req) + if err != nil { + t.Errorf("cannot create startWorkspaceContext: %v", err) + return nil + } + + // tie down values that would otherwise change for each test + ctx.CLIAPIKey = "Ab=5=rRA*9:C'T{;RRB\u003e]vK2p6`fFfrS" + ctx.OwnerToken = "%7J'[Of/8NDiWE+9F,I6^Jcj_1\u0026}-F8p" + + fixture.Context = ctx + } + + pvc, serr := manager.createPVCForWorkspacePod(fixture.Context) + result := gold{} + if serr != nil { + result.Error = serr.Error() + return &result + } + result.PVC = *pvc + + return &result + }, + Fixture: func() interface{} { return &fixture{} }, + Gold: func() interface{} { return &gold{} }, + } + test.Run() +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.golden b/components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.golden new file mode 100644 index 00000000000000..82c679353f99b5 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.golden @@ -0,0 +1,21 @@ +{ + "reason": { + "metadata": { + "name": "ws-test", + "namespace": "default", + "creationTimestamp": null + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "30Gi" + } + }, + "storageClassName": "test-storage" + }, + "status": {} + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.json b/components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.json new file mode 100644 index 00000000000000..3e5c5cd1c84294 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_custom_storage.json @@ -0,0 +1,40 @@ +{ + "classes": { + "gitpodio-pvc": { + "resourceRequests": {"cpu": "900m"}, + "resourceLimits": {"cpu": "900m"}, + "pvcConfig": { + "size": "30Gi", + "storageClass": "test-storage", + "snapshotClass": "test-snapshot" + } + } + }, + "spec": { + "ideImage": { + "webRef": "eu.gcr.io/gitpod-core-dev/buid/theia-ide:someversion" + }, + "workspaceImage": "eu.gcr.io/gitpod-dev/workspace-images/ac1c0755007966e4d6e090ea821729ac747d22ac/eu.gcr.io/gitpod-dev/workspace-base-images/github.com/typefox/gitpod:80a7d427a1fcd346d420603d80a31d57cf75a7af", + "initializer": { + "snapshot": { + "snapshot": "workspaces/cryptic-id-goes-herg/fd62804b-4cab-11e9-843a-4e645373048e.tar@gitpod-dev-user-christesting" + } + }, + "ports": [ + { + "port": 8080 + } + ], + "envvars": [ + { + "name": "foo", + "value": "bar" + } + ], + "git": { + "username": "usernameGoesHere", + "email": "some@user.com" + }, + "class": "gitpodio-pvc" + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_default_storage.golden b/components/ws-manager/pkg/manager/testdata/cpwp_default_storage.golden new file mode 100644 index 00000000000000..43b727cca0efe4 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_default_storage.golden @@ -0,0 +1,21 @@ +{ + "reason": { + "metadata": { + "name": "ws-test", + "namespace": "default", + "creationTimestamp": null + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "30Gi" + } + }, + "storageClassName": "" + }, + "status": {} + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_default_storage.json b/components/ws-manager/pkg/manager/testdata/cpwp_default_storage.json new file mode 100644 index 00000000000000..d3d0dc95616b13 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_default_storage.json @@ -0,0 +1,40 @@ +{ + "classes": { + "gitpodio-pvc": { + "resourceRequests": {"cpu": "900m"}, + "resourceLimits": {"cpu": "900m"}, + "pvcConfig": { + "size": "30Gi", + "storageClass": "", + "snapshotClass": "" + } + } + }, + "spec": { + "ideImage": { + "webRef": "eu.gcr.io/gitpod-core-dev/buid/theia-ide:someversion" + }, + "workspaceImage": "eu.gcr.io/gitpod-dev/workspace-images/ac1c0755007966e4d6e090ea821729ac747d22ac/eu.gcr.io/gitpod-dev/workspace-base-images/github.com/typefox/gitpod:80a7d427a1fcd346d420603d80a31d57cf75a7af", + "initializer": { + "snapshot": { + "snapshot": "workspaces/cryptic-id-goes-herg/fd62804b-4cab-11e9-843a-4e645373048e.tar@gitpod-dev-user-christesting" + } + }, + "ports": [ + { + "port": 8080 + } + ], + "envvars": [ + { + "name": "foo", + "value": "bar" + } + ], + "git": { + "username": "usernameGoesHere", + "email": "some@user.com" + }, + "class": "gitpodio-pvc" + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_no_class.golden b/components/ws-manager/pkg/manager/testdata/cpwp_no_class.golden new file mode 100644 index 00000000000000..a510ca07c4fa2a --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_no_class.golden @@ -0,0 +1,21 @@ +{ + "reason": { + "metadata": { + "name": "ws-test", + "namespace": "default", + "creationTimestamp": null + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "0" + } + }, + "storageClassName": "" + }, + "status": {} + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_no_class.json b/components/ws-manager/pkg/manager/testdata/cpwp_no_class.json new file mode 100644 index 00000000000000..744cc18a86d84c --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_no_class.json @@ -0,0 +1,28 @@ +{ + "spec": { + "ideImage": { + "webRef": "eu.gcr.io/gitpod-core-dev/buid/theia-ide:someversion" + }, + "workspaceImage": "eu.gcr.io/gitpod-dev/workspace-images/ac1c0755007966e4d6e090ea821729ac747d22ac/eu.gcr.io/gitpod-dev/workspace-base-images/github.com/typefox/gitpod:80a7d427a1fcd346d420603d80a31d57cf75a7af", + "initializer": { + "snapshot": { + "snapshot": "workspaces/cryptic-id-goes-herg/fd62804b-4cab-11e9-843a-4e645373048e.tar@gitpod-dev-user-christesting" + } + }, + "ports": [ + { + "port": 8080 + } + ], + "envvars": [ + { + "name": "foo", + "value": "bar" + } + ], + "git": { + "username": "usernameGoesHere", + "email": "some@user.com" + } + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.golden b/components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.golden new file mode 100644 index 00000000000000..a510ca07c4fa2a --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.golden @@ -0,0 +1,21 @@ +{ + "reason": { + "metadata": { + "name": "ws-test", + "namespace": "default", + "creationTimestamp": null + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "0" + } + }, + "storageClassName": "" + }, + "status": {} + } +} diff --git a/components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.json b/components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.json new file mode 100644 index 00000000000000..0a9fe6f4b70d74 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/cpwp_no_pvc.json @@ -0,0 +1,35 @@ +{ + "classes": { + "gitpodio-pvc": { + "resourceRequests": {"cpu": "900m"}, + "resourceLimits": {"cpu": "900m"} + } + }, + "spec": { + "ideImage": { + "webRef": "eu.gcr.io/gitpod-core-dev/buid/theia-ide:someversion" + }, + "workspaceImage": "eu.gcr.io/gitpod-dev/workspace-images/ac1c0755007966e4d6e090ea821729ac747d22ac/eu.gcr.io/gitpod-dev/workspace-base-images/github.com/typefox/gitpod:80a7d427a1fcd346d420603d80a31d57cf75a7af", + "initializer": { + "snapshot": { + "snapshot": "workspaces/cryptic-id-goes-herg/fd62804b-4cab-11e9-843a-4e645373048e.tar@gitpod-dev-user-christesting" + } + }, + "ports": [ + { + "port": 8080 + } + ], + "envvars": [ + { + "name": "foo", + "value": "bar" + } + ], + "git": { + "username": "usernameGoesHere", + "email": "some@user.com" + }, + "class": "gitpodio-pvc" + } +}