github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/addrs/provider_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package addrs 5 6 import ( 7 "testing" 8 9 "github.com/go-test/deep" 10 svchost "github.com/hashicorp/terraform-svchost" 11 ) 12 13 func TestProviderString(t *testing.T) { 14 tests := []struct { 15 Input Provider 16 Want string 17 }{ 18 { 19 Provider{ 20 Type: "test", 21 Hostname: DefaultProviderRegistryHost, 22 Namespace: "hashicorp", 23 }, 24 NewDefaultProvider("test").String(), 25 }, 26 { 27 Provider{ 28 Type: "test-beta", 29 Hostname: DefaultProviderRegistryHost, 30 Namespace: "hashicorp", 31 }, 32 NewDefaultProvider("test-beta").String(), 33 }, 34 { 35 Provider{ 36 Type: "test", 37 Hostname: "registry.terraform.com", 38 Namespace: "hashicorp", 39 }, 40 "registry.terraform.com/hashicorp/test", 41 }, 42 { 43 Provider{ 44 Type: "test", 45 Hostname: DefaultProviderRegistryHost, 46 Namespace: "othercorp", 47 }, 48 DefaultProviderRegistryHost.ForDisplay() + "/othercorp/test", 49 }, 50 } 51 52 for _, test := range tests { 53 got := test.Input.String() 54 if got != test.Want { 55 t.Errorf("wrong result for %s\n", test.Input.String()) 56 } 57 } 58 } 59 60 func TestProviderLegacyString(t *testing.T) { 61 tests := []struct { 62 Input Provider 63 Want string 64 }{ 65 { 66 Provider{ 67 Type: "test", 68 Hostname: DefaultProviderRegistryHost, 69 Namespace: LegacyProviderNamespace, 70 }, 71 "test", 72 }, 73 { 74 Provider{ 75 Type: "terraform", 76 Hostname: BuiltInProviderHost, 77 Namespace: BuiltInProviderNamespace, 78 }, 79 "terraform", 80 }, 81 } 82 83 for _, test := range tests { 84 got := test.Input.LegacyString() 85 if got != test.Want { 86 t.Errorf("wrong result for %s\ngot: %s\nwant: %s", test.Input.String(), got, test.Want) 87 } 88 } 89 } 90 91 func TestProviderDisplay(t *testing.T) { 92 tests := []struct { 93 Input Provider 94 Want string 95 }{ 96 { 97 Provider{ 98 Type: "test", 99 Hostname: DefaultProviderRegistryHost, 100 Namespace: "hashicorp", 101 }, 102 "hashicorp/test", 103 }, 104 { 105 Provider{ 106 Type: "test", 107 Hostname: "registry.terraform.com", 108 Namespace: "hashicorp", 109 }, 110 "registry.terraform.com/hashicorp/test", 111 }, 112 { 113 Provider{ 114 Type: "test", 115 Hostname: DefaultProviderRegistryHost, 116 Namespace: "othercorp", 117 }, 118 "othercorp/test", 119 }, 120 } 121 122 for _, test := range tests { 123 got := test.Input.ForDisplay() 124 if got != test.Want { 125 t.Errorf("wrong result for %s\n", test.Input.String()) 126 } 127 } 128 } 129 130 func TestProviderIsDefaultProvider(t *testing.T) { 131 tests := []struct { 132 Input Provider 133 Want bool 134 }{ 135 { 136 Provider{ 137 Type: "test", 138 Hostname: DefaultProviderRegistryHost, 139 Namespace: "hashicorp", 140 }, 141 true, 142 }, 143 { 144 Provider{ 145 Type: "test", 146 Hostname: "registry.terraform.com", 147 Namespace: "hashicorp", 148 }, 149 false, 150 }, 151 { 152 Provider{ 153 Type: "test", 154 Hostname: DefaultProviderRegistryHost, 155 Namespace: "othercorp", 156 }, 157 false, 158 }, 159 } 160 161 for _, test := range tests { 162 got := IsDefaultProvider(test.Input) 163 if got != test.Want { 164 t.Errorf("wrong result for %s\n", test.Input.String()) 165 } 166 } 167 } 168 169 func TestProviderIsBuiltIn(t *testing.T) { 170 tests := []struct { 171 Input Provider 172 Want bool 173 }{ 174 { 175 Provider{ 176 Type: "test", 177 Hostname: BuiltInProviderHost, 178 Namespace: BuiltInProviderNamespace, 179 }, 180 true, 181 }, 182 { 183 Provider{ 184 Type: "terraform", 185 Hostname: BuiltInProviderHost, 186 Namespace: BuiltInProviderNamespace, 187 }, 188 true, 189 }, 190 { 191 Provider{ 192 Type: "test", 193 Hostname: BuiltInProviderHost, 194 Namespace: "boop", 195 }, 196 false, 197 }, 198 { 199 Provider{ 200 Type: "test", 201 Hostname: DefaultProviderRegistryHost, 202 Namespace: BuiltInProviderNamespace, 203 }, 204 false, 205 }, 206 { 207 Provider{ 208 Type: "test", 209 Hostname: DefaultProviderRegistryHost, 210 Namespace: "hashicorp", 211 }, 212 false, 213 }, 214 { 215 Provider{ 216 Type: "test", 217 Hostname: "registry.terraform.com", 218 Namespace: "hashicorp", 219 }, 220 false, 221 }, 222 { 223 Provider{ 224 Type: "test", 225 Hostname: DefaultProviderRegistryHost, 226 Namespace: "othercorp", 227 }, 228 false, 229 }, 230 } 231 232 for _, test := range tests { 233 got := test.Input.IsBuiltIn() 234 if got != test.Want { 235 t.Errorf("wrong result for %s\ngot: %#v\nwant: %#v", test.Input.String(), got, test.Want) 236 } 237 } 238 } 239 240 func TestProviderIsLegacy(t *testing.T) { 241 tests := []struct { 242 Input Provider 243 Want bool 244 }{ 245 { 246 Provider{ 247 Type: "test", 248 Hostname: DefaultProviderRegistryHost, 249 Namespace: LegacyProviderNamespace, 250 }, 251 true, 252 }, 253 { 254 Provider{ 255 Type: "test", 256 Hostname: "registry.terraform.com", 257 Namespace: LegacyProviderNamespace, 258 }, 259 false, 260 }, 261 { 262 Provider{ 263 Type: "test", 264 Hostname: DefaultProviderRegistryHost, 265 Namespace: "hashicorp", 266 }, 267 false, 268 }, 269 } 270 271 for _, test := range tests { 272 got := test.Input.IsLegacy() 273 if got != test.Want { 274 t.Errorf("wrong result for %s\n", test.Input.String()) 275 } 276 } 277 } 278 279 func TestParseProviderSourceStr(t *testing.T) { 280 tests := map[string]struct { 281 Want Provider 282 Err bool 283 }{ 284 "registry.terraform.io/hashicorp/aws": { 285 Provider{ 286 Type: "aws", 287 Namespace: "hashicorp", 288 Hostname: DefaultProviderRegistryHost, 289 }, 290 false, 291 }, 292 "registry.Terraform.io/HashiCorp/AWS": { 293 Provider{ 294 Type: "aws", 295 Namespace: "hashicorp", 296 Hostname: DefaultProviderRegistryHost, 297 }, 298 false, 299 }, 300 "hashicorp/aws": { 301 Provider{ 302 Type: "aws", 303 Namespace: "hashicorp", 304 Hostname: DefaultProviderRegistryHost, 305 }, 306 false, 307 }, 308 "HashiCorp/AWS": { 309 Provider{ 310 Type: "aws", 311 Namespace: "hashicorp", 312 Hostname: DefaultProviderRegistryHost, 313 }, 314 false, 315 }, 316 "aws": { 317 Provider{ 318 Type: "aws", 319 Namespace: "hashicorp", 320 Hostname: DefaultProviderRegistryHost, 321 }, 322 false, 323 }, 324 "AWS": { 325 Provider{ 326 Type: "aws", 327 Namespace: "hashicorp", 328 Hostname: DefaultProviderRegistryHost, 329 }, 330 false, 331 }, 332 "example.com/foo-bar/baz-boop": { 333 Provider{ 334 Type: "baz-boop", 335 Namespace: "foo-bar", 336 Hostname: svchost.Hostname("example.com"), 337 }, 338 false, 339 }, 340 "foo-bar/baz-boop": { 341 Provider{ 342 Type: "baz-boop", 343 Namespace: "foo-bar", 344 Hostname: DefaultProviderRegistryHost, 345 }, 346 false, 347 }, 348 "localhost:8080/foo/bar": { 349 Provider{ 350 Type: "bar", 351 Namespace: "foo", 352 Hostname: svchost.Hostname("localhost:8080"), 353 }, 354 false, 355 }, 356 "example.com/too/many/parts/here": { 357 Provider{}, 358 true, 359 }, 360 "/too///many//slashes": { 361 Provider{}, 362 true, 363 }, 364 "///": { 365 Provider{}, 366 true, 367 }, 368 "/ / /": { // empty strings 369 Provider{}, 370 true, 371 }, 372 "badhost!/hashicorp/aws": { 373 Provider{}, 374 true, 375 }, 376 "example.com/badnamespace!/aws": { 377 Provider{}, 378 true, 379 }, 380 "example.com/bad--namespace/aws": { 381 Provider{}, 382 true, 383 }, 384 "example.com/-badnamespace/aws": { 385 Provider{}, 386 true, 387 }, 388 "example.com/badnamespace-/aws": { 389 Provider{}, 390 true, 391 }, 392 "example.com/bad.namespace/aws": { 393 Provider{}, 394 true, 395 }, 396 "example.com/hashicorp/badtype!": { 397 Provider{}, 398 true, 399 }, 400 "example.com/hashicorp/bad--type": { 401 Provider{}, 402 true, 403 }, 404 "example.com/hashicorp/-badtype": { 405 Provider{}, 406 true, 407 }, 408 "example.com/hashicorp/badtype-": { 409 Provider{}, 410 true, 411 }, 412 "example.com/hashicorp/bad.type": { 413 Provider{}, 414 true, 415 }, 416 417 // We forbid the terraform- prefix both because it's redundant to 418 // include "terraform" in a Terraform provider name and because we use 419 // the longer prefix terraform-provider- to hint for users who might be 420 // accidentally using the git repository name or executable file name 421 // instead of the provider type. 422 "example.com/hashicorp/terraform-provider-bad": { 423 Provider{}, 424 true, 425 }, 426 "example.com/hashicorp/terraform-bad": { 427 Provider{}, 428 true, 429 }, 430 } 431 432 for name, test := range tests { 433 got, diags := ParseProviderSourceString(name) 434 for _, problem := range deep.Equal(got, test.Want) { 435 t.Errorf(problem) 436 } 437 if len(diags) > 0 { 438 if test.Err == false { 439 t.Errorf("got error, expected success") 440 } 441 } else { 442 if test.Err { 443 t.Errorf("got success, expected error") 444 } 445 } 446 } 447 } 448 449 func TestParseProviderPart(t *testing.T) { 450 tests := map[string]struct { 451 Want string 452 Error string 453 }{ 454 `foo`: { 455 `foo`, 456 ``, 457 }, 458 `FOO`: { 459 `foo`, 460 ``, 461 }, 462 `Foo`: { 463 `foo`, 464 ``, 465 }, 466 `abc-123`: { 467 `abc-123`, 468 ``, 469 }, 470 `Испытание`: { 471 `испытание`, 472 ``, 473 }, 474 `münchen`: { // this is a precomposed u with diaeresis 475 `münchen`, // this is a precomposed u with diaeresis 476 ``, 477 }, 478 `münchen`: { // this is a separate u and combining diaeresis 479 `münchen`, // this is a precomposed u with diaeresis 480 ``, 481 }, 482 `abc--123`: { 483 ``, 484 `cannot use multiple consecutive dashes`, 485 }, 486 `xn--80akhbyknj4f`: { // this is the punycode form of "испытание", but we don't accept punycode here 487 ``, 488 `cannot use multiple consecutive dashes`, 489 }, 490 `abc.123`: { 491 ``, 492 `dots are not allowed`, 493 }, 494 `-abc123`: { 495 ``, 496 `must contain only letters, digits, and dashes, and may not use leading or trailing dashes`, 497 }, 498 `abc123-`: { 499 ``, 500 `must contain only letters, digits, and dashes, and may not use leading or trailing dashes`, 501 }, 502 ``: { 503 ``, 504 `must have at least one character`, 505 }, 506 } 507 508 for given, test := range tests { 509 t.Run(given, func(t *testing.T) { 510 got, err := ParseProviderPart(given) 511 if test.Error != "" { 512 if err == nil { 513 t.Errorf("unexpected success\ngot: %s\nwant: %s", err, test.Error) 514 } else if got := err.Error(); got != test.Error { 515 t.Errorf("wrong error\ngot: %s\nwant: %s", got, test.Error) 516 } 517 } else { 518 if err != nil { 519 t.Errorf("unexpected error\ngot: %s\nwant: <nil>", err) 520 } else if got != test.Want { 521 t.Errorf("wrong result\ngot: %s\nwant: %s", got, test.Want) 522 } 523 } 524 }) 525 } 526 } 527 528 func TestProviderEquals(t *testing.T) { 529 tests := []struct { 530 InputP Provider 531 OtherP Provider 532 Want bool 533 }{ 534 { 535 NewProvider(DefaultProviderRegistryHost, "foo", "test"), 536 NewProvider(DefaultProviderRegistryHost, "foo", "test"), 537 true, 538 }, 539 { 540 NewProvider(DefaultProviderRegistryHost, "foo", "test"), 541 NewProvider(DefaultProviderRegistryHost, "bar", "test"), 542 false, 543 }, 544 { 545 NewProvider(DefaultProviderRegistryHost, "foo", "test"), 546 NewProvider(DefaultProviderRegistryHost, "foo", "my-test"), 547 false, 548 }, 549 { 550 NewProvider(DefaultProviderRegistryHost, "foo", "test"), 551 NewProvider("example.com", "foo", "test"), 552 false, 553 }, 554 } 555 for _, test := range tests { 556 t.Run(test.InputP.String(), func(t *testing.T) { 557 got := test.InputP.Equals(test.OtherP) 558 if got != test.Want { 559 t.Errorf("wrong result\ngot: %v\nwant: %v", got, test.Want) 560 } 561 }) 562 } 563 }