From f7ae491d22294e7411f5551281a5281498fdc22b Mon Sep 17 00:00:00 2001 From: Petu Eusebiu Date: Fri, 22 Oct 2021 12:56:55 +0300 Subject: [PATCH] Fix data race in sync tests Signed-off-by: Petu Eusebiu --- pkg/extensions/sync/sync.go | 4 +- pkg/extensions/sync/sync_test.go | 279 +++++++++++++++++++++++-------- 2 files changed, 213 insertions(+), 70 deletions(-) diff --git a/pkg/extensions/sync/sync.go b/pkg/extensions/sync/sync.go index c700fa92..1c68cdf4 100644 --- a/pkg/extensions/sync/sync.go +++ b/pkg/extensions/sync/sync.go @@ -435,11 +435,9 @@ func Run(cfg Config, log log.Logger, address, port, serverCert, serverKey, caCer } } - var ticker *time.Ticker - for _, regCfg := range cfg.Registries { // schedule each registry sync - ticker = time.NewTicker(regCfg.PollInterval) + ticker := time.NewTicker(regCfg.PollInterval) upstreamRegistry := strings.Replace(strings.Replace(regCfg.URL, "http://", "", 1), "https://", "", 1) diff --git a/pkg/extensions/sync/sync_test.go b/pkg/extensions/sync/sync_test.go index b4e282de..2731dffa 100644 --- a/pkg/extensions/sync/sync_test.go +++ b/pkg/extensions/sync/sync_test.go @@ -37,6 +37,7 @@ const ( testImage = "zot-test" testImageTag = "0.0.1" + testCveImage = "/zot-cve-test" ) var errSync = errors.New("sync error, src oci repo differs from dest one") @@ -180,6 +181,11 @@ func TestSyncOnDemand(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(srcBaseURL) @@ -239,6 +245,11 @@ func TestSyncOnDemand(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -289,12 +300,6 @@ func TestSyncOnDemand(t *testing.T) { if eq := reflect.DeepEqual(destTagsList.Tags, srcTagsList.Tags); eq == false { panic(errSync) } - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) } @@ -331,6 +336,11 @@ func TestSync(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(srcBaseURL) @@ -388,6 +398,11 @@ func TestSync(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -424,7 +439,7 @@ func TestSync(t *testing.T) { break } - time.Sleep(1 * time.Second) + time.Sleep(500 * time.Millisecond) } if eq := reflect.DeepEqual(destTagsList.Tags, srcTagsList.Tags); eq == false { @@ -437,11 +452,119 @@ func TestSync(t *testing.T) { So(resp.StatusCode(), ShouldEqual, 200) }) - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() + Convey("Test sync with more contents", func() { + destPort := getFreePort() + destBaseURL := getBaseURL(destPort, false) + + destConfig := config.New() + destConfig.HTTP.Port = destPort + + destDir, err := ioutil.TempDir("", "oci-dest-repo-test") + if err != nil { + panic(err) + } + + defer os.RemoveAll(destDir) + + destConfig.Storage.RootDirectory = destDir + + regex := ".*" + semver := true + + invalidRegex := "invalid" + + var tlsVerify bool + + syncRegistryConfig := sync.RegistryConfig{ + Content: []sync.Content{ + { + Prefix: testImage, + Tags: &sync.Tags{ + Regex: ®ex, + Semver: &semver, + }, + }, + { + Prefix: testCveImage, + Tags: &sync.Tags{ + Regex: &invalidRegex, + Semver: &semver, + }, + }, + }, + URL: srcBaseURL, + PollInterval: updateDuration, + TLSVerify: &tlsVerify, + CertDir: "", + } + + destConfig.Extensions = &extconf.ExtensionConfig{} + destConfig.Extensions.Search = nil + destConfig.Extensions.Sync = &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}} + + dc := api.NewController(destConfig) + + go func() { + // this blocks + if err := dc.Run(); err != nil { + return + } + }() + + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + + // wait till ready + for { + _, err := resty.R().Get(destBaseURL) + if err == nil { + break + } + time.Sleep(100 * time.Millisecond) + } + + var srcTagsList TagsList + var destTagsList TagsList + + resp, _ := resty.R().Get(srcBaseURL + "/v2/" + testImage + "/tags/list") + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + err = json.Unmarshal(resp.Body(), &srcTagsList) + if err != nil { + panic(err) + } + + for { + resp, err = resty.R().Get(destBaseURL + "/v2/" + testImage + "/tags/list") + if err != nil { + panic(err) + } + + err = json.Unmarshal(resp.Body(), &destTagsList) + if err != nil { + panic(err) + } + + if len(destTagsList.Tags) > 0 { + break + } + + time.Sleep(500 * time.Millisecond) + } + + if eq := reflect.DeepEqual(destTagsList.Tags, srcTagsList.Tags); eq == false { + panic(errSync) + } + + Convey("Test sync on POST request on /sync", func() { + resp, _ := resty.R().Post(destBaseURL + "/sync") + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + }) + }) }) } @@ -497,6 +620,11 @@ func TestSyncTLS(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + cert, err := tls.LoadX509KeyPair("../../../test/data/client.cert", "../../../test/data/client.key") if err != nil { panic(err) @@ -597,11 +725,16 @@ func TestSyncTLS(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { destBuf, _ := ioutil.ReadFile(path.Join(destDir, testImage, "index.json")) _ = json.Unmarshal(destBuf, &destIndex) - time.Sleep(1 * time.Second) + time.Sleep(500 * time.Millisecond) if len(destIndex.Manifests) > 0 { break } @@ -617,12 +750,6 @@ func TestSyncTLS(t *testing.T) { if !found { panic(errSync) } - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) } @@ -668,6 +795,11 @@ func TestSyncBasicAuth(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(srcBaseURL) @@ -726,6 +858,11 @@ func TestSyncBasicAuth(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -762,18 +899,12 @@ func TestSyncBasicAuth(t *testing.T) { break } - time.Sleep(1 * time.Second) + time.Sleep(500 * time.Millisecond) } if eq := reflect.DeepEqual(destTagsList.Tags, srcTagsList.Tags); eq == false { panic(errSync) } - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) Convey("Verify sync basic auth with bad file credentials", func() { @@ -832,6 +963,11 @@ func TestSyncBasicAuth(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -847,12 +983,6 @@ func TestSyncBasicAuth(t *testing.T) { So(string(resp.Body()), ShouldContainSubstring, "sync: couldn't fetch upstream registry's catalog") So(resp.StatusCode(), ShouldEqual, 500) }) - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) Convey("Verify on demand sync with basic auth", func() { @@ -906,6 +1036,11 @@ func TestSyncBasicAuth(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -969,12 +1104,6 @@ func TestSyncBasicAuth(t *testing.T) { So(resp, ShouldNotBeNil) So(resp.StatusCode(), ShouldEqual, 200) }) - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) }) } @@ -1030,6 +1159,11 @@ func TestSyncBadUrl(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -1045,11 +1179,6 @@ func TestSyncBadUrl(t *testing.T) { So(string(resp.Body()), ShouldContainSubstring, "unsupported protocol scheme") So(resp.StatusCode(), ShouldEqual, 500) }) - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - }() }) } @@ -1086,6 +1215,11 @@ func TestSyncNoImagesByRegex(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(srcBaseURL) @@ -1141,6 +1275,11 @@ func TestSyncNoImagesByRegex(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -1169,12 +1308,6 @@ func TestSyncNoImagesByRegex(t *testing.T) { So(c.Repositories, ShouldResemble, []string{}) }) - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) } @@ -1211,6 +1344,11 @@ func TestSyncInvalidRegex(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(srcBaseURL) @@ -1266,6 +1404,11 @@ func TestSyncInvalidRegex(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -1281,12 +1424,6 @@ func TestSyncInvalidRegex(t *testing.T) { So(string(resp.Body()), ShouldContainSubstring, "error parsing regexp") So(resp.StatusCode(), ShouldEqual, 500) }) - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) } @@ -1323,6 +1460,11 @@ func TestSyncNotSemver(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(srcBaseURL) @@ -1393,6 +1535,11 @@ func TestSyncNotSemver(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -1423,12 +1570,6 @@ func TestSyncNotSemver(t *testing.T) { So(len(destTagsList.Tags), ShouldEqual, 1) So(destTagsList.Tags[0], ShouldEqual, testImageTag) }) - - defer func() { - ctx := context.Background() - _ = dc.Server.Shutdown(ctx) - _ = sc.Server.Shutdown(ctx) - }() }) } @@ -1480,6 +1621,11 @@ func TestSyncInvalidCerts(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = sc.Server.Shutdown(ctx) + }() + cert, err := tls.LoadX509KeyPair("../../../test/data/client.cert", "../../../test/data/client.key") if err != nil { panic(err) @@ -1573,6 +1719,11 @@ func TestSyncInvalidCerts(t *testing.T) { } }() + defer func() { + ctx := context.Background() + _ = dc.Server.Shutdown(ctx) + }() + // wait till ready for { _, err := resty.R().Get(destBaseURL) @@ -1588,12 +1739,6 @@ func TestSyncInvalidCerts(t *testing.T) { So(string(resp.Body()), ShouldContainSubstring, "signed by unknown authority") So(resp.StatusCode(), ShouldEqual, 500) }) - - defer func() { - ctx := context.Background() - _ = sc.Server.Shutdown(ctx) - _ = dc.Server.Shutdown(ctx) - }() }) }