sigs.k8s.io/cluster-api@v1.7.1/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package upstreamv1beta1 18 19 import ( 20 "encoding/json" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 . "github.com/onsi/gomega" 25 "github.com/pkg/errors" 26 ) 27 28 func TestMarshalJSON(t *testing.T) { 29 var tests = []struct { 30 bts BootstrapTokenString 31 expected string 32 }{ 33 {BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, `"abcdef.abcdef0123456789"`}, 34 {BootstrapTokenString{ID: "foo", Secret: "bar"}, `"foo.bar"`}, 35 {BootstrapTokenString{ID: "h", Secret: "b"}, `"h.b"`}, 36 } 37 for _, rt := range tests { 38 t.Run(rt.bts.ID, func(t *testing.T) { 39 g := NewWithT(t) 40 41 b, err := json.Marshal(rt.bts) 42 g.Expect(err).ToNot(HaveOccurred()) 43 g.Expect(b).To(BeEquivalentTo(rt.expected)) 44 }) 45 } 46 } 47 48 func TestUnmarshalJSON(t *testing.T) { 49 var tests = []struct { 50 input string 51 bts *BootstrapTokenString 52 expectedError bool 53 }{ 54 {`"f.s"`, &BootstrapTokenString{}, true}, 55 {`"abcdef."`, &BootstrapTokenString{}, true}, 56 {`"abcdef:abcdef0123456789"`, &BootstrapTokenString{}, true}, 57 {`abcdef.abcdef0123456789`, &BootstrapTokenString{}, true}, 58 {`"abcdef.abcdef0123456789`, &BootstrapTokenString{}, true}, 59 {`"abcdef.ABCDEF0123456789"`, &BootstrapTokenString{}, true}, 60 {`"abcdef.abcdef0123456789"`, &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, false}, 61 {`"123456.aabbccddeeffgghh"`, &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}, false}, 62 } 63 for _, rt := range tests { 64 t.Run(rt.input, func(t *testing.T) { 65 g := NewWithT(t) 66 67 newbts := &BootstrapTokenString{} 68 err := json.Unmarshal([]byte(rt.input), newbts) 69 if rt.expectedError { 70 g.Expect(err).To(HaveOccurred()) 71 } else { 72 g.Expect(err).ToNot(HaveOccurred()) 73 } 74 g.Expect(newbts).To(Equal(rt.bts)) 75 }) 76 } 77 } 78 79 func TestJSONRoundtrip(t *testing.T) { 80 var tests = []struct { 81 input string 82 bts *BootstrapTokenString 83 }{ 84 {`"abcdef.abcdef0123456789"`, nil}, 85 {"", &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, 86 } 87 for _, rt := range tests { 88 t.Run(rt.input, func(t *testing.T) { 89 g := NewWithT(t) 90 91 g.Expect(roundtrip(rt.input, rt.bts)).To(Succeed()) 92 }) 93 } 94 } 95 96 func roundtrip(input string, bts *BootstrapTokenString) error { 97 var b []byte 98 var err error 99 newbts := &BootstrapTokenString{} 100 // If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string 101 if input != "" { 102 if err := json.Unmarshal([]byte(input), newbts); err != nil { 103 return errors.Wrap(err, "expected no unmarshal error, got error") 104 } 105 if b, err = json.Marshal(newbts); err != nil { 106 return errors.Wrap(err, "expected no marshal error, got error") 107 } 108 if input != string(b) { 109 return errors.Errorf( 110 "expected token: %s\n\t actual: %s", 111 input, 112 string(b), 113 ) 114 } 115 } else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object 116 if b, err = json.Marshal(bts); err != nil { 117 return errors.Wrap(err, "expected no marshal error, got error") 118 } 119 if err := json.Unmarshal(b, newbts); err != nil { 120 return errors.Wrap(err, "expected no unmarshal error, got error") 121 } 122 if diff := cmp.Diff(bts, newbts); diff != "" { 123 return errors.Errorf( 124 "expected object: %v\n\t actual: %v\n\t got diff: %v", 125 bts, 126 newbts, 127 diff, 128 ) 129 } 130 } 131 return nil 132 } 133 134 func TestTokenFromIDAndSecret(t *testing.T) { 135 var tests = []struct { 136 bts BootstrapTokenString 137 expected string 138 }{ 139 {BootstrapTokenString{ID: "foo", Secret: "bar"}, "foo.bar"}, 140 {BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, "abcdef.abcdef0123456789"}, 141 {BootstrapTokenString{ID: "h", Secret: "b"}, "h.b"}, 142 } 143 for _, rt := range tests { 144 t.Run(rt.bts.ID, func(t *testing.T) { 145 g := NewWithT(t) 146 147 g.Expect(rt.bts.String()).To(Equal(rt.expected)) 148 }) 149 } 150 } 151 152 func TestNewBootstrapTokenString(t *testing.T) { 153 var tests = []struct { 154 token string 155 expectedError bool 156 bts *BootstrapTokenString 157 }{ 158 {token: "", expectedError: true, bts: nil}, 159 {token: ".", expectedError: true, bts: nil}, 160 {token: "1234567890123456789012", expectedError: true, bts: nil}, // invalid parcel size 161 {token: "12345.1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 162 {token: ".1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 163 {token: "123456.", expectedError: true, bts: nil}, // invalid parcel size 164 {token: "123456:1234567890.123456", expectedError: true, bts: nil}, // invalid separation 165 {token: "abcdef:1234567890123456", expectedError: true, bts: nil}, // invalid separation 166 {token: "Abcdef.1234567890123456", expectedError: true, bts: nil}, // invalid token id 167 {token: "123456.AABBCCDDEEFFGGHH", expectedError: true, bts: nil}, // invalid token secret 168 {token: "123456.AABBCCD-EEFFGGHH", expectedError: true, bts: nil}, // invalid character 169 {token: "abc*ef.1234567890123456", expectedError: true, bts: nil}, // invalid character 170 {token: "abcdef.1234567890123456", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "1234567890123456"}}, 171 {token: "123456.aabbccddeeffgghh", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}}, 172 {token: "abcdef.abcdef0123456789", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, 173 {token: "123456.1234560123456789", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "1234560123456789"}}, 174 } 175 for _, rt := range tests { 176 t.Run(rt.token, func(t *testing.T) { 177 g := NewWithT(t) 178 179 actual, err := NewBootstrapTokenString(rt.token) 180 if rt.expectedError { 181 g.Expect(err).To(HaveOccurred()) 182 } else { 183 g.Expect(err).ToNot(HaveOccurred()) 184 } 185 g.Expect(actual).To(Equal(rt.bts)) 186 }) 187 } 188 } 189 190 func TestNewBootstrapTokenStringFromIDAndSecret(t *testing.T) { 191 var tests = []struct { 192 id, secret string 193 expectedError bool 194 bts *BootstrapTokenString 195 }{ 196 {id: "", secret: "", expectedError: true, bts: nil}, 197 {id: "1234567890123456789012", secret: "", expectedError: true, bts: nil}, // invalid parcel size 198 {id: "12345", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 199 {id: "", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 200 {id: "123456", secret: "", expectedError: true, bts: nil}, // invalid parcel size 201 {id: "Abcdef", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid token id 202 {id: "123456", secret: "AABBCCDDEEFFGGHH", expectedError: true, bts: nil}, // invalid token secret 203 {id: "123456", secret: "AABBCCD-EEFFGGHH", expectedError: true, bts: nil}, // invalid character 204 {id: "abc*ef", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid character 205 {id: "abcdef", secret: "1234567890123456", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "1234567890123456"}}, 206 {id: "123456", secret: "aabbccddeeffgghh", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}}, 207 {id: "abcdef", secret: "abcdef0123456789", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, 208 {id: "123456", secret: "1234560123456789", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "1234560123456789"}}, 209 } 210 for _, rt := range tests { 211 t.Run(rt.id, func(t *testing.T) { 212 g := NewWithT(t) 213 214 actual, err := NewBootstrapTokenStringFromIDAndSecret(rt.id, rt.secret) 215 if rt.expectedError { 216 g.Expect(err).To(HaveOccurred()) 217 } else { 218 g.Expect(err).ToNot(HaveOccurred()) 219 } 220 g.Expect(actual).To(Equal(rt.bts)) 221 }) 222 } 223 }