sigs.k8s.io/cluster-api/bootstrap/kubeadm@v0.0.0-20191016155141-23a891785b60/kubeadm/v1beta2/bootstraptokenstring_test.go (about) 1 /* 2 Copyright 2019 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 v1beta2 18 19 import ( 20 "encoding/json" 21 "reflect" 22 "testing" 23 24 "github.com/pkg/errors" 25 ) 26 27 func TestMarshalJSON(t *testing.T) { 28 var tests = []struct { 29 bts BootstrapTokenString 30 expected string 31 }{ 32 {BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, `"abcdef.abcdef0123456789"`}, 33 {BootstrapTokenString{ID: "foo", Secret: "bar"}, `"foo.bar"`}, 34 {BootstrapTokenString{ID: "h", Secret: "b"}, `"h.b"`}, 35 } 36 for _, rt := range tests { 37 t.Run(rt.bts.ID, func(t *testing.T) { 38 b, err := json.Marshal(rt.bts) 39 if err != nil { 40 t.Fatalf("json.Marshal returned an unexpected error: %v", err) 41 } 42 if string(b) != rt.expected { 43 t.Errorf( 44 "failed BootstrapTokenString.MarshalJSON:\n\texpected: %s\n\t actual: %s", 45 rt.expected, 46 string(b), 47 ) 48 } 49 }) 50 } 51 } 52 53 func TestUnmarshalJSON(t *testing.T) { 54 var tests = []struct { 55 input string 56 bts *BootstrapTokenString 57 expectedError bool 58 }{ 59 {`"f.s"`, &BootstrapTokenString{}, true}, 60 {`"abcdef."`, &BootstrapTokenString{}, true}, 61 {`"abcdef:abcdef0123456789"`, &BootstrapTokenString{}, true}, 62 {`abcdef.abcdef0123456789`, &BootstrapTokenString{}, true}, 63 {`"abcdef.abcdef0123456789`, &BootstrapTokenString{}, true}, 64 {`"abcdef.ABCDEF0123456789"`, &BootstrapTokenString{}, true}, 65 {`"abcdef.abcdef0123456789"`, &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, false}, 66 {`"123456.aabbccddeeffgghh"`, &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}, false}, 67 } 68 for _, rt := range tests { 69 t.Run(rt.input, func(t *testing.T) { 70 newbts := &BootstrapTokenString{} 71 err := json.Unmarshal([]byte(rt.input), newbts) 72 if (err != nil) != rt.expectedError { 73 t.Errorf("failed BootstrapTokenString.UnmarshalJSON:\n\texpected error: %t\n\t actual error: %v", rt.expectedError, err) 74 } else if !reflect.DeepEqual(rt.bts, newbts) { 75 t.Errorf( 76 "failed BootstrapTokenString.UnmarshalJSON:\n\texpected: %v\n\t actual: %v", 77 rt.bts, 78 newbts, 79 ) 80 } 81 }) 82 } 83 } 84 85 func TestJSONRoundtrip(t *testing.T) { 86 var tests = []struct { 87 input string 88 bts *BootstrapTokenString 89 }{ 90 {`"abcdef.abcdef0123456789"`, nil}, 91 {"", &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, 92 } 93 for _, rt := range tests { 94 t.Run(rt.input, func(t *testing.T) { 95 if err := roundtrip(rt.input, rt.bts); err != nil { 96 t.Errorf("failed BootstrapTokenString JSON roundtrip with error: %v", err) 97 } 98 }) 99 } 100 } 101 102 func roundtrip(input string, bts *BootstrapTokenString) error { 103 var b []byte 104 var err error 105 newbts := &BootstrapTokenString{} 106 // If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string 107 if len(input) > 0 { 108 if err := json.Unmarshal([]byte(input), newbts); err != nil { 109 return errors.Wrap(err, "expected no unmarshal error, got error") 110 } 111 if b, err = json.Marshal(newbts); err != nil { 112 return errors.Wrap(err, "expected no marshal error, got error") 113 } 114 if input != string(b) { 115 return errors.Errorf( 116 "expected token: %s\n\t actual: %s", 117 input, 118 string(b), 119 ) 120 } 121 } else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object 122 if b, err = json.Marshal(bts); err != nil { 123 return errors.Wrap(err, "expected no marshal error, got error") 124 } 125 if err := json.Unmarshal(b, newbts); err != nil { 126 return errors.Wrap(err, "expected no unmarshal error, got error") 127 } 128 if !reflect.DeepEqual(bts, newbts) { 129 return errors.Errorf( 130 "expected object: %v\n\t actual: %v", 131 bts, 132 newbts, 133 ) 134 } 135 } 136 return nil 137 } 138 139 func TestTokenFromIDAndSecret(t *testing.T) { 140 var tests = []struct { 141 bts BootstrapTokenString 142 expected string 143 }{ 144 {BootstrapTokenString{ID: "foo", Secret: "bar"}, "foo.bar"}, 145 {BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, "abcdef.abcdef0123456789"}, 146 {BootstrapTokenString{ID: "h", Secret: "b"}, "h.b"}, 147 } 148 for _, rt := range tests { 149 t.Run(rt.bts.ID, func(t *testing.T) { 150 actual := rt.bts.String() 151 if actual != rt.expected { 152 t.Errorf( 153 "failed BootstrapTokenString.String():\n\texpected: %s\n\t actual: %s", 154 rt.expected, 155 actual, 156 ) 157 } 158 }) 159 } 160 } 161 162 func TestNewBootstrapTokenString(t *testing.T) { 163 var tests = []struct { 164 token string 165 expectedError bool 166 bts *BootstrapTokenString 167 }{ 168 {token: "", expectedError: true, bts: nil}, 169 {token: ".", expectedError: true, bts: nil}, 170 {token: "1234567890123456789012", expectedError: true, bts: nil}, // invalid parcel size 171 {token: "12345.1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 172 {token: ".1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 173 {token: "123456.", expectedError: true, bts: nil}, // invalid parcel size 174 {token: "123456:1234567890.123456", expectedError: true, bts: nil}, // invalid separation 175 {token: "abcdef:1234567890123456", expectedError: true, bts: nil}, // invalid separation 176 {token: "Abcdef.1234567890123456", expectedError: true, bts: nil}, // invalid token id 177 {token: "123456.AABBCCDDEEFFGGHH", expectedError: true, bts: nil}, // invalid token secret 178 {token: "123456.AABBCCD-EEFFGGHH", expectedError: true, bts: nil}, // invalid character 179 {token: "abc*ef.1234567890123456", expectedError: true, bts: nil}, // invalid character 180 {token: "abcdef.1234567890123456", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "1234567890123456"}}, 181 {token: "123456.aabbccddeeffgghh", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}}, 182 {token: "abcdef.abcdef0123456789", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, 183 {token: "123456.1234560123456789", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "1234560123456789"}}, 184 } 185 for _, rt := range tests { 186 t.Run(rt.token, func(t *testing.T) { 187 actual, err := NewBootstrapTokenString(rt.token) 188 if (err != nil) != rt.expectedError { 189 t.Errorf( 190 "failed NewBootstrapTokenString for the token %q\n\texpected error: %t\n\t actual error: %v", 191 rt.token, 192 rt.expectedError, 193 err, 194 ) 195 } else if !reflect.DeepEqual(actual, rt.bts) { 196 t.Errorf( 197 "failed NewBootstrapTokenString for the token %q\n\texpected: %v\n\t actual: %v", 198 rt.token, 199 rt.bts, 200 actual, 201 ) 202 } 203 }) 204 } 205 } 206 207 func TestNewBootstrapTokenStringFromIDAndSecret(t *testing.T) { 208 var tests = []struct { 209 id, secret string 210 expectedError bool 211 bts *BootstrapTokenString 212 }{ 213 {id: "", secret: "", expectedError: true, bts: nil}, 214 {id: "1234567890123456789012", secret: "", expectedError: true, bts: nil}, // invalid parcel size 215 {id: "12345", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 216 {id: "", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid parcel size 217 {id: "123456", secret: "", expectedError: true, bts: nil}, // invalid parcel size 218 {id: "Abcdef", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid token id 219 {id: "123456", secret: "AABBCCDDEEFFGGHH", expectedError: true, bts: nil}, // invalid token secret 220 {id: "123456", secret: "AABBCCD-EEFFGGHH", expectedError: true, bts: nil}, // invalid character 221 {id: "abc*ef", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid character 222 {id: "abcdef", secret: "1234567890123456", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "1234567890123456"}}, 223 {id: "123456", secret: "aabbccddeeffgghh", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}}, 224 {id: "abcdef", secret: "abcdef0123456789", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, 225 {id: "123456", secret: "1234560123456789", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "1234560123456789"}}, 226 } 227 for _, rt := range tests { 228 t.Run(rt.id, func(t *testing.T) { 229 actual, err := NewBootstrapTokenStringFromIDAndSecret(rt.id, rt.secret) 230 if (err != nil) != rt.expectedError { 231 t.Errorf( 232 "failed NewBootstrapTokenStringFromIDAndSecret for the token with id %q and secret %q\n\texpected error: %t\n\t actual error: %v", 233 rt.id, 234 rt.secret, 235 rt.expectedError, 236 err, 237 ) 238 } else if !reflect.DeepEqual(actual, rt.bts) { 239 t.Errorf( 240 "failed NewBootstrapTokenStringFromIDAndSecret for the token with id %q and secret %q\n\texpected: %v\n\t actual: %v", 241 rt.id, 242 rt.secret, 243 rt.bts, 244 actual, 245 ) 246 } 247 }) 248 } 249 }