mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
kubeadm: add better test coverage to token.go
new tests added: - TestRunGenerateToken - TestNewCmdTokenGenerate - TestNewCmdToken - TestGetSecretString - TestGetClientset - TestRunDeleteToken - TestRunListTokens
This commit is contained in:
parent
5364f7beb8
commit
312b8cc193
@ -94,6 +94,7 @@ go_test(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -18,8 +18,17 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
@ -27,11 +36,47 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
|
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TokenExpectedRegex = "^\\S{6}\\.\\S{16}\n$"
|
TokenExpectedRegex = "^\\S{6}\\.\\S{16}\n$"
|
||||||
|
TestConfig = `apiVersion: v1
|
||||||
|
clusters:
|
||||||
|
- cluster:
|
||||||
|
certificate-authority-data:
|
||||||
|
server: localhost:8000
|
||||||
|
name: prod
|
||||||
|
contexts:
|
||||||
|
- context:
|
||||||
|
cluster: prod
|
||||||
|
namespace: default
|
||||||
|
user: default-service-account
|
||||||
|
name: default
|
||||||
|
current-context: default
|
||||||
|
kind: Config
|
||||||
|
preferences: {}
|
||||||
|
users:
|
||||||
|
- name: kubernetes-admin
|
||||||
|
user:
|
||||||
|
client-certificate-data:
|
||||||
|
client-key-data:
|
||||||
|
`
|
||||||
|
TestConfigCertAuthorityData = "certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFM01USXhOREUxTlRFek1Gb1hEVEkzTVRJeE1qRTFOVEV6TUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTlZrCnNkT0NjRDBIOG9ycXZ5djBEZ09jZEpjRGc4aTJPNGt3QVpPOWZUanJGRHJqbDZlVXRtdlMyZ1lZd0c4TGhPV2gKb0lkZ3AvbVkrbVlDakliUUJtTmE2Ums1V2JremhJRzM1c1lseE9NVUJJR0xXMzN0RTh4SlR1RVd3V0NmZnpLcQpyaU1UT1A3REF3MUxuM2xUNlpJNGRNM09NOE1IUk9Wd3lRMDVpbWo5eUx5R1lYdTlvSncwdTVXWVpFYmpUL3VpCjJBZ2QwVDMrZGFFb044aVBJOTlVQkQxMzRkc2VGSEJEY3hHcmsvVGlQdHBpSC9IOGoxRWZaYzRzTGlONzJmL2YKYUpacTROSHFiT2F5UkpITCtJejFNTW1DRkN3cjdHOHVENWVvWWp2dEdZN2xLc1pBTlUwK3VlUnJsTitxTzhQWQpxaTZNMDFBcmV1UzFVVHFuTkM4Q0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFNbXo4Nm9LMmFLa0owMnlLSC9ZcTlzaDZZcDEKYmhLS25mMFJCaTA1clRacWdhTi9oTnROdmQxSzJxZGRLNzhIT2pVdkpNRGp3NERieXF0Wll2V01XVFRCQnQrSgpPMGNyWkg5NXlqUW42YzRlcU1FTjFhOUFKNXRlclNnTDVhREJsK0FMTWxaNVpxTzBUOUJDdTJtNXV3dGNWaFZuCnh6cGpTT3V5WVdOQ3A5bW9mV2VPUTljNXhEcElWeUlMUkFvNmZ5Z2c3N25TSDN4ckVmd0VKUHFMd1RPYVk1bTcKeEZWWWJoR3dxUGU5V0I5aTR5cnNrZUFBWlpUSzdVbklKMXFkRmlHQk9aZlRtaDhYQ3BOTHZZcFBLQW9hWWlsRwpjOW1acVhpWVlESTV6R1IxMElpc2FWNXJUY2hDenNQVWRhQzRVbnpTZG01cTdKYTAyb0poQlU1TE1FMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
|
||||||
|
TestConfigNoCluster = `apiVersion: v1
|
||||||
|
clusters:
|
||||||
|
- cluster:
|
||||||
|
server:
|
||||||
|
name: prod
|
||||||
|
contexts:
|
||||||
|
- context:
|
||||||
|
namespace: default
|
||||||
|
user: default-service-account
|
||||||
|
name: default
|
||||||
|
kind: Config
|
||||||
|
preferences: {}
|
||||||
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRunGenerateToken(t *testing.T) {
|
func TestRunGenerateToken(t *testing.T) {
|
||||||
@ -46,7 +91,7 @@ func TestRunGenerateToken(t *testing.T) {
|
|||||||
|
|
||||||
matched, err := regexp.MatchString(TokenExpectedRegex, output)
|
matched, err := regexp.MatchString(TokenExpectedRegex, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("encountered an error while trying to match RunGenerateToken's output: %v", err)
|
t.Fatalf("Encountered an error while trying to match RunGenerateToken's output: %v", err)
|
||||||
}
|
}
|
||||||
if !matched {
|
if !matched {
|
||||||
t.Errorf("RunGenerateToken's output did not match expected regex; wanted: [%s], got: [%s]", TokenExpectedRegex, output)
|
t.Errorf("RunGenerateToken's output did not match expected regex; wanted: [%s], got: [%s]", TokenExpectedRegex, output)
|
||||||
@ -65,6 +110,7 @@ func TestRunCreateToken(t *testing.T) {
|
|||||||
token string
|
token string
|
||||||
usages []string
|
usages []string
|
||||||
extraGroups []string
|
extraGroups []string
|
||||||
|
printJoin bool
|
||||||
expectedError bool
|
expectedError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -123,10 +169,18 @@ func TestRunCreateToken(t *testing.T) {
|
|||||||
extraGroups: []string{"system:bootstrappers:foo"},
|
extraGroups: []string{"system:bootstrappers:foo"},
|
||||||
expectedError: true,
|
expectedError: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid: print join command",
|
||||||
|
token: "",
|
||||||
|
usages: []string{"signing", "authentication"},
|
||||||
|
extraGroups: []string{"system:bootstrappers:foo"},
|
||||||
|
printJoin: true,
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|
||||||
cfg := &kubeadmapiext.MasterConfiguration{
|
cfg := &kubeadmapiext.MasterConfiguration{
|
||||||
|
|
||||||
// KubernetesVersion is not used by bootstrap-token, but we set this explicitly to avoid
|
// KubernetesVersion is not used by bootstrap-token, but we set this explicitly to avoid
|
||||||
// the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
// the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
||||||
KubernetesVersion: "v1.9.0",
|
KubernetesVersion: "v1.9.0",
|
||||||
@ -136,9 +190,345 @@ func TestRunCreateToken(t *testing.T) {
|
|||||||
TokenGroups: tc.extraGroups,
|
TokenGroups: tc.extraGroups,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := RunCreateToken(&buf, fakeClient, "", cfg, "", false, "")
|
err := RunCreateToken(&buf, fakeClient, "", cfg, "", tc.printJoin, "")
|
||||||
if (err != nil) != tc.expectedError {
|
if (err != nil) != tc.expectedError {
|
||||||
t.Errorf("Test case %s: RunCreateToken expected error: %v, saw: %v", tc.name, tc.expectedError, (err != nil))
|
t.Errorf("Test case %s: RunCreateToken expected error: %v, saw: %v", tc.name, tc.expectedError, (err != nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewCmdTokenGenerate(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
args := []string{}
|
||||||
|
|
||||||
|
cmd := NewCmdTokenGenerate(&buf)
|
||||||
|
cmd.SetArgs(args)
|
||||||
|
|
||||||
|
if err := cmd.Execute(); err != nil {
|
||||||
|
t.Errorf("Cannot execute token command: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewCmdToken(t *testing.T) {
|
||||||
|
var buf, bufErr bytes.Buffer
|
||||||
|
testConfigFile := "test-config-file"
|
||||||
|
|
||||||
|
tmpDir, err := ioutil.TempDir("", "kubeadm-token-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
fullPath := filepath.Join(tmpDir, testConfigFile)
|
||||||
|
|
||||||
|
f, err := os.Create(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
configToWrite string
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid: generate",
|
||||||
|
args: []string{"generate"},
|
||||||
|
configToWrite: "",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid: delete",
|
||||||
|
args: []string{"delete", "abcdef.1234567890123456", "--dry-run", "--kubeconfig=" + fullPath},
|
||||||
|
configToWrite: TestConfig,
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := NewCmdToken(&buf, &bufErr)
|
||||||
|
for _, tc := range testCases {
|
||||||
|
if _, err = f.WriteString(tc.configToWrite); err != nil {
|
||||||
|
t.Errorf("Unable to write test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
cmd.SetArgs(tc.args)
|
||||||
|
err := cmd.Execute()
|
||||||
|
if (err != nil) != tc.expectedError {
|
||||||
|
t.Errorf("Test case %q: NewCmdToken expected error: %v, saw: %v", tc.name, tc.expectedError, (err != nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSecretString(t *testing.T) {
|
||||||
|
secret := v1.Secret{}
|
||||||
|
key := "test-key"
|
||||||
|
if str := getSecretString(&secret, key); str != "" {
|
||||||
|
t.Errorf("getSecretString() did not return empty string for a nil v1.Secret.Data")
|
||||||
|
}
|
||||||
|
secret.Data = make(map[string][]byte)
|
||||||
|
if str := getSecretString(&secret, key); str != "" {
|
||||||
|
t.Errorf("getSecretString() did not return empty string for missing v1.Secret.Data key")
|
||||||
|
}
|
||||||
|
secret.Data[key] = []byte("test-value")
|
||||||
|
if str := getSecretString(&secret, key); str == "" {
|
||||||
|
t.Errorf("getSecretString() failed for a valid v1.Secret.Data key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetClientset(t *testing.T) {
|
||||||
|
testConfigFile := "test-config-file"
|
||||||
|
|
||||||
|
tmpDir, err := ioutil.TempDir("", "kubeadm-token-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
fullPath := filepath.Join(tmpDir, testConfigFile)
|
||||||
|
|
||||||
|
// test dryRun = false on a non-exisiting file
|
||||||
|
if _, err = getClientset(fullPath, false); err == nil {
|
||||||
|
t.Errorf("getClientset(); dry-run: false; did no fail for test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test dryRun = true on a non-exisiting file
|
||||||
|
if _, err = getClientset(fullPath, true); err == nil {
|
||||||
|
t.Errorf("getClientset(); dry-run: true; did no fail for test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Create(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if _, err = f.WriteString(TestConfig); err != nil {
|
||||||
|
t.Errorf("Unable to write test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test dryRun = true on an exisiting file
|
||||||
|
if _, err = getClientset(fullPath, true); err != nil {
|
||||||
|
t.Errorf("getClientset(); dry-run: true; failed for test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunDeleteToken(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
tmpDir, err := ioutil.TempDir("", "kubeadm-token-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
fullPath := filepath.Join(tmpDir, "test-config-file")
|
||||||
|
|
||||||
|
f, err := os.Create(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if _, err = f.WriteString(TestConfig); err != nil {
|
||||||
|
t.Errorf("Unable to write test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := getClientset(fullPath, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to run getClientset() for test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test valid; should not fail
|
||||||
|
// for some reason Secrets().Delete() does not fail even for this dummy config
|
||||||
|
if err = RunDeleteToken(&buf, client, "abcdef.1234567890123456"); err != nil {
|
||||||
|
t.Errorf("RunDeleteToken() failed for a valid token: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test invalid token; should fail
|
||||||
|
if err = RunDeleteToken(&buf, client, "invalid-token"); err == nil {
|
||||||
|
t.Errorf("RunDeleteToken() succeeded for an invalid token: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpTestItr uint32
|
||||||
|
var httpSentResponse uint32 = 1
|
||||||
|
|
||||||
|
func TestRunListTokens(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
var bufOut, bufErr bytes.Buffer
|
||||||
|
|
||||||
|
tmpDir, err := ioutil.TempDir("", "kubeadm-token-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
fullPath := filepath.Join(tmpDir, "test-config-file")
|
||||||
|
|
||||||
|
f, err := os.Create(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to create test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
// test config without secrets; should fail
|
||||||
|
if _, err = f.WriteString(TestConfig); err != nil {
|
||||||
|
t.Errorf("Unable to write test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := getClientset(fullPath, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to run getClientset() for test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = RunListTokens(&bufOut, &bufErr, client); err == nil {
|
||||||
|
t.Errorf("RunListTokens() did not fail for a config without secrets: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test config without secrets but use a dummy API server that returns secrets
|
||||||
|
portString := "9008"
|
||||||
|
http.HandleFunc("/", httpHandler)
|
||||||
|
httpServer := &http.Server{Addr: "localhost:" + portString}
|
||||||
|
go func() {
|
||||||
|
err := httpServer.ListenAndServe()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to start dummy API server: localhost:%s", portString)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
fmt.Printf("dummy API server listening on localhost:%s\n", portString)
|
||||||
|
testConfigOpenPort := strings.Replace(TestConfig, "server: localhost:8000", "server: localhost:"+portString, -1)
|
||||||
|
|
||||||
|
if _, err = f.WriteString(testConfigOpenPort); err != nil {
|
||||||
|
t.Errorf("Unable to write test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err = getClientset(fullPath, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to run getClientset() for test file %q: %v", fullPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// the order of these tests should match the case check
|
||||||
|
// for httpTestItr in httpHandler
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "token-id not defined",
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "secret name not formatted correctly",
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "token-secret not defined",
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "token expiration not formatted correctly",
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "token expiration formatted correctly",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "token usage constant not true",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "token usage constant set to true",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
bufErr.Reset()
|
||||||
|
atomic.StoreUint32(&httpSentResponse, 0)
|
||||||
|
fmt.Printf("Running HTTP test case (%d) %q\n", atomic.LoadUint32(&httpTestItr), tc.name)
|
||||||
|
// should always return nil here if a valid list of secrets if fetched
|
||||||
|
err := RunListTokens(&bufOut, &bufErr, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("HTTP test case %d: Was unable to fetch a list of secrets", atomic.LoadUint32(&httpTestItr))
|
||||||
|
}
|
||||||
|
// wait for a response from the dummy HTTP server
|
||||||
|
timeSpent := 0 * time.Millisecond
|
||||||
|
timeToSleep := 50 * time.Millisecond
|
||||||
|
timeMax := 2000 * time.Millisecond
|
||||||
|
for {
|
||||||
|
if atomic.LoadUint32(&httpSentResponse) == 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if timeSpent >= timeMax {
|
||||||
|
t.Errorf("HTTP test case %d: The server did not respond within %d ms", atomic.LoadUint32(&httpTestItr), timeMax)
|
||||||
|
}
|
||||||
|
timeSpent += timeToSleep
|
||||||
|
time.Sleep(timeToSleep)
|
||||||
|
}
|
||||||
|
// check if an error is written in the error buffer
|
||||||
|
hasError := bufErr.Len() != 0
|
||||||
|
if hasError != tc.expectedError {
|
||||||
|
t.Errorf("HTTP test case %d: RunListTokens expected error: %v, saw: %v; %v", atomic.LoadUint32(&httpTestItr), tc.expectedError, hasError, bufErr.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only one of these should run at a time in a goroutine
|
||||||
|
func httpHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tokenID := []byte("07401b")
|
||||||
|
tokenSecret := []byte("f395accd246ae52d")
|
||||||
|
tokenExpire := []byte("2012-11-01T22:08:41+00:00")
|
||||||
|
badValue := "bad-value"
|
||||||
|
name := bootstrapapi.BootstrapTokenSecretPrefix + string(tokenID)
|
||||||
|
tokenUsageKey := bootstrapapi.BootstrapTokenUsagePrefix + "test"
|
||||||
|
|
||||||
|
secret := v1.Secret{}
|
||||||
|
secret.Type = bootstrapapi.SecretTypeBootstrapToken
|
||||||
|
secret.TypeMeta = metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"}
|
||||||
|
secret.Data = map[string][]byte{}
|
||||||
|
|
||||||
|
switch atomic.LoadUint32(&httpTestItr) {
|
||||||
|
case 0:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = []byte("")
|
||||||
|
case 1:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID
|
||||||
|
secret.ObjectMeta = metav1.ObjectMeta{Name: badValue}
|
||||||
|
case 2:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenSecretKey] = []byte("")
|
||||||
|
secret.ObjectMeta = metav1.ObjectMeta{Name: name}
|
||||||
|
case 3:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = []byte(badValue)
|
||||||
|
secret.ObjectMeta = metav1.ObjectMeta{Name: name}
|
||||||
|
case 4:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = tokenExpire
|
||||||
|
secret.ObjectMeta = metav1.ObjectMeta{Name: name}
|
||||||
|
case 5:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = tokenExpire
|
||||||
|
secret.Data[tokenUsageKey] = []byte("false")
|
||||||
|
secret.ObjectMeta = metav1.ObjectMeta{Name: name}
|
||||||
|
case 6:
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenIDKey] = tokenID
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenSecretKey] = tokenSecret
|
||||||
|
secret.Data[bootstrapapi.BootstrapTokenExpirationKey] = tokenExpire
|
||||||
|
secret.Data[tokenUsageKey] = []byte("true")
|
||||||
|
secret.ObjectMeta = metav1.ObjectMeta{Name: name}
|
||||||
|
}
|
||||||
|
|
||||||
|
secretList := v1.SecretList{}
|
||||||
|
secretList.Items = []v1.Secret{secret}
|
||||||
|
secretList.TypeMeta = metav1.TypeMeta{APIVersion: "v1", Kind: "SecretList"}
|
||||||
|
|
||||||
|
output, err := json.Marshal(secretList)
|
||||||
|
if err == nil {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
w.Write([]byte(output))
|
||||||
|
}
|
||||||
|
atomic.AddUint32(&httpTestItr, 1)
|
||||||
|
atomic.StoreUint32(&httpSentResponse, 1)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user