"Fossies" - the Fresh Open Source Software Archive

Member "minikube-1.26.1/test/integration/aaa_download_only_test.go" (2 Aug 2022, 10501 Bytes) of package /linux/misc/minikube-1.26.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "aaa_download_only_test.go": 1.25.2_vs_1.26.0.

A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.


    1 //go:build integration
    2 
    3 /*
    4 Copyright 2019 The Kubernetes Authors All rights reserved.
    5 
    6 Licensed under the Apache License, Version 2.0 (the "License");
    7 you may not use this file except in compliance with the License.
    8 You may obtain a copy of the License at
    9 
   10     http://www.apache.org/licenses/LICENSE-2.0
   11 
   12 Unless required by applicable law or agreed to in writing, software
   13 distributed under the License is distributed on an "AS IS" BASIS,
   14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15 See the License for the specific language governing permissions and
   16 limitations under the License.
   17 */
   18 
   19 package integration
   20 
   21 import (
   22     "bufio"
   23     "bytes"
   24     "context"
   25     "crypto/md5"
   26     "crypto/sha256"
   27     "encoding/json"
   28     "fmt"
   29     "net/http"
   30     "net/http/httptest"
   31     "os"
   32     "os/exec"
   33     "path/filepath"
   34     "runtime"
   35     "strings"
   36     "testing"
   37 
   38     "k8s.io/minikube/pkg/minikube/bootstrapper/images"
   39     "k8s.io/minikube/pkg/minikube/constants"
   40     "k8s.io/minikube/pkg/minikube/download"
   41     "k8s.io/minikube/pkg/minikube/localpath"
   42 )
   43 
   44 // TestDownloadOnly makes sure the --download-only parameter in minikube start caches the appropriate images and tarballs.
   45 func TestDownloadOnly(t *testing.T) {
   46     // Stores the startup run result for later error messages
   47     var rrr *RunResult
   48     profile := UniqueProfileName("download-only")
   49     ctx, cancel := context.WithTimeout(context.Background(), Minutes(30))
   50     defer Cleanup(t, profile, cancel)
   51     containerRuntime := ContainerRuntime()
   52 
   53     versions := []string{
   54         constants.OldestKubernetesVersion,
   55         constants.DefaultKubernetesVersion,
   56         constants.NewestKubernetesVersion,
   57     }
   58 
   59     // Small optimization, don't run the exact same set of tests twice
   60     if constants.DefaultKubernetesVersion == constants.NewestKubernetesVersion {
   61         versions = versions[:len(versions)-1]
   62     }
   63 
   64     for _, v := range versions {
   65         t.Run(v, func(t *testing.T) {
   66             defer PostMortemLogs(t, profile)
   67 
   68             t.Run("json-events", func(t *testing.T) {
   69                 // --force to avoid uid check
   70                 args := append([]string{"start", "-o=json", "--download-only", "-p", profile, "--force", "--alsologtostderr", fmt.Sprintf("--kubernetes-version=%s", v), fmt.Sprintf("--container-runtime=%s", containerRuntime)}, StartArgs()...)
   71                 rt, err := Run(t, exec.CommandContext(ctx, Target(), args...))
   72                 if rrr == nil {
   73                     // Preserve the initial run-result for debugging
   74                     rrr = rt
   75                 }
   76                 if err != nil {
   77                     t.Errorf("failed to download only. args: %q %v", args, err)
   78                 }
   79 
   80                 s := bufio.NewScanner(bytes.NewReader(rt.Stdout.Bytes()))
   81                 for s.Scan() {
   82                     var rtObj map[string]interface{}
   83                     err := json.Unmarshal(s.Bytes(), &rtObj)
   84                     if err != nil {
   85                         t.Errorf("failed to parse output: %v", err)
   86                     } else if step, ok := rtObj["data"]; ok {
   87                         if stepMap, ok := step.(map[string]interface{}); ok {
   88                             if stepMap["currentstep"] == "" {
   89                                 t.Errorf("Empty step number for %v", stepMap["name"])
   90                             }
   91                         }
   92                     }
   93                 }
   94             })
   95 
   96             preloadExists := false
   97             t.Run("preload-exists", func(t *testing.T) {
   98                 // skip for none, as none driver does not have preload feature.
   99                 if NoneDriver() {
  100                     t.Skip("None driver does not have preload")
  101                 }
  102                 // Driver does not matter here, since the only exception is none driver,
  103                 // which cannot occur here.
  104                 if download.PreloadExists(v, containerRuntime, "docker", true) {
  105                     // Just make sure the tarball path exists
  106                     if _, err := os.Stat(download.TarballPath(v, containerRuntime)); err != nil {
  107                         t.Errorf("failed to verify preloaded tarball file exists: %v", err)
  108                     }
  109                     preloadExists = true
  110                 } else {
  111                     t.Skip("No preload image")
  112                 }
  113             })
  114 
  115             t.Run("cached-images", func(t *testing.T) {
  116                 // skip verify for cache images if --driver=none
  117                 if NoneDriver() {
  118                     t.Skip("None driver has no cache")
  119                 }
  120                 if preloadExists {
  121                     t.Skip("Preload exists, images won't be cached")
  122                 }
  123                 imgs, err := images.Kubeadm("", v)
  124                 if err != nil {
  125                     t.Errorf("failed to get kubeadm images for %v: %+v", v, err)
  126                 }
  127 
  128                 for _, img := range imgs {
  129                     img = strings.Replace(img, ":", "_", 1) // for example kube-scheduler:v1.15.2 --> kube-scheduler_v1.15.2
  130                     fp := filepath.Join(localpath.MiniPath(), "cache", "images", img)
  131                     _, err := os.Stat(fp)
  132                     if err != nil {
  133                         t.Errorf("expected image file exist at %q but got error: %v", fp, err)
  134                     }
  135                 }
  136             })
  137 
  138             t.Run("binaries", func(t *testing.T) {
  139                 if preloadExists {
  140                     t.Skip("Preload exists, binaries are present within.")
  141                 }
  142                 // checking binaries downloaded (kubelet,kubeadm)
  143                 for _, bin := range constants.KubernetesReleaseBinaries {
  144                     fp := filepath.Join(localpath.MiniPath(), "cache", "linux", runtime.GOARCH, v, bin)
  145                     _, err := os.Stat(fp)
  146                     if err != nil {
  147                         t.Errorf("expected the file for binary exist at %q but got error %v", fp, err)
  148                     }
  149                 }
  150             })
  151 
  152             t.Run("kubectl", func(t *testing.T) {
  153                 // If we are on darwin/windows, check to make sure OS specific kubectl has been downloaded
  154                 // as well for the `minikube kubectl` command
  155                 if runtime.GOOS == "linux" {
  156                     t.Skip("Test for darwin and windows")
  157                 }
  158                 binary := "kubectl"
  159                 if runtime.GOOS == "windows" {
  160                     binary = "kubectl.exe"
  161                 }
  162                 fp := filepath.Join(localpath.MiniPath(), "cache", runtime.GOOS, runtime.GOARCH, v, binary)
  163                 if _, err := os.Stat(fp); err != nil {
  164                     t.Errorf("expected the file for binary exist at %q but got error %v", fp, err)
  165                 }
  166             })
  167 
  168             // checks if the duration of `minikube logs` takes longer than 5 seconds
  169             t.Run("LogsDuration", func(t *testing.T) {
  170                 ctx, cancel := context.WithTimeout(context.Background(), Seconds(5))
  171                 defer cancel()
  172                 args := []string{"logs", "-p", profile}
  173                 if _, err := Run(t, exec.CommandContext(ctx, Target(), args...)); err != nil {
  174                     t.Logf("minikube logs failed with error: %v", err)
  175                 }
  176                 if err := ctx.Err(); err == context.DeadlineExceeded {
  177                     t.Error("minikube logs expected to finish by 5 seconds, but took longer")
  178                 }
  179             })
  180 
  181         })
  182     }
  183 
  184     // This is a weird place to test profile deletion, but this test is serial, and we have a profile to delete!
  185     t.Run("DeleteAll", func(t *testing.T) {
  186         defer PostMortemLogs(t, profile)
  187 
  188         if !CanCleanup() {
  189             t.Skip("skipping, as cleanup is disabled")
  190         }
  191         rr, err := Run(t, exec.CommandContext(ctx, Target(), "delete", "--all"))
  192         if err != nil {
  193             t.Errorf("failed to delete all. args: %q : %v", rr.Command(), err)
  194         }
  195     })
  196     // Delete should always succeed, even if previously partially or fully deleted.
  197     t.Run("DeleteAlwaysSucceeds", func(t *testing.T) {
  198         defer PostMortemLogs(t, profile)
  199 
  200         if !CanCleanup() {
  201             t.Skip("skipping, as cleanup is disabled")
  202         }
  203         rr, err := Run(t, exec.CommandContext(ctx, Target(), "delete", "-p", profile))
  204         if err != nil {
  205             t.Errorf("failed to delete. args: %q: %v", rr.Command(), err)
  206         }
  207     })
  208 
  209 }
  210 
  211 // TestDownloadOnlyKic makes sure --download-only caches the docker driver images as well.
  212 func TestDownloadOnlyKic(t *testing.T) {
  213     if !KicDriver() {
  214         t.Skip("skipping, only for docker or podman driver")
  215     }
  216     profile := UniqueProfileName("download-docker")
  217     ctx, cancel := context.WithTimeout(context.Background(), Minutes(15))
  218     defer Cleanup(t, profile, cancel)
  219 
  220     cRuntime := ContainerRuntime()
  221 
  222     args := []string{"start", "--download-only", "-p", profile, "--force", "--alsologtostderr"}
  223     args = append(args, StartArgs()...)
  224 
  225     cmd := exec.CommandContext(ctx, Target(), args...)
  226     // make sure this works even if docker daemon isn't running
  227     cmd.Env = append(os.Environ(), "DOCKER_HOST=/does/not/exist")
  228     if _, err := Run(t, cmd); err != nil {
  229         t.Errorf("start with download only failed %q : %v", args, err)
  230     }
  231 
  232     // Make sure the downloaded image tarball exists
  233     tarball := download.TarballPath(constants.DefaultKubernetesVersion, cRuntime)
  234     contents, err := os.ReadFile(tarball)
  235     if err != nil {
  236         t.Errorf("failed to read tarball file %q: %v", tarball, err)
  237     }
  238 
  239     if arm64Platform() {
  240         t.Skip("Skip for arm64 platform. See https://github.com/kubernetes/minikube/issues/10144")
  241     }
  242     // Make sure it has the correct checksum
  243     checksum := md5.Sum(contents)
  244     remoteChecksum, err := os.ReadFile(download.PreloadChecksumPath(constants.DefaultKubernetesVersion, cRuntime))
  245     if err != nil {
  246         t.Errorf("failed to read checksum file %q : %v", download.PreloadChecksumPath(constants.DefaultKubernetesVersion, cRuntime), err)
  247     }
  248     if string(remoteChecksum) != string(checksum[:]) {
  249         t.Errorf("failed to verify checksum. checksum of %q does not match remote checksum (%q != %q)", tarball, string(remoteChecksum), string(checksum[:]))
  250     }
  251 }
  252 
  253 // createSha256File is a helper function which creates sha256 checksum file from given file
  254 func createSha256File(filePath string) error {
  255     dat, _ := os.ReadFile(filePath)
  256     sum := sha256.Sum256(dat)
  257 
  258     f, err := os.Create(filePath + ".sha256")
  259     if err != nil {
  260         return err
  261     }
  262     defer f.Close()
  263 
  264     _, err = f.WriteString(fmt.Sprintf("%x", sum[:]))
  265     if err != nil {
  266         return err
  267     }
  268     return nil
  269 }
  270 
  271 // TestBinaryMirror tests functionality of --binary-mirror flag
  272 func TestBinaryMirror(t *testing.T) {
  273     profile := UniqueProfileName("binary-mirror")
  274     ctx, cancel := context.WithTimeout(context.Background(), Minutes(10))
  275     defer Cleanup(t, profile, cancel)
  276 
  277     tmpDir := t.TempDir()
  278 
  279     // Start test server which will serve binary files
  280     ts := httptest.NewServer(
  281         http.FileServer(http.Dir(tmpDir)),
  282     )
  283     defer ts.Close()
  284 
  285     binaryName := "kubectl"
  286     if runtime.GOOS == "windows" {
  287         binaryName = "kubectl.exe"
  288     }
  289     binaryPath, err := download.Binary(binaryName, constants.DefaultKubernetesVersion, runtime.GOOS, runtime.GOARCH, "")
  290     if err != nil {
  291         t.Errorf("Failed to download binary: %+v", err)
  292     }
  293 
  294     newBinaryDir := filepath.Join(tmpDir, constants.DefaultKubernetesVersion, "bin", runtime.GOOS, runtime.GOARCH)
  295     if err := os.MkdirAll(newBinaryDir, os.ModePerm); err != nil {
  296         t.Errorf("Failed to create %s directories", newBinaryDir)
  297     }
  298 
  299     newBinaryPath := filepath.Join(newBinaryDir, binaryName)
  300     if err := os.Rename(binaryPath, newBinaryPath); err != nil {
  301         t.Errorf("Failed to move binary file: %+v", err)
  302     }
  303     if err := createSha256File(newBinaryPath); err != nil {
  304         t.Errorf("Failed to generate sha256 checksum file: %+v", err)
  305     }
  306 
  307     args := append([]string{"start", "--download-only", "-p", profile, "--alsologtostderr", "--binary-mirror", ts.URL}, StartArgs()...)
  308 
  309     cmd := exec.CommandContext(ctx, Target(), args...)
  310     if _, err := Run(t, cmd); err != nil {
  311         t.Errorf("start with --binary-mirror failed %q : %v", args, err)
  312     }
  313 }