sigs.k8s.io/blob-csi-driver@v1.24.1/test/e2e/suite_test.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package e2e 18 19 import ( 20 "context" 21 "encoding/json" 22 "flag" 23 "fmt" 24 "log" 25 "os" 26 "os/exec" 27 "path" 28 "path/filepath" 29 "strings" 30 "testing" 31 "time" 32 33 "github.com/onsi/ginkgo/v2" 34 "github.com/onsi/ginkgo/v2/reporters" 35 "github.com/onsi/gomega" 36 "github.com/pborman/uuid" 37 "k8s.io/klog/v2" 38 "k8s.io/kubernetes/test/e2e/framework" 39 "k8s.io/kubernetes/test/e2e/framework/config" 40 _ "k8s.io/kubernetes/test/e2e/framework/debug/init" 41 "sigs.k8s.io/blob-csi-driver/pkg/blob" 42 "sigs.k8s.io/blob-csi-driver/pkg/util" 43 "sigs.k8s.io/blob-csi-driver/test/utils/azure" 44 "sigs.k8s.io/blob-csi-driver/test/utils/credentials" 45 "sigs.k8s.io/blob-csi-driver/test/utils/testutil" 46 ) 47 48 const ( 49 kubeconfigEnvVar = "KUBECONFIG" 50 reportDirEnv = "ARTIFACTS" 51 defaultReportDir = "/workspace/_artifacts" 52 ) 53 54 var isAzureStackCloud = strings.EqualFold(os.Getenv("AZURE_CLOUD_NAME"), "AZURESTACKCLOUD") 55 var blobDriver *blob.Driver 56 var projectRoot string 57 58 type testCmd struct { 59 command string 60 args []string 61 startLog string 62 endLog string 63 } 64 65 func TestMain(m *testing.M) { 66 flag.StringVar(&projectRoot, "project-root", "", "path to the blob csi driver project root, used for script execution") 67 flag.Parse() 68 if projectRoot == "" { 69 klog.Fatal("project-root must be set") 70 } 71 72 config.CopyFlags(config.Flags, flag.CommandLine) 73 framework.RegisterCommonFlags(flag.CommandLine) 74 framework.RegisterClusterFlags(flag.CommandLine) 75 flag.Parse() 76 framework.AfterReadingAllFlags(&framework.TestContext) 77 os.Exit(m.Run()) 78 } 79 80 func TestE2E(t *testing.T) { 81 gomega.RegisterFailHandler(ginkgo.Fail) 82 reportDir := os.Getenv(reportDirEnv) 83 if reportDir == "" { 84 reportDir = defaultReportDir 85 } 86 r := []ginkgo.Reporter{reporters.NewJUnitReporter(path.Join(reportDir, "junit_01.xml"))} 87 ginkgo.RunSpecsWithDefaultAndCustomReporters(t, "Azure Blob Storage CSI driver End-to-End Tests", r) 88 } 89 90 var _ = ginkgo.SynchronizedBeforeSuite(func(ctx ginkgo.SpecContext) []byte { 91 creds, err := credentials.CreateAzureCredentialFile() 92 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 93 azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret) 94 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 95 _, err = azureClient.EnsureResourceGroup(ctx, creds.ResourceGroup, creds.Location, nil) 96 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 97 98 if testutil.IsRunningInProw() { 99 // Need to login to ACR using SP credential if we are running in Prow so we can push test images. 100 // If running locally, user should run 'docker login' before running E2E tests 101 registry := os.Getenv("REGISTRY") 102 gomega.Expect(registry).NotTo(gomega.Equal("")) 103 104 log.Println("Attempting docker login with Azure service principal") 105 cmd := exec.Command("docker", "login", fmt.Sprintf("--username=%s", creds.AADClientID), fmt.Sprintf("--password=%s", creds.AADClientSecret), registry) 106 err = cmd.Run() 107 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 108 log.Println("docker login is successful") 109 } 110 111 // Install Azure Blob Storage CSI driver on cluster from project root 112 e2eBootstrap := testCmd{ 113 command: "make", 114 args: []string{"e2e-bootstrap"}, 115 startLog: "Installing Azure Blob Storage CSI driver ...", 116 endLog: "Azure Blob Storage CSI driver installed", 117 } 118 119 createMetricsSVC := testCmd{ 120 command: "make", 121 args: []string{"create-metrics-svc"}, 122 startLog: "create metrics service ...", 123 endLog: "metrics service created", 124 } 125 execTestCmd([]testCmd{e2eBootstrap, createMetricsSVC}) 126 127 if testutil.IsRunningInProw() { 128 data, err := json.Marshal(creds) 129 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 130 return data 131 } 132 133 return nil 134 }, func(ctx ginkgo.SpecContext, data []byte) { 135 if testutil.IsRunningInProw() { 136 creds := &credentials.Credentials{} 137 err := json.Unmarshal(data, creds) 138 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 139 // set env for azidentity.EnvironmentCredential 140 os.Setenv("AZURE_TENANT_ID", creds.TenantID) 141 os.Setenv("AZURE_CLIENT_ID", creds.AADClientID) 142 os.Setenv("AZURE_CLIENT_SECRET", creds.AADClientSecret) 143 } 144 145 // k8s.io/kubernetes/test/e2e/framework requires env KUBECONFIG to be set 146 // it does not fall back to defaults 147 if os.Getenv(kubeconfigEnvVar) == "" { 148 kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config") 149 os.Setenv(kubeconfigEnvVar, kubeconfig) 150 } 151 152 // spin up a blob driver locally to make use of the azure client and controller service 153 kubeconfig := os.Getenv(kubeconfigEnvVar) 154 _, useBlobfuseProxy := os.LookupEnv("ENABLE_BLOBFUSE_PROXY") 155 os.Setenv("AZURE_CREDENTIAL_FILE", credentials.TempAzureCredentialFilePath) 156 driverOptions := blob.DriverOptions{ 157 NodeID: os.Getenv("nodeid"), 158 DriverName: blob.DefaultDriverName, 159 BlobfuseProxyEndpoint: "", 160 EnableBlobfuseProxy: useBlobfuseProxy, 161 BlobfuseProxyConnTimout: 5, 162 EnableBlobMockMount: false, 163 } 164 kubeClient, err := util.GetKubeClient(kubeconfig, 25.0, 50, "") 165 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 166 cloud, err := blob.GetCloudProvider(context.Background(), kubeClient, driverOptions.NodeID, "", "", "", false) 167 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 168 blobDriver = blob.NewDriver(&driverOptions, kubeClient, cloud) 169 go func() { 170 err := blobDriver.Run(context.Background(), fmt.Sprintf("unix:///tmp/csi-%s.sock", uuid.NewUUID().String())) 171 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 172 }() 173 }) 174 175 var _ = ginkgo.SynchronizedAfterSuite(func(ctx ginkgo.SpecContext) {}, 176 func(ctx ginkgo.SpecContext) { 177 blobLog := testCmd{ 178 command: "bash", 179 args: []string{"test/utils/blob_log.sh"}, 180 startLog: "==============start blob log(after suite)===================", 181 endLog: "==============end blob log(after suite)===================", 182 } 183 e2eTeardown := testCmd{ 184 command: "make", 185 args: []string{"e2e-teardown"}, 186 startLog: "Uninstalling Azure Blob Storage CSI driver...", 187 endLog: "Azure Blob Storage CSI driver uninstalled", 188 } 189 execTestCmd([]testCmd{blobLog, e2eTeardown}) 190 191 // install/uninstall CSI Driver deployment scripts test 192 installDriver := testCmd{ 193 command: "bash", 194 args: []string{"deploy/install-driver.sh", "master", "local,enable-blobfuse-proxy"}, 195 startLog: "===================install CSI Driver deployment scripts test===================", 196 endLog: "===================================================", 197 } 198 uninstallDriver := testCmd{ 199 command: "bash", 200 args: []string{"deploy/uninstall-driver.sh", "master", "local,enable-blobfuse-proxy"}, 201 startLog: "===================uninstall CSI Driver deployment scripts test===================", 202 endLog: "===================================================", 203 } 204 execTestCmd([]testCmd{installDriver, uninstallDriver}) 205 206 checkAccountCreationLeak(ctx) 207 208 err := credentials.DeleteAzureCredentialFile() 209 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 210 }, ginkgo.NodeTimeout(10*time.Minute)) 211 212 func execTestCmd(cmds []testCmd) { 213 ginkgo.GinkgoHelper() 214 215 for _, cmd := range cmds { 216 log.Println(cmd.startLog) 217 cmdSh := exec.Command(cmd.command, cmd.args...) 218 cmdSh.Dir = projectRoot 219 cmdSh.Stdout = os.Stdout 220 cmdSh.Stderr = os.Stderr 221 err := cmdSh.Run() 222 if err != nil { 223 log.Printf("Failed to run command: %s %s, Error: %s\n", cmd.command, strings.Join(cmd.args, " "), err.Error()) 224 } 225 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 226 log.Println(cmd.endLog) 227 } 228 } 229 230 func checkAccountCreationLeak(ctx context.Context) { 231 creds, err := credentials.CreateAzureCredentialFile() 232 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 233 azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret) 234 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 235 236 accountNum, err := azureClient.GetAccountNumByResourceGroup(ctx, creds.ResourceGroup) 237 framework.ExpectNoError(err, fmt.Sprintf("failed to GetAccountNumByResourceGroup(%s): %v", creds.ResourceGroup, err)) 238 ginkgo.By(fmt.Sprintf("GetAccountNumByResourceGroup(%s) returns %d accounts", creds.ResourceGroup, accountNum)) 239 240 accountLimitInTest := 20 241 gomega.Expect(accountNum >= accountLimitInTest).To(gomega.BeFalse()) 242 }