mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			374 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2017 The Kubernetes Authors.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
// Unit tests for hack/e2e.go shim
 | 
						|
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"flag"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"reflect"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
type FileInfo struct {
 | 
						|
	when time.Time
 | 
						|
}
 | 
						|
 | 
						|
func (f FileInfo) Name() string {
 | 
						|
	return "fake-file"
 | 
						|
}
 | 
						|
 | 
						|
func (f FileInfo) Size() int64 {
 | 
						|
	return 0
 | 
						|
}
 | 
						|
 | 
						|
func (f FileInfo) Mode() os.FileMode {
 | 
						|
	return 0
 | 
						|
}
 | 
						|
 | 
						|
func (f FileInfo) ModTime() time.Time {
 | 
						|
	return f.when
 | 
						|
}
 | 
						|
 | 
						|
func (f FileInfo) IsDir() bool {
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
func (f FileInfo) Sys() interface{} {
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
func TestParse(t *testing.T) {
 | 
						|
	cases := []struct {
 | 
						|
		args     []string
 | 
						|
		expected flags
 | 
						|
		err      error
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			[]string{"foo", "-v=false"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--verbose-commands=false"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"foo", "-v"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--verbose-commands=true"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"hello", "world"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--verbose-commands=true", "world"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"hello", "--", "--venus", "--karaoke"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--verbose-commands=true", "--venus", "--karaoke"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"hello", "--alpha", "--beta"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--alpha", "--beta"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"so", "--get", "--boo"},
 | 
						|
			flags{true, oldDefault, []string{"--boo"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"omg", "--get=false", "--", "ugh"},
 | 
						|
			flags{false, oldDefault, []string{"--verbose-commands=true", "ugh"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"wee", "--old=5m", "--get"},
 | 
						|
			flags{true, 5 * time.Minute, []string{"--verbose-commands=true"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"fun", "--times", "--old=666s"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--times", "--old=666s"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"wut", "-h"},
 | 
						|
			flags{},
 | 
						|
			flag.ErrHelp,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			[]string{"wut", "--", "-h"},
 | 
						|
			flags{getDefault, oldDefault, []string{"--verbose-commands=true", "-h"}},
 | 
						|
			nil,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, c := range cases {
 | 
						|
		a, err := parse(c.args)
 | 
						|
		if err != c.err {
 | 
						|
			t.Errorf("%d: a=%v != e%v", i, err, c.err)
 | 
						|
		}
 | 
						|
		e := c.expected
 | 
						|
		if a.get != e.get {
 | 
						|
			t.Errorf("%d: a=%v != e=%v", i, a.get, e.get)
 | 
						|
		}
 | 
						|
		if a.old != e.old {
 | 
						|
			t.Errorf("%d: a=%v != e=%v", i, a.old, e.old)
 | 
						|
		}
 | 
						|
		if !reflect.DeepEqual(a.args, e.args) {
 | 
						|
			t.Errorf("%d: a=%v != e=%v", i, a.args, e.args)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestLook(t *testing.T) {
 | 
						|
	lpf := errors.New("LookPath failed")
 | 
						|
	sf := errors.New("Stat failed")
 | 
						|
	lpnc := errors.New("LookPath should not be called")
 | 
						|
	snc := errors.New("Stat should not be called")
 | 
						|
	cases := []struct {
 | 
						|
		stat     error
 | 
						|
		lookPath error
 | 
						|
		goPath   string
 | 
						|
		expected error
 | 
						|
	}{
 | 
						|
		{ // GOPATH set, stat succeeds returns gopath
 | 
						|
			stat:     nil,
 | 
						|
			lookPath: lpnc,
 | 
						|
			goPath:   "fake-gopath/",
 | 
						|
			expected: nil,
 | 
						|
		},
 | 
						|
		{ // GOPATH set, stat fails, terms on lookpath
 | 
						|
			stat:     sf,
 | 
						|
			lookPath: lpf,
 | 
						|
			goPath:   "fake-gopath/",
 | 
						|
			expected: lpf,
 | 
						|
		},
 | 
						|
		{ // GOPATH unset, stat not called, terms on lookpath
 | 
						|
			stat:     snc,
 | 
						|
			lookPath: lpf,
 | 
						|
			goPath:   "",
 | 
						|
			expected: lpf,
 | 
						|
		},
 | 
						|
		{ // GOPATH unset, stat not called, lookpath matches
 | 
						|
			stat:     snc,
 | 
						|
			lookPath: nil,
 | 
						|
			goPath:   "",
 | 
						|
			expected: nil,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, c := range cases {
 | 
						|
		l := tester{
 | 
						|
			func(string) (os.FileInfo, error) {
 | 
						|
				return FileInfo{}, c.stat
 | 
						|
			},
 | 
						|
			func(string) (string, error) {
 | 
						|
				if c.lookPath != nil {
 | 
						|
					return "FAILED", c.lookPath
 | 
						|
				}
 | 
						|
				return "$PATH-FOUND", nil
 | 
						|
			},
 | 
						|
			c.goPath,
 | 
						|
			nil, // wait
 | 
						|
		}
 | 
						|
		if _, err := l.lookKubetest(); err != c.expected {
 | 
						|
			t.Errorf("err: %s != %s", err, c.expected)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestGetKubetest(t *testing.T) {
 | 
						|
	gp := "fake-gopath"
 | 
						|
	gpk := filepath.Join(gp, "bin", "kubetest")
 | 
						|
	p := "PATH"
 | 
						|
	pk := filepath.Join(p, "kubetest")
 | 
						|
	eu := errors.New("upgrade failed")
 | 
						|
	euVerbose := fmt.Errorf("go get -u k8s.io/test-infra/kubetest: %v", eu)
 | 
						|
	et := errors.New("touch failed")
 | 
						|
	cases := []struct {
 | 
						|
		name string
 | 
						|
		get  bool
 | 
						|
		old  time.Duration
 | 
						|
 | 
						|
		stat     string        // stat succeeds on this file
 | 
						|
		path     bool          // file exists on path
 | 
						|
		age      time.Duration // age of mod time on file
 | 
						|
		upgraded bool          // go get -u succeeds
 | 
						|
		touched  bool          // touch succeeds
 | 
						|
		goPath   string        // GOPATH var
 | 
						|
 | 
						|
		returnPath  string
 | 
						|
		returnError error
 | 
						|
	}{
 | 
						|
		{name: "0: Pass when on GOPATH/bin",
 | 
						|
			get: false,
 | 
						|
			old: 0,
 | 
						|
 | 
						|
			stat:     gpk,
 | 
						|
			path:     false,
 | 
						|
			age:      100,
 | 
						|
			upgraded: false,
 | 
						|
			touched:  false,
 | 
						|
			goPath:   gp,
 | 
						|
 | 
						|
			returnPath:  gpk,
 | 
						|
			returnError: nil,
 | 
						|
		},
 | 
						|
		{name: "1: Pass when on PATH",
 | 
						|
			get: false,
 | 
						|
			old: 0,
 | 
						|
 | 
						|
			stat:     pk,
 | 
						|
			path:     true,
 | 
						|
			age:      100,
 | 
						|
			upgraded: false,
 | 
						|
			touched:  false,
 | 
						|
			goPath:   gp,
 | 
						|
 | 
						|
			returnPath:  pk,
 | 
						|
			returnError: nil,
 | 
						|
		},
 | 
						|
		{name: "2: Don't upgrade if on PATH and GOPATH is ''",
 | 
						|
			get: true,
 | 
						|
			old: 0,
 | 
						|
 | 
						|
			stat:     pk,
 | 
						|
			path:     true,
 | 
						|
			age:      100,
 | 
						|
			upgraded: false,
 | 
						|
			touched:  false,
 | 
						|
			goPath:   "",
 | 
						|
 | 
						|
			returnPath:  pk,
 | 
						|
			returnError: nil,
 | 
						|
		},
 | 
						|
		{name: "3: Don't upgrade on PATH when young.",
 | 
						|
			get: true,
 | 
						|
			old: time.Hour,
 | 
						|
 | 
						|
			stat:     pk,
 | 
						|
			path:     true,
 | 
						|
			age:      time.Second,
 | 
						|
			upgraded: false,
 | 
						|
			touched:  false,
 | 
						|
			goPath:   gp,
 | 
						|
 | 
						|
			returnPath:  pk,
 | 
						|
			returnError: nil,
 | 
						|
		},
 | 
						|
		{name: "4: Upgrade if old but GOPATH is set.",
 | 
						|
			get: true,
 | 
						|
			old: 0,
 | 
						|
 | 
						|
			stat:     pk,
 | 
						|
			path:     true,
 | 
						|
			age:      time.Second,
 | 
						|
			upgraded: true,
 | 
						|
			touched:  true,
 | 
						|
			goPath:   gp,
 | 
						|
 | 
						|
			returnPath:  pk,
 | 
						|
			returnError: nil,
 | 
						|
		},
 | 
						|
		{name: "5: Fail if upgrade fails",
 | 
						|
			get: true,
 | 
						|
			old: 0,
 | 
						|
 | 
						|
			stat:     pk,
 | 
						|
			path:     true,
 | 
						|
			age:      time.Second,
 | 
						|
			upgraded: false,
 | 
						|
			touched:  false,
 | 
						|
			goPath:   gpk,
 | 
						|
 | 
						|
			returnPath:  "",
 | 
						|
			returnError: euVerbose,
 | 
						|
		},
 | 
						|
		{name: "6: Fail if touch fails",
 | 
						|
			get: true,
 | 
						|
			old: 0,
 | 
						|
 | 
						|
			stat:     pk,
 | 
						|
			path:     true,
 | 
						|
			age:      time.Second,
 | 
						|
			upgraded: true,
 | 
						|
			touched:  false,
 | 
						|
			goPath:   gpk,
 | 
						|
 | 
						|
			returnPath:  "",
 | 
						|
			returnError: et,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, c := range cases {
 | 
						|
		didUp := false
 | 
						|
		didTouch := false
 | 
						|
		l := tester{
 | 
						|
			stat: func(p string) (os.FileInfo, error) {
 | 
						|
				// stat
 | 
						|
				if p != c.stat {
 | 
						|
					return nil, fmt.Errorf("Failed to find %s", p)
 | 
						|
				}
 | 
						|
				return FileInfo{time.Now().Add(c.age * -1)}, nil
 | 
						|
			},
 | 
						|
			lookPath: func(name string) (string, error) {
 | 
						|
				if c.path {
 | 
						|
					return filepath.Join(p, name), nil
 | 
						|
				}
 | 
						|
				return "", fmt.Errorf("Not on path: %s", name)
 | 
						|
			},
 | 
						|
			goPath: c.goPath,
 | 
						|
			wait: func(cmd string, args ...string) error {
 | 
						|
				if cmd == "go" {
 | 
						|
					if c.upgraded {
 | 
						|
						didUp = true
 | 
						|
						return nil
 | 
						|
					}
 | 
						|
					return eu
 | 
						|
				}
 | 
						|
				if c.touched {
 | 
						|
					didTouch = true
 | 
						|
					return nil
 | 
						|
				}
 | 
						|
				return et
 | 
						|
			},
 | 
						|
		}
 | 
						|
		p, e := l.getKubetest(c.get, c.old)
 | 
						|
		if p != c.returnPath {
 | 
						|
			t.Errorf("%d: test=%q returnPath %q != %q", i, c.name, p, c.returnPath)
 | 
						|
		}
 | 
						|
		if e == nil || c.returnError == nil {
 | 
						|
			if e != c.returnError {
 | 
						|
				t.Errorf("%d: test=%q returnError %q != %q", i, c.name, e, c.returnError)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			if e.Error() != c.returnError.Error() {
 | 
						|
				t.Errorf("%d: test=%q returnError %q != %q", i, c.name, e, c.returnError)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if didUp != c.upgraded {
 | 
						|
			t.Errorf("%d: test=%q bad upgrade state of %v", i, c.name, didUp)
 | 
						|
		}
 | 
						|
		if didTouch != c.touched {
 | 
						|
			t.Errorf("%d: test=%q bad touch state of %v", i, c.name, didTouch)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |