github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/plugin/discovery/meta_set_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package discovery
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestPluginMetaSetManipulation(t *testing.T) {
    13  	metas := []PluginMeta{
    14  		{
    15  			Name:    "foo",
    16  			Version: "1.0.0",
    17  			Path:    "test-foo",
    18  		},
    19  		{
    20  			Name:    "bar",
    21  			Version: "2.0.0",
    22  			Path:    "test-bar",
    23  		},
    24  		{
    25  			Name:    "baz",
    26  			Version: "2.0.0",
    27  			Path:    "test-bar",
    28  		},
    29  	}
    30  	s := make(PluginMetaSet)
    31  
    32  	if count := s.Count(); count != 0 {
    33  		t.Fatalf("set has Count %d before any items added", count)
    34  	}
    35  
    36  	// Can we add metas?
    37  	for _, p := range metas {
    38  		s.Add(p)
    39  		if !s.Has(p) {
    40  			t.Fatalf("%q not in set after adding it", p.Name)
    41  		}
    42  	}
    43  
    44  	if got, want := s.Count(), len(metas); got != want {
    45  		t.Fatalf("set has Count %d after all items added; want %d", got, want)
    46  	}
    47  
    48  	// Can we still retrieve earlier ones after we added later ones?
    49  	for _, p := range metas {
    50  		if !s.Has(p) {
    51  			t.Fatalf("%q not in set after all adds", p.Name)
    52  		}
    53  	}
    54  
    55  	// Can we remove metas?
    56  	for _, p := range metas {
    57  		s.Remove(p)
    58  		if s.Has(p) {
    59  			t.Fatalf("%q still in set after removing it", p.Name)
    60  		}
    61  	}
    62  
    63  	if count := s.Count(); count != 0 {
    64  		t.Fatalf("set has Count %d after all items removed", count)
    65  	}
    66  }
    67  
    68  func TestPluginMetaSetValidateVersions(t *testing.T) {
    69  	metas := []PluginMeta{
    70  		{
    71  			Name:    "foo",
    72  			Version: "1.0.0",
    73  			Path:    "test-foo",
    74  		},
    75  		{
    76  			Name:    "bar",
    77  			Version: "0.0.1",
    78  			Path:    "test-bar",
    79  		},
    80  		{
    81  			Name:    "baz",
    82  			Version: "bananas",
    83  			Path:    "test-bar",
    84  		},
    85  	}
    86  	s := make(PluginMetaSet)
    87  
    88  	for _, p := range metas {
    89  		s.Add(p)
    90  	}
    91  
    92  	valid, invalid := s.ValidateVersions()
    93  	if count := valid.Count(); count != 2 {
    94  		t.Errorf("valid set has %d metas; want 2", count)
    95  	}
    96  	if count := invalid.Count(); count != 1 {
    97  		t.Errorf("valid set has %d metas; want 1", count)
    98  	}
    99  
   100  	if !valid.Has(metas[0]) {
   101  		t.Errorf("'foo' not in valid set")
   102  	}
   103  	if !valid.Has(metas[1]) {
   104  		t.Errorf("'bar' not in valid set")
   105  	}
   106  	if !invalid.Has(metas[2]) {
   107  		t.Errorf("'baz' not in invalid set")
   108  	}
   109  
   110  	if invalid.Has(metas[0]) {
   111  		t.Errorf("'foo' in invalid set")
   112  	}
   113  	if invalid.Has(metas[1]) {
   114  		t.Errorf("'bar' in invalid set")
   115  	}
   116  	if valid.Has(metas[2]) {
   117  		t.Errorf("'baz' in valid set")
   118  	}
   119  
   120  }
   121  
   122  func TestPluginMetaSetWithName(t *testing.T) {
   123  	tests := []struct {
   124  		metas     []PluginMeta
   125  		name      string
   126  		wantCount int
   127  	}{
   128  		{
   129  			[]PluginMeta{},
   130  			"foo",
   131  			0,
   132  		},
   133  		{
   134  			[]PluginMeta{
   135  				{
   136  					Name:    "foo",
   137  					Version: "0.0.1",
   138  					Path:    "foo",
   139  				},
   140  			},
   141  			"foo",
   142  			1,
   143  		},
   144  		{
   145  			[]PluginMeta{
   146  				{
   147  					Name:    "foo",
   148  					Version: "0.0.1",
   149  					Path:    "foo",
   150  				},
   151  			},
   152  			"bar",
   153  			0,
   154  		},
   155  	}
   156  
   157  	for i, test := range tests {
   158  		t.Run(fmt.Sprintf("Test%02d", i), func(t *testing.T) {
   159  			s := make(PluginMetaSet)
   160  			for _, p := range test.metas {
   161  				s.Add(p)
   162  			}
   163  			filtered := s.WithName(test.name)
   164  			if gotCount := filtered.Count(); gotCount != test.wantCount {
   165  				t.Errorf("got count %d in %#v; want %d", gotCount, filtered, test.wantCount)
   166  			}
   167  		})
   168  	}
   169  }
   170  
   171  func TestPluginMetaSetByName(t *testing.T) {
   172  	metas := []PluginMeta{
   173  		{
   174  			Name:    "foo",
   175  			Version: "1.0.0",
   176  			Path:    "test-foo",
   177  		},
   178  		{
   179  			Name:    "foo",
   180  			Version: "2.0.0",
   181  			Path:    "test-foo-2",
   182  		},
   183  		{
   184  			Name:    "bar",
   185  			Version: "0.0.1",
   186  			Path:    "test-bar",
   187  		},
   188  		{
   189  			Name:    "baz",
   190  			Version: "1.2.0",
   191  			Path:    "test-bar",
   192  		},
   193  	}
   194  	s := make(PluginMetaSet)
   195  
   196  	for _, p := range metas {
   197  		s.Add(p)
   198  	}
   199  
   200  	byName := s.ByName()
   201  	if got, want := len(byName), 3; got != want {
   202  		t.Errorf("%d keys in ByName map; want %d", got, want)
   203  	}
   204  	if got, want := len(byName["foo"]), 2; got != want {
   205  		t.Errorf("%d metas for 'foo'; want %d", got, want)
   206  	}
   207  	if got, want := len(byName["bar"]), 1; got != want {
   208  		t.Errorf("%d metas for 'bar'; want %d", got, want)
   209  	}
   210  	if got, want := len(byName["baz"]), 1; got != want {
   211  		t.Errorf("%d metas for 'baz'; want %d", got, want)
   212  	}
   213  
   214  	if !byName["foo"].Has(metas[0]) {
   215  		t.Errorf("%#v missing from 'foo' set", metas[0])
   216  	}
   217  	if !byName["foo"].Has(metas[1]) {
   218  		t.Errorf("%#v missing from 'foo' set", metas[1])
   219  	}
   220  	if !byName["bar"].Has(metas[2]) {
   221  		t.Errorf("%#v missing from 'bar' set", metas[2])
   222  	}
   223  	if !byName["baz"].Has(metas[3]) {
   224  		t.Errorf("%#v missing from 'baz' set", metas[3])
   225  	}
   226  }
   227  
   228  func TestPluginMetaSetNewest(t *testing.T) {
   229  	tests := []struct {
   230  		versions []string
   231  		want     string
   232  	}{
   233  		{
   234  			[]string{
   235  				"0.0.1",
   236  			},
   237  			"0.0.1",
   238  		},
   239  		{
   240  			[]string{
   241  				"0.0.1",
   242  				"0.0.2",
   243  			},
   244  			"0.0.2",
   245  		},
   246  		{
   247  			[]string{
   248  				"1.0.0",
   249  				"1.0.0-beta1",
   250  			},
   251  			"1.0.0",
   252  		},
   253  		{
   254  			[]string{
   255  				"0.0.1",
   256  				"1.0.0",
   257  			},
   258  			"1.0.0",
   259  		},
   260  	}
   261  
   262  	for _, test := range tests {
   263  		t.Run(strings.Join(test.versions, "|"), func(t *testing.T) {
   264  			s := make(PluginMetaSet)
   265  			for _, version := range test.versions {
   266  				s.Add(PluginMeta{
   267  					Name:    "foo",
   268  					Version: VersionStr(version),
   269  					Path:    "foo-V" + version,
   270  				})
   271  			}
   272  
   273  			newest := s.Newest()
   274  			if newest.Version != VersionStr(test.want) {
   275  				t.Errorf("version is %q; want %q", newest.Version, test.want)
   276  			}
   277  		})
   278  	}
   279  }
   280  
   281  func TestPluginMetaSetConstrainVersions(t *testing.T) {
   282  	metas := []PluginMeta{
   283  		{
   284  			Name:    "foo",
   285  			Version: "1.0.0",
   286  			Path:    "test-foo",
   287  		},
   288  		{
   289  			Name:    "foo",
   290  			Version: "2.0.0",
   291  			Path:    "test-foo-2",
   292  		},
   293  		{
   294  			Name:    "foo",
   295  			Version: "3.0.0",
   296  			Path:    "test-foo-2",
   297  		},
   298  		{
   299  			Name:    "bar",
   300  			Version: "0.0.5",
   301  			Path:    "test-bar",
   302  		},
   303  		{
   304  			Name:    "baz",
   305  			Version: "0.0.1",
   306  			Path:    "test-bar",
   307  		},
   308  	}
   309  	s := make(PluginMetaSet)
   310  
   311  	for _, p := range metas {
   312  		s.Add(p)
   313  	}
   314  
   315  	byName := s.ConstrainVersions(PluginRequirements{
   316  		"foo": &PluginConstraints{Versions: ConstraintStr(">=2.0.0").MustParse()},
   317  		"bar": &PluginConstraints{Versions: ConstraintStr(">=0.0.0").MustParse()},
   318  		"baz": &PluginConstraints{Versions: ConstraintStr(">=1.0.0").MustParse()},
   319  		"fun": &PluginConstraints{Versions: ConstraintStr(">5.0.0").MustParse()},
   320  	})
   321  	if got, want := len(byName), 3; got != want {
   322  		t.Errorf("%d keys in map; want %d", got, want)
   323  	}
   324  
   325  	if got, want := len(byName["foo"]), 2; got != want {
   326  		t.Errorf("%d metas for 'foo'; want %d", got, want)
   327  	}
   328  	if got, want := len(byName["bar"]), 1; got != want {
   329  		t.Errorf("%d metas for 'bar'; want %d", got, want)
   330  	}
   331  	if got, want := len(byName["baz"]), 0; got != want {
   332  		t.Errorf("%d metas for 'baz'; want %d", got, want)
   333  	}
   334  	// "fun" is not in the map at all, because we have no metas for that name
   335  
   336  	if !byName["foo"].Has(metas[1]) {
   337  		t.Errorf("%#v missing from 'foo' set", metas[1])
   338  	}
   339  	if !byName["foo"].Has(metas[2]) {
   340  		t.Errorf("%#v missing from 'foo' set", metas[2])
   341  	}
   342  	if !byName["bar"].Has(metas[3]) {
   343  		t.Errorf("%#v missing from 'bar' set", metas[3])
   344  	}
   345  
   346  }
   347  
   348  func TestPluginMetaSetOverridePaths(t *testing.T) {
   349  
   350  	metas := []PluginMeta{
   351  		{
   352  			Name:    "foo",
   353  			Version: "1.0.0",
   354  			Path:    "test-foo-1",
   355  		},
   356  		{
   357  			Name:    "foo",
   358  			Version: "2.0.0",
   359  			Path:    "test-foo-2",
   360  		},
   361  		{
   362  			Name:    "foo",
   363  			Version: "3.0.0",
   364  			Path:    "test-foo-3",
   365  		},
   366  		{
   367  			Name:    "bar",
   368  			Version: "0.0.5",
   369  			Path:    "test-bar-5",
   370  		},
   371  		{
   372  			Name:    "bar",
   373  			Version: "0.0.6",
   374  			Path:    "test-bar-6",
   375  		},
   376  		{
   377  			Name:    "baz",
   378  			Version: "0.0.1",
   379  			Path:    "test-bar",
   380  		},
   381  	}
   382  	s := make(PluginMetaSet)
   383  
   384  	for _, p := range metas {
   385  		s.Add(p)
   386  	}
   387  
   388  	ns := s.OverridePaths(map[string]string{
   389  		"foo": "override-foo",
   390  		"fun": "override-fun",
   391  	})
   392  
   393  	if got, want := ns.Count(), 5; got != want {
   394  		t.Errorf("got %d metas; want %d", got, want)
   395  	}
   396  
   397  	if !ns.Has(metas[3]) {
   398  		t.Errorf("new set is missing %#v", metas[3])
   399  	}
   400  	if !ns.Has(metas[4]) {
   401  		t.Errorf("new set is missing %#v", metas[4])
   402  	}
   403  	if !ns.Has(metas[5]) {
   404  		t.Errorf("new set is missing %#v", metas[5])
   405  	}
   406  	if !ns.Has(PluginMeta{
   407  		Name:    "foo",
   408  		Version: VersionZero,
   409  		Path:    "override-foo",
   410  	}) {
   411  		t.Errorf("new set is missing 'foo' override")
   412  	}
   413  	if !ns.Has(PluginMeta{
   414  		Name:    "fun",
   415  		Version: VersionZero,
   416  		Path:    "override-fun",
   417  	}) {
   418  		t.Errorf("new set is missing 'fun' override")
   419  	}
   420  }