Skip to content

Commit 1fe922e

Browse files
authored
Merge pull request kubernetes#83369 from ereslibre/feature-gates-test
kubeadm: add test to detect panics when given certain feature gates
2 parents 144708b + cd1ad56 commit 1fe922e

File tree

6 files changed

+77
-28
lines changed

6 files changed

+77
-28
lines changed

cmd/kubeadm/test/cmd/completion_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestCmdCompletion(t *testing.T) {
3737

3838
for _, rt := range tests {
3939
t.Run(rt.name, func(t *testing.T) {
40-
_, _, actual := RunCmd(kubeadmPath, "completion", rt.args)
40+
_, _, _, actual := RunCmd(kubeadmPath, "completion", rt.args)
4141
if (actual == nil) != rt.expected {
4242
t.Errorf(
4343
"failed CmdCompletion running 'kubeadm completion %s' with an error: %v\n\texpected: %t\n\t actual: %t",

cmd/kubeadm/test/cmd/init_test.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
3030
)
3131

32-
func runKubeadmInit(args ...string) (string, string, error) {
32+
func runKubeadmInit(args ...string) (string, string, int, error) {
3333
kubeadmPath := getKubeadmPath()
3434
kubeadmArgs := []string{"init", "--dry-run", "--ignore-preflight-errors=all"}
3535
kubeadmArgs = append(kubeadmArgs, args...)
@@ -66,7 +66,7 @@ func TestCmdInitToken(t *testing.T) {
6666

6767
for _, rt := range initTest {
6868
t.Run(rt.name, func(t *testing.T) {
69-
_, _, err := runKubeadmInit(rt.args)
69+
_, _, _, err := runKubeadmInit(rt.args)
7070
if (err == nil) != rt.expected {
7171
t.Fatalf(dedent.Dedent(`
7272
CmdInitToken test case %q failed with an error: %v
@@ -110,7 +110,7 @@ func TestCmdInitKubernetesVersion(t *testing.T) {
110110

111111
for _, rt := range initTest {
112112
t.Run(rt.name, func(t *testing.T) {
113-
_, _, err := runKubeadmInit(rt.args)
113+
_, _, _, err := runKubeadmInit(rt.args)
114114
if (err == nil) != rt.expected {
115115
t.Fatalf(dedent.Dedent(`
116116
CmdInitKubernetesVersion test case %q failed with an error: %v
@@ -184,7 +184,7 @@ func TestCmdInitConfig(t *testing.T) {
184184

185185
for _, rt := range initTest {
186186
t.Run(rt.name, func(t *testing.T) {
187-
_, _, err := runKubeadmInit(rt.args)
187+
_, _, _, err := runKubeadmInit(rt.args)
188188
if (err == nil) != rt.expected {
189189
t.Fatalf(dedent.Dedent(`
190190
CmdInitConfig test case %q failed with an error: %v
@@ -235,7 +235,7 @@ func TestCmdInitCertPhaseCSR(t *testing.T) {
235235
csrDir := testutil.SetupTempDir(t)
236236
cert := &certs.KubeadmCertKubeletClient
237237
kubeadmPath := getKubeadmPath()
238-
_, stderr, err := RunCmd(kubeadmPath,
238+
_, stderr, _, err := RunCmd(kubeadmPath,
239239
"init",
240240
"phase",
241241
"certs",
@@ -303,7 +303,7 @@ func TestCmdInitAPIPort(t *testing.T) {
303303

304304
for _, rt := range initTest {
305305
t.Run(rt.name, func(t *testing.T) {
306-
_, _, err := runKubeadmInit(rt.args)
306+
_, _, _, err := runKubeadmInit(rt.args)
307307
if (err == nil) != rt.expected {
308308
t.Fatalf(dedent.Dedent(`
309309
CmdInitAPIPort test case %q failed with an error: %v
@@ -321,3 +321,52 @@ func TestCmdInitAPIPort(t *testing.T) {
321321
})
322322
}
323323
}
324+
325+
// TestCmdInitFeatureGates test that feature gates won't make kubeadm panic.
326+
// When go panics it will exit with a 2 code. While we don't expect the init
327+
// calls to succeed in these tests, we ensure that the exit code of calling
328+
// kubeadm with different feature gates is not 2.
329+
func TestCmdInitFeatureGates(t *testing.T) {
330+
const PanicExitcode = 2
331+
332+
if *kubeadmCmdSkip {
333+
t.Log("kubeadm cmd tests being skipped")
334+
t.Skip()
335+
}
336+
337+
initTest := []struct {
338+
name string
339+
args string
340+
}{
341+
{
342+
name: "no feature gates passed",
343+
args: "",
344+
},
345+
{
346+
name: "feature gate CoreDNS=true",
347+
args: "--feature-gates=CoreDNS=true",
348+
},
349+
{
350+
name: "feature gate IPv6DualStack=true",
351+
args: "--feature-gates=IPv6DualStack=true",
352+
},
353+
}
354+
355+
for _, rt := range initTest {
356+
t.Run(rt.name, func(t *testing.T) {
357+
_, _, exitcode, err := runKubeadmInit(rt.args)
358+
if exitcode == PanicExitcode {
359+
t.Fatalf(dedent.Dedent(`
360+
CmdInitFeatureGates test case %q failed with an error: %v
361+
command 'kubeadm init %s'
362+
got exit code: %t (panic); unexpected
363+
`),
364+
rt.name,
365+
err,
366+
rt.args,
367+
PanicExitcode,
368+
)
369+
}
370+
})
371+
}
372+
}

cmd/kubeadm/test/cmd/join_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import "testing"
2121
// kubeadmReset executes "kubeadm reset" and restarts kubelet.
2222
func kubeadmReset() error {
2323
kubeadmPath := getKubeadmPath()
24-
_, _, err := RunCmd(kubeadmPath, "reset")
24+
_, _, _, err := RunCmd(kubeadmPath, "reset")
2525
return err
2626
}
2727

@@ -43,7 +43,7 @@ func TestCmdJoinConfig(t *testing.T) {
4343
kubeadmPath := getKubeadmPath()
4444
for _, rt := range initTest {
4545
t.Run(rt.name, func(t *testing.T) {
46-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
46+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
4747
if (actual == nil) != rt.expected {
4848
t.Errorf(
4949
"failed CmdJoinConfig running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -76,7 +76,7 @@ func TestCmdJoinDiscoveryFile(t *testing.T) {
7676
kubeadmPath := getKubeadmPath()
7777
for _, rt := range initTest {
7878
t.Run(rt.name, func(t *testing.T) {
79-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
79+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
8080
if (actual == nil) != rt.expected {
8181
t.Errorf(
8282
"failed CmdJoinDiscoveryFile running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -109,7 +109,7 @@ func TestCmdJoinDiscoveryToken(t *testing.T) {
109109
kubeadmPath := getKubeadmPath()
110110
for _, rt := range initTest {
111111
t.Run(rt.name, func(t *testing.T) {
112-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
112+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
113113
if (actual == nil) != rt.expected {
114114
t.Errorf(
115115
"failed CmdJoinDiscoveryToken running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -141,7 +141,7 @@ func TestCmdJoinNodeName(t *testing.T) {
141141
kubeadmPath := getKubeadmPath()
142142
for _, rt := range initTest {
143143
t.Run(rt.name, func(t *testing.T) {
144-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
144+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
145145
if (actual == nil) != rt.expected {
146146
t.Errorf(
147147
"failed CmdJoinNodeName running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -174,7 +174,7 @@ func TestCmdJoinTLSBootstrapToken(t *testing.T) {
174174
kubeadmPath := getKubeadmPath()
175175
for _, rt := range initTest {
176176
t.Run(rt.name, func(t *testing.T) {
177-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
177+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
178178
if (actual == nil) != rt.expected {
179179
t.Errorf(
180180
"failed CmdJoinTLSBootstrapToken running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -207,7 +207,7 @@ func TestCmdJoinToken(t *testing.T) {
207207
kubeadmPath := getKubeadmPath()
208208
for _, rt := range initTest {
209209
t.Run(rt.name, func(t *testing.T) {
210-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
210+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
211211
if (actual == nil) != rt.expected {
212212
t.Errorf(
213213
"failed CmdJoinToken running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -240,7 +240,7 @@ func TestCmdJoinBadArgs(t *testing.T) {
240240

241241
for _, rt := range initTest {
242242
t.Run(rt.name, func(t *testing.T) {
243-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
243+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
244244
if (actual == nil) != rt.expected {
245245
t.Errorf(
246246
"failed CmdJoinBadArgs 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -272,7 +272,7 @@ func TestCmdJoinArgsMixed(t *testing.T) {
272272
kubeadmPath := getKubeadmPath()
273273
for _, rt := range initTest {
274274
t.Run(rt.name, func(t *testing.T) {
275-
_, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
275+
_, _, _, actual := RunCmd(kubeadmPath, "join", rt.args, "--ignore-preflight-errors=all")
276276
if (actual == nil) != rt.expected {
277277
t.Errorf(
278278
"failed CmdJoinArgsMixed running 'kubeadm join %s' with an error: %v\n\texpected: %t\n\t actual: %t",

cmd/kubeadm/test/cmd/token_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func TestCmdTokenGenerate(t *testing.T) {
4848
t.Log("kubeadm cmd tests being skipped")
4949
t.Skip()
5050
}
51-
stdout, _, err := RunCmd(kubeadmPath, "token", "generate")
51+
stdout, _, _, err := RunCmd(kubeadmPath, "token", "generate")
5252
if err != nil {
5353
t.Fatalf("'kubeadm token generate' exited uncleanly: %v", err)
5454
}
@@ -78,7 +78,7 @@ func TestCmdTokenGenerateTypoError(t *testing.T) {
7878
}
7979

8080
kubeadmPath := getKubeadmPath()
81-
_, _, err := RunCmd(kubeadmPath, "token", "genorate") // subtle typo
81+
_, _, _, err := RunCmd(kubeadmPath, "token", "genorate") // subtle typo
8282
if err == nil {
8383
t.Error("'kubeadm token genorate' (a deliberate typo) exited without an error when we expected non-zero exit status")
8484
}
@@ -101,7 +101,7 @@ func TestCmdTokenDelete(t *testing.T) {
101101
kubeadmPath := getKubeadmPath()
102102
for _, rt := range tests {
103103
t.Run(rt.name, func(t *testing.T) {
104-
_, _, actual := RunCmd(kubeadmPath, "token", "delete", rt.args)
104+
_, _, _, actual := RunCmd(kubeadmPath, "token", "delete", rt.args)
105105
if (actual == nil) != rt.expected {
106106
t.Errorf(
107107
"failed CmdTokenDelete running 'kubeadm token %s' with an error: %v\n\texpected: %t\n\t actual: %t",

cmd/kubeadm/test/cmd/util.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,24 @@ import (
2929
// Forked from test/e2e/framework because the e2e framework is quite bloated
3030
// for our purposes here, and modified to remove undesired logging.
3131

32-
func runCmdNoWrap(command string, args ...string) (string, string, error) {
32+
func runCmdNoWrap(command string, args ...string) (string, string, int, error) {
3333
var bout, berr bytes.Buffer
3434
cmd := exec.Command(command, args...)
3535
cmd.Stdout = &bout
3636
cmd.Stderr = &berr
3737
err := cmd.Run()
3838
stdout, stderr := bout.String(), berr.String()
39-
return stdout, stderr, err
39+
return stdout, stderr, cmd.ProcessState.ExitCode(), err
4040
}
4141

4242
// RunCmd is a utility function for kubeadm testing that executes a specified command
43-
func RunCmd(command string, args ...string) (string, string, error) {
44-
stdout, stderr, err := runCmdNoWrap(command, args...)
43+
func RunCmd(command string, args ...string) (string, string, int, error) {
44+
stdout, stderr, retcode, err := runCmdNoWrap(command, args...)
4545
if err != nil {
46-
return stdout, stderr, errors.Wrapf(err, "error running %s %v; \nstdout %q, \nstderr %q, \ngot error",
47-
command, args, stdout, stderr)
46+
return stdout, stderr, retcode, errors.Wrapf(err, "error running %s %v; \nretcode %d, \nstdout %q, \nstderr %q, \ngot error",
47+
command, args, retcode, stdout, stderr)
4848
}
49-
return stdout, stderr, nil
49+
return stdout, stderr, retcode, nil
5050
}
5151

5252
// RunSubCommand is a utility function for kubeadm testing that executes a Cobra sub command

cmd/kubeadm/test/cmd/version_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func TestCmdVersion(t *testing.T) {
5353
kubeadmPath := getKubeadmPath()
5454
for _, rt := range versionTest {
5555
t.Run(rt.name, func(t *testing.T) {
56-
stdout, _, actual := RunCmd(kubeadmPath, "version", rt.args)
56+
stdout, _, _, actual := RunCmd(kubeadmPath, "version", rt.args)
5757
if (actual == nil) != rt.expected {
5858
t.Errorf(
5959
"failed CmdVersion running 'kubeadm version %s' with an error: %v\n\texpected: %t\n\t actual: %t",
@@ -96,7 +96,7 @@ func TestCmdVersionOutputJsonOrYaml(t *testing.T) {
9696
kubeadmPath := getKubeadmPath()
9797
for _, rt := range versionTest {
9898
t.Run(rt.name, func(t *testing.T) {
99-
stdout, _, actual := RunCmd(kubeadmPath, "version", rt.args)
99+
stdout, _, _, actual := RunCmd(kubeadmPath, "version", rt.args)
100100
if (actual == nil) != rt.expected {
101101
t.Errorf(
102102
"failed CmdVersion running 'kubeadm version %s' with an error: %v\n\texpected: %t\n\t actual: %t",

0 commit comments

Comments
 (0)