From 378d6cd1cf19da957811bc9b30f4b3e242ce3e71 Mon Sep 17 00:00:00 2001 From: eaudetcobello Date: Wed, 11 Dec 2024 16:57:56 -0500 Subject: [PATCH] Unit test ValidateNodeTokenAccessHandler (#880) --- .../pkg/k8sd/api/node_access_handler_test.go | 100 ++++++++++++++++++ src/k8s/pkg/snap/mock/provider.go | 39 +++++++ 2 files changed, 139 insertions(+) create mode 100644 src/k8s/pkg/k8sd/api/node_access_handler_test.go create mode 100644 src/k8s/pkg/snap/mock/provider.go diff --git a/src/k8s/pkg/k8sd/api/node_access_handler_test.go b/src/k8s/pkg/k8sd/api/node_access_handler_test.go new file mode 100644 index 000000000..8171bb15c --- /dev/null +++ b/src/k8s/pkg/k8sd/api/node_access_handler_test.go @@ -0,0 +1,100 @@ +package api + +import ( + "context" + "net/http" + "os" + "path" + "testing" + + "github.com/canonical/k8s/pkg/snap" + "github.com/canonical/k8s/pkg/snap/mock" + . "github.com/onsi/gomega" +) + +func TestValidateNodeTokenAccessHandler(t *testing.T) { + for _, tc := range []struct { + name string + tokenHeaderContent string + tokenFileContent string + expectErr bool + createFile bool + }{ + { + name: "header and file token match", + tokenHeaderContent: "node-token", + tokenFileContent: "node-token", + createFile: true, + }, + { + name: "header and file token differ", + tokenHeaderContent: "node-token", + tokenFileContent: "different-node-token", + expectErr: true, + createFile: true, + }, + { + name: "missing header token", + tokenFileContent: "node-token", + expectErr: true, + createFile: true, + }, + { + name: "missing token file", + tokenHeaderContent: "node-token", + tokenFileContent: "node-token", + expectErr: true, + }, + { + name: "missing token in token file", + tokenHeaderContent: "node-token", + expectErr: true, + createFile: true, + }, + { + name: "missing header and token file", + expectErr: true, + }, + } { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + dir := t.TempDir() + + var err error + if tc.createFile { + err = os.WriteFile(path.Join(dir, "token-file"), []byte(tc.tokenFileContent), 0o644) + g.Expect(err).ToNot(HaveOccurred()) + } + + e := &Endpoints{ + context: context.Background(), + provider: &mock.Provider{ + SnapFn: func() snap.Snap { + return &mock.Snap{ + Mock: mock.Mock{ + NodeTokenFile: path.Join(dir, "token-file"), + }, + } + }, + }, + } + + req := &http.Request{ + Header: make(http.Header), + } + req.Header.Set("Node-Token", tc.tokenHeaderContent) + + handler := e.ValidateNodeTokenAccessHandler("Node-Token") + valid, resp := handler(nil, req) + + if tc.expectErr { + g.Expect(valid).To(BeFalse()) + g.Expect(resp).NotTo(BeNil()) + } else { + g.Expect(valid).To(BeTrue()) + g.Expect(resp).To(BeNil()) + } + }) + } +} diff --git a/src/k8s/pkg/snap/mock/provider.go b/src/k8s/pkg/snap/mock/provider.go new file mode 100644 index 000000000..321553c2f --- /dev/null +++ b/src/k8s/pkg/snap/mock/provider.go @@ -0,0 +1,39 @@ +package mock + +import ( + "github.com/canonical/k8s/pkg/snap" + "github.com/canonical/microcluster/v2/microcluster" +) + +type Provider struct { + MicroClusterFn func() *microcluster.MicroCluster + SnapFn func() snap.Snap + NotifyUpdateNodeConfigControllerFn func() + NotifyFeatureControllerFn func(network, gateway, ingress, loadBalancer, localStorage, metricsServer, dns bool) +} + +func (p *Provider) MicroCluster() *microcluster.MicroCluster { + if p.MicroClusterFn != nil { + return p.MicroClusterFn() + } + return nil +} + +func (p *Provider) Snap() snap.Snap { + if p.SnapFn != nil { + return p.SnapFn() + } + return nil +} + +func (p *Provider) NotifyUpdateNodeConfigController() { + if p.NotifyUpdateNodeConfigControllerFn != nil { + p.NotifyUpdateNodeConfigControllerFn() + } +} + +func (p *Provider) NotifyFeatureController(network, gateway, ingress, loadBalancer, localStorage, metricsServer, dns bool) { + if p.NotifyFeatureControllerFn != nil { + p.NotifyFeatureControllerFn(network, gateway, ingress, loadBalancer, localStorage, metricsServer, dns) + } +}