github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/internal/getproviders/registry_source_test.go (about)

     1  package getproviders
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/apparentlymart/go-versions/versions"
    10  	"github.com/google/go-cmp/cmp"
    11  	svchost "github.com/hashicorp/terraform-svchost"
    12  
    13  	"github.com/hashicorp/terraform/addrs"
    14  )
    15  
    16  func TestSourceAvailableVersions(t *testing.T) {
    17  	source, baseURL, close := testRegistrySource(t)
    18  	defer close()
    19  
    20  	tests := []struct {
    21  		provider     string
    22  		wantVersions []string
    23  		wantErr      string
    24  	}{
    25  		// These test cases are relying on behaviors of the fake provider
    26  		// registry server implemented in client_test.go.
    27  		{
    28  			"example.com/awesomesauce/happycloud",
    29  			[]string{"1.0.0", "1.2.0"},
    30  			``,
    31  		},
    32  		{
    33  			"example.com/weaksauce/no-versions",
    34  			nil,
    35  			``, // having no versions is not an error, it's just odd
    36  		},
    37  		{
    38  			"example.com/nonexist/nonexist",
    39  			nil,
    40  			`provider registry example.com does not have a provider named example.com/nonexist/nonexist`,
    41  		},
    42  		{
    43  			"not.example.com/foo/bar",
    44  			nil,
    45  			`host not.example.com does not offer a Terraform provider registry`,
    46  		},
    47  		{
    48  			"too-new.example.com/foo/bar",
    49  			nil,
    50  			`host too-new.example.com does not support the provider registry protocol required by this Terraform version, but may be compatible with a different Terraform version`,
    51  		},
    52  		{
    53  			"fails.example.com/foo/bar",
    54  			nil,
    55  			`could not query provider registry for fails.example.com/foo/bar: Get ` + baseURL + `/fails-immediately/foo/bar/versions: EOF`,
    56  		},
    57  	}
    58  
    59  	for _, test := range tests {
    60  		t.Run(test.provider, func(t *testing.T) {
    61  			// TEMP: We don't yet have a function for parsing provider
    62  			// source addresses so we'll just fake it in here for now.
    63  			parts := strings.Split(test.provider, "/")
    64  			providerAddr := addrs.Provider{
    65  				Hostname:  svchost.Hostname(parts[0]),
    66  				Namespace: parts[1],
    67  				Type:      parts[2],
    68  			}
    69  
    70  			gotVersions, err := source.AvailableVersions(providerAddr)
    71  
    72  			if err != nil {
    73  				if test.wantErr == "" {
    74  					t.Fatalf("wrong error\ngot:  %s\nwant: <nil>", err.Error())
    75  				}
    76  				if got, want := err.Error(), test.wantErr; got != want {
    77  					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
    78  				}
    79  				return
    80  			}
    81  
    82  			if test.wantErr != "" {
    83  				t.Fatalf("wrong error\ngot:  <nil>\nwant: %s", test.wantErr)
    84  			}
    85  
    86  			var gotVersionsStr []string
    87  			if gotVersions != nil {
    88  				gotVersionsStr = make([]string, len(gotVersions))
    89  				for i, v := range gotVersions {
    90  					gotVersionsStr[i] = v.String()
    91  				}
    92  			}
    93  
    94  			if diff := cmp.Diff(test.wantVersions, gotVersionsStr); diff != "" {
    95  				t.Errorf("wrong result\n%s", diff)
    96  			}
    97  		})
    98  	}
    99  
   100  }
   101  
   102  func TestSourcePackageMeta(t *testing.T) {
   103  	source, baseURL, close := testRegistrySource(t)
   104  	defer close()
   105  
   106  	tests := []struct {
   107  		provider string
   108  		version  string
   109  		os, arch string
   110  		want     PackageMeta
   111  		wantErr  string
   112  	}{
   113  		// These test cases are relying on behaviors of the fake provider
   114  		// registry server implemented in client_test.go.
   115  		{
   116  			"example.com/awesomesauce/happycloud",
   117  			"1.2.0",
   118  			"linux", "amd64",
   119  			PackageMeta{
   120  				ProtocolVersions: VersionList{versions.MustParseVersion("5.0.0")},
   121  				TargetPlatform:   Platform{"linux", "amd64"},
   122  				Filename:         "happycloud_1.2.0.zip",
   123  				Location:         PackageHTTPURL(baseURL + "/pkg/happycloud_1.2.0.zip"),
   124  				SHA256Sum:        [32]uint8{30: 0xf0, 31: 0x0d}, // fake registry uses a memorable sum
   125  			},
   126  			``,
   127  		},
   128  		{
   129  			"example.com/awesomesauce/happycloud",
   130  			"1.2.0",
   131  			"nonexist", "amd64",
   132  			PackageMeta{},
   133  			`provider example.com/awesomesauce/happycloud 1.2.0 is not available for nonexist_amd64`,
   134  		},
   135  		{
   136  			"not.example.com/awesomesauce/happycloud",
   137  			"1.2.0",
   138  			"linux", "amd64",
   139  			PackageMeta{},
   140  			`host not.example.com does not offer a Terraform provider registry`,
   141  		},
   142  		{
   143  			"too-new.example.com/awesomesauce/happycloud",
   144  			"1.2.0",
   145  			"linux", "amd64",
   146  			PackageMeta{},
   147  			`host too-new.example.com does not support the provider registry protocol required by this Terraform version, but may be compatible with a different Terraform version`,
   148  		},
   149  		{
   150  			"fails.example.com/awesomesauce/happycloud",
   151  			"1.2.0",
   152  			"linux", "amd64",
   153  			PackageMeta{},
   154  			`could not query provider registry for fails.example.com/awesomesauce/happycloud: Get http://placeholder-origin/fails-immediately/awesomesauce/happycloud/1.2.0/download/linux/amd64: EOF`,
   155  		},
   156  	}
   157  
   158  	// Sometimes error messages contain specific HTTP endpoint URLs, but
   159  	// since our test server is on a random port we'd not be able to
   160  	// consistently match those. Instead, we'll normalize the URLs.
   161  	urlPattern := regexp.MustCompile(`http://[^/]+/`)
   162  
   163  	cmpOpts := cmp.Comparer(Version.Same)
   164  
   165  	for _, test := range tests {
   166  		t.Run(fmt.Sprintf("%s for %s_%s", test.provider, test.os, test.arch), func(t *testing.T) {
   167  			// TEMP: We don't yet have a function for parsing provider
   168  			// source addresses so we'll just fake it in here for now.
   169  			parts := strings.Split(test.provider, "/")
   170  			providerAddr := addrs.Provider{
   171  				Hostname:  svchost.Hostname(parts[0]),
   172  				Namespace: parts[1],
   173  				Type:      parts[2],
   174  			}
   175  
   176  			version := versions.MustParseVersion(test.version)
   177  
   178  			got, err := source.PackageMeta(providerAddr, version, Platform{test.os, test.arch})
   179  
   180  			if err != nil {
   181  				if test.wantErr == "" {
   182  					t.Fatalf("wrong error\ngot:  %s\nwant: <nil>", err.Error())
   183  				}
   184  				gotErr := urlPattern.ReplaceAllLiteralString(err.Error(), "http://placeholder-origin/")
   185  				if got, want := gotErr, test.wantErr; got != want {
   186  					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
   187  				}
   188  				return
   189  			}
   190  
   191  			if test.wantErr != "" {
   192  				t.Fatalf("wrong error\ngot:  <nil>\nwant: %s", test.wantErr)
   193  			}
   194  
   195  			if diff := cmp.Diff(test.want, got, cmpOpts); diff != "" {
   196  				t.Errorf("wrong result\n%s", diff)
   197  			}
   198  		})
   199  	}
   200  
   201  }