zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/extensions/sync/content_internal_test.go (about)

     1  //go:build sync
     2  // +build sync
     3  
     4  package sync
     5  
     6  import (
     7  	"testing"
     8  
     9  	. "github.com/smartystreets/goconvey/convey"
    10  
    11  	syncconf "zotregistry.dev/zot/pkg/extensions/config/sync"
    12  	"zotregistry.dev/zot/pkg/log"
    13  )
    14  
    15  func TestContentManager(t *testing.T) {
    16  	testCases := []struct {
    17  		repo     string
    18  		content  syncconf.Content
    19  		expected string
    20  	}{
    21  		{
    22  			repo:     "alpine/zot-fold/alpine",
    23  			content:  syncconf.Content{Prefix: "zot-fold/alpine", Destination: "/alpine", StripPrefix: false},
    24  			expected: "zot-fold/alpine",
    25  		},
    26  		{
    27  			repo:     "zot-fold/alpine",
    28  			content:  syncconf.Content{Prefix: "zot-fold/alpine", Destination: "/", StripPrefix: false},
    29  			expected: "zot-fold/alpine",
    30  		},
    31  		{
    32  			repo:     "alpine",
    33  			content:  syncconf.Content{Prefix: "zot-fold/alpine", Destination: "/alpine", StripPrefix: true},
    34  			expected: "zot-fold/alpine",
    35  		},
    36  		{
    37  			repo:     "/",
    38  			content:  syncconf.Content{Prefix: "zot-fold/alpine", Destination: "/", StripPrefix: true},
    39  			expected: "zot-fold/alpine",
    40  		},
    41  		{
    42  			repo:     "",
    43  			content:  syncconf.Content{Prefix: "/", Destination: "/", StripPrefix: true},
    44  			expected: "/",
    45  		},
    46  		{
    47  			repo:     "alpine",
    48  			content:  syncconf.Content{Prefix: "zot-fold/alpine", Destination: "/alpine", StripPrefix: true},
    49  			expected: "zot-fold/alpine",
    50  		},
    51  		{
    52  			repo:     "alpine",
    53  			content:  syncconf.Content{Prefix: "zot-fold/*", Destination: "/", StripPrefix: true},
    54  			expected: "zot-fold/alpine",
    55  		},
    56  		{
    57  			repo:     "alpine",
    58  			content:  syncconf.Content{Prefix: "zot-fold/**", Destination: "/", StripPrefix: true},
    59  			expected: "zot-fold/alpine",
    60  		},
    61  		{
    62  			repo:     "zot-fold/alpine",
    63  			content:  syncconf.Content{Prefix: "zot-fold/**", Destination: "/", StripPrefix: false},
    64  			expected: "zot-fold/alpine",
    65  		},
    66  	}
    67  
    68  	Convey("Test GetRepoDestination()", t, func() {
    69  		for _, test := range testCases {
    70  			cm := NewContentManager([]syncconf.Content{test.content}, log.Logger{})
    71  			actualResult := cm.GetRepoDestination(test.expected)
    72  			So(actualResult, ShouldEqual, test.repo)
    73  		}
    74  	})
    75  
    76  	// this is the inverse function of getRepoDestination()
    77  	Convey("Test GetRepoSource()", t, func() {
    78  		for _, test := range testCases {
    79  			cm := NewContentManager([]syncconf.Content{test.content}, log.Logger{})
    80  			actualResult := cm.GetRepoSource(test.repo)
    81  			So(actualResult, ShouldEqual, test.expected)
    82  		}
    83  	})
    84  
    85  	Convey("Test MatchesContent() error", t, func() {
    86  		content := syncconf.Content{Prefix: "[repo%^&"}
    87  		cm := NewContentManager([]syncconf.Content{content}, log.Logger{})
    88  		So(cm.MatchesContent("repo"), ShouldEqual, false)
    89  	})
    90  }
    91  
    92  func TestGetContentByLocalRepo(t *testing.T) {
    93  	testCases := []struct {
    94  		repo     string
    95  		content  []syncconf.Content
    96  		expected int
    97  	}{
    98  		{
    99  			repo: "alpine/zot-fold/alpine",
   100  			content: []syncconf.Content{
   101  				{Prefix: "zot-fold/alpine/", Destination: "/alpine", StripPrefix: true},
   102  				{Prefix: "zot-fold/alpine", Destination: "/alpine", StripPrefix: false},
   103  			},
   104  			expected: 1,
   105  		},
   106  		{
   107  			repo: "alpine/zot-fold/alpine",
   108  			content: []syncconf.Content{
   109  				{Prefix: "zot-fold/*", Destination: "/alpine", StripPrefix: false},
   110  				{Prefix: "zot-fold/alpine", Destination: "/alpine", StripPrefix: true},
   111  			},
   112  			expected: 0,
   113  		},
   114  		{
   115  			repo: "myFold/zot-fold/internal/alpine",
   116  			content: []syncconf.Content{
   117  				{Prefix: "zot-fold/alpine", Destination: "/alpine", StripPrefix: true},
   118  				{Prefix: "zot-fold/**", Destination: "/myFold", StripPrefix: false},
   119  			},
   120  			expected: 1,
   121  		},
   122  		{
   123  			repo: "alpine",
   124  			content: []syncconf.Content{
   125  				{Prefix: "zot-fold/*", Destination: "/alpine", StripPrefix: true},
   126  				{Prefix: "zot-fold/alpine", Destination: "/", StripPrefix: true},
   127  			},
   128  			expected: -1,
   129  		},
   130  		{
   131  			repo: "alpine",
   132  			content: []syncconf.Content{
   133  				{Prefix: "zot-fold/*", Destination: "/alpine", StripPrefix: true},
   134  				{Prefix: "zot-fold/*", Destination: "/", StripPrefix: true},
   135  			},
   136  			expected: 1,
   137  		},
   138  		{
   139  			repo: "alpine/alpine",
   140  			content: []syncconf.Content{
   141  				{Prefix: "zot-fold/*", Destination: "/alpine", StripPrefix: true},
   142  				{Prefix: "zot-fold/*", Destination: "/", StripPrefix: true},
   143  			},
   144  			expected: 0,
   145  		},
   146  	}
   147  
   148  	Convey("Test getContentByLocalRepo()", t, func() {
   149  		for _, test := range testCases {
   150  			cm := NewContentManager(test.content, log.Logger{})
   151  			actualResult := cm.getContentByLocalRepo(test.repo)
   152  			if test.expected == -1 {
   153  				var tnil *syncconf.Content = nil
   154  				So(actualResult, ShouldEqual, tnil)
   155  			} else {
   156  				So(actualResult, ShouldEqual, &test.content[test.expected])
   157  			}
   158  		}
   159  	})
   160  
   161  	Convey("Test getContentByLocalRepo() error", t, func() {
   162  		content := syncconf.Content{Prefix: "[repo%^&"}
   163  		cm := NewContentManager([]syncconf.Content{content}, log.Logger{})
   164  		So(cm.getContentByLocalRepo("repo"), ShouldBeNil)
   165  	})
   166  }
   167  
   168  func TestFilterTags(t *testing.T) {
   169  	allTagsRegex := ".*"
   170  	badRegex := "[*"
   171  	semverFalse := false
   172  	semverTrue := true
   173  	testCases := []struct {
   174  		tags         []string
   175  		repo         string
   176  		content      []syncconf.Content
   177  		filteredTags []string
   178  		err          bool
   179  	}{
   180  		{
   181  			repo: "alpine",
   182  			content: []syncconf.Content{
   183  				{Prefix: "**", Tags: &syncconf.Tags{Regex: &allTagsRegex, Semver: &semverFalse}},
   184  			},
   185  			tags:         []string{"v1", "v2", "v3"},
   186  			filteredTags: []string{"v1", "v2", "v3"},
   187  			err:          false,
   188  		},
   189  		{
   190  			repo: "alpine",
   191  			content: []syncconf.Content{
   192  				{Prefix: "**", Tags: &syncconf.Tags{}},
   193  			},
   194  			tags:         []string{"v1", "v2", "v3"},
   195  			filteredTags: []string{"v1", "v2", "v3"},
   196  			err:          false,
   197  		},
   198  		{
   199  			repo: "alpine",
   200  			content: []syncconf.Content{
   201  				{Prefix: "**", Tags: &syncconf.Tags{Regex: &allTagsRegex, Semver: &semverTrue}},
   202  			},
   203  			tags:         []string{"1s0", "2v9", "v3.0.3"},
   204  			filteredTags: []string{"v3.0.3"},
   205  			err:          false,
   206  		},
   207  		{
   208  			repo: "infra/busybox",
   209  			content: []syncconf.Content{
   210  				{Prefix: "infra/*", Tags: &syncconf.Tags{Semver: &semverTrue}},
   211  			},
   212  			tags:         []string{"latest", "v1.0.1"},
   213  			filteredTags: []string{"v1.0.1"},
   214  			err:          false,
   215  		},
   216  		{
   217  			repo: "repo",
   218  			content: []syncconf.Content{
   219  				{Prefix: "repo*", Tags: &syncconf.Tags{Regex: &badRegex}},
   220  			},
   221  			tags:         []string{"latest", "v2.0.1"},
   222  			filteredTags: []string{},
   223  			err:          true,
   224  		},
   225  
   226  		{
   227  			repo: "repo",
   228  			content: []syncconf.Content{
   229  				{Prefix: "repo", Tags: &syncconf.Tags{Regex: &allTagsRegex}},
   230  			},
   231  			tags:         []string{},
   232  			filteredTags: []string{},
   233  			err:          false,
   234  		},
   235  	}
   236  
   237  	Convey("Test FilterTags()", t, func() {
   238  		for _, test := range testCases {
   239  			cm := NewContentManager(test.content, log.NewLogger("debug", ""))
   240  			actualResult, err := cm.FilterTags(test.repo, test.tags)
   241  			So(actualResult, ShouldResemble, test.filteredTags)
   242  			if test.err {
   243  				So(err, ShouldNotBeNil)
   244  			} else {
   245  				So(err, ShouldBeNil)
   246  			}
   247  		}
   248  	})
   249  }