1
16
17 package genericclioptions
18
19 import (
20 "net/http"
21 "testing"
22
23 "github.com/spf13/cobra"
24 )
25
26 var kubectlCmd = &cobra.Command{Use: "kubectl"}
27 var applyCmd = &cobra.Command{Use: "apply"}
28 var createCmd = &cobra.Command{Use: "create"}
29 var secretCmd = &cobra.Command{Use: "secret"}
30 var genericCmd = &cobra.Command{Use: "generic"}
31 var authCmd = &cobra.Command{Use: "auth"}
32 var reconcileCmd = &cobra.Command{Use: "reconcile"}
33
34 func TestParseCommandHeaders(t *testing.T) {
35 tests := map[string]struct {
36
37
38 commands []*cobra.Command
39
40 expectedHeaders map[string]string
41 }{
42 "Single kubectl command example": {
43 commands: []*cobra.Command{kubectlCmd},
44 expectedHeaders: map[string]string{
45 kubectlCommandHeader: "kubectl",
46 },
47 },
48 "Simple kubectl apply example": {
49 commands: []*cobra.Command{kubectlCmd, applyCmd},
50 expectedHeaders: map[string]string{
51 kubectlCommandHeader: "kubectl apply",
52 },
53 },
54 "Kubectl auth reconcile example": {
55 commands: []*cobra.Command{kubectlCmd, authCmd, reconcileCmd},
56 expectedHeaders: map[string]string{
57 kubectlCommandHeader: "kubectl auth reconcile",
58 },
59 },
60 "Long kubectl create secret generic example": {
61 commands: []*cobra.Command{kubectlCmd, createCmd, secretCmd, genericCmd},
62 expectedHeaders: map[string]string{
63 kubectlCommandHeader: "kubectl create secret generic",
64 },
65 },
66 }
67
68 for name, tc := range tests {
69 t.Run(name, func(t *testing.T) {
70 rootCmd := buildCommandChain(tc.commands)
71 ch := &CommandHeaderRoundTripper{}
72 ch.ParseCommandHeaders(rootCmd, []string{})
73
74 if _, found := ch.Headers[kubectlSessionHeader]; !found {
75 t.Errorf("expected kubectl session header (%s) is missing", kubectlSessionHeader)
76 }
77
78 for key, expectedValue := range tc.expectedHeaders {
79 actualValue, found := ch.Headers[key]
80 if found {
81 if expectedValue != actualValue {
82 t.Errorf("expected header value (%s), got (%s)", expectedValue, actualValue)
83 }
84 } else {
85 t.Errorf("expected header (%s) not found", key)
86 }
87 }
88 })
89 }
90 }
91
92
93
94
95 func buildCommandChain(commands []*cobra.Command) *cobra.Command {
96 var currCmd *cobra.Command
97 if len(commands) > 0 {
98 currCmd = commands[0]
99 }
100 for i := 1; i < len(commands); i++ {
101 cmd := commands[i]
102 currCmd.AddCommand(cmd)
103 currCmd = cmd
104 }
105 return currCmd
106 }
107
108
109
110 func TestCancelRequest(t *testing.T) {
111 tests := map[string]struct {
112 delegate http.RoundTripper
113 cancelled bool
114 }{
115 "CancelRequest propagated to delegate": {
116 delegate: &cancellableRoundTripper{},
117 cancelled: true,
118 },
119 "CancelRequest not propagated to delegate": {
120 delegate: &nonCancellableRoundTripper{},
121 cancelled: false,
122 },
123 }
124
125 for name, tc := range tests {
126 t.Run(name, func(t *testing.T) {
127 rt := &CommandHeaderRoundTripper{
128 Delegate: tc.delegate,
129 }
130 req := http.Request{}
131 rt.CancelRequest(&req)
132 if tc.cancelled != req.Close {
133 t.Errorf("expected RoundTripper cancel (%v), got (%v)", tc.cancelled, req.Close)
134 }
135 })
136 }
137 }
138
139
140 type cancellableRoundTripper struct{}
141
142 func (rtc *cancellableRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
143 return nil, nil
144 }
145
146 func (rtc *cancellableRoundTripper) CancelRequest(req *http.Request) {
147 req.Close = true
148 }
149
150
151 type nonCancellableRoundTripper struct{}
152
153 func (rtc *nonCancellableRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
154 return nil, nil
155 }
156
View as plain text