0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-30 22:34:13 -05:00

test(sync): consolidate all sync tests (#1332)

Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
This commit is contained in:
peusebiu 2023-04-07 09:36:27 +03:00 committed by GitHub
parent 38997be596
commit 96232bb11c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 462 additions and 56 deletions

View file

@ -1265,3 +1265,61 @@ func TestCompareArtifactRefs(t *testing.T) {
} }
}) })
} }
func TestCompareArtifactManifests(t *testing.T) {
testCases := []struct {
refs1 ispec.Artifact
refs2 ispec.Artifact
expected bool
}{
{
refs1: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest1",
},
},
},
refs2: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest1",
},
},
},
expected: true,
},
{
refs1: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest1",
},
},
},
refs2: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest2",
},
},
},
expected: false,
},
}
Convey("Test artifactsEqual()", t, func() {
for _, test := range testCases {
actualResult := artifactsEqual(test.refs1, test.refs2)
So(actualResult, ShouldEqual, test.expected)
}
})
}

View file

@ -10,7 +10,6 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@ -201,6 +200,7 @@ func makeDownstreamServer(
BaseConfig: extconf.BaseConfig{Enable: &defVal}, BaseConfig: extconf.BaseConfig{Enable: &defVal},
} }
destConfig.Extensions.Sync = syncConfig destConfig.Extensions.Sync = syncConfig
destConfig.Log.Output = path.Join(destDir, "sync.log")
dctlr := api.NewController(destConfig) dctlr := api.NewController(destConfig)
@ -981,8 +981,8 @@ func TestPeriodically(t *testing.T) {
}) })
} }
func TestOnDemandPermsDenied(t *testing.T) { func TestPermsDenied(t *testing.T) {
Convey("Verify sync on demand feature without perm on sync cache", t, func() { Convey("Verify sync feature without perm on sync cache", t, func() {
updateDuration, _ := time.ParseDuration("30m") updateDuration, _ := time.ParseDuration("30m")
sctlr, srcBaseURL, _, _, _ := makeUpstreamServer(t, false, false) sctlr, srcBaseURL, _, _, _ := makeUpstreamServer(t, false, false)
@ -1031,6 +1031,7 @@ func TestOnDemandPermsDenied(t *testing.T) {
destConfig.Extensions = &extconf.ExtensionConfig{} destConfig.Extensions = &extconf.ExtensionConfig{}
destConfig.Extensions.Search = nil destConfig.Extensions.Search = nil
destConfig.Extensions.Sync = syncConfig destConfig.Extensions.Sync = syncConfig
destConfig.Log.Output = path.Join(destDir, "sync.log")
dctlr := api.NewController(destConfig) dctlr := api.NewController(destConfig)
dcm := test.NewControllerManager(dctlr) dcm := test.NewControllerManager(dctlr)
@ -1047,8 +1048,20 @@ func TestOnDemandPermsDenied(t *testing.T) {
dcm.StartAndWait(destPort) dcm.StartAndWait(destPort)
// give it time to sync found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
time.Sleep(3 * time.Second) "couldn't get localCachePath for ", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := resty.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err := resty.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -1058,6 +1071,10 @@ func TestOnDemandPermsDenied(t *testing.T) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}) })
} }
@ -1172,8 +1189,8 @@ func TestConfigReloader(t *testing.T) {
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
t.Logf("downstream log: %s", string(data))
So(err, ShouldBeNil) So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
So(string(data), ShouldContainSubstring, "reloaded params") So(string(data), ShouldContainSubstring, "reloaded params")
So(string(data), ShouldContainSubstring, "new configuration settings") So(string(data), ShouldContainSubstring, "new configuration settings")
So(string(data), ShouldContainSubstring, "\"Sync\":null") So(string(data), ShouldContainSubstring, "\"Sync\":null")
@ -1250,18 +1267,25 @@ func TestMandatoryAnnotations(t *testing.T) {
defer dcm.StopServer() defer dcm.StopServer()
// give it time to set up sync found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
time.Sleep(10 * time.Second) "couldn't upload manifest because of missing annotations", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/0.0.1") resp, err := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/0.0.1")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
data, err := os.ReadFile(logFile.Name())
t.Logf("downstream log: %s", string(data))
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "couldn't upload manifest because of missing annotations")
}) })
} }
@ -1307,8 +1331,20 @@ func TestBadTLS(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
// give it time to set up sync found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
time.Sleep(3 * time.Second) "x509: certificate signed by unknown authority", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, _ := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + "invalid") resp, _ := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + "invalid")
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
@ -1318,7 +1354,7 @@ func TestBadTLS(t *testing.T) {
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
resp, err := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err = destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
}) })
@ -1561,12 +1597,27 @@ func TestBasicAuth(t *testing.T) {
Registries: []syncconf.RegistryConfig{syncRegistryConfig}, Registries: []syncconf.RegistryConfig{syncRegistryConfig},
} }
destConfig.Log.Output = path.Join(destDir, "sync.log")
dctlr := api.NewController(destConfig) dctlr := api.NewController(destConfig)
dcm := test.NewControllerManager(dctlr) dcm := test.NewControllerManager(dctlr)
dcm.StartAndWait(destPort) dcm.StartAndWait(destPort)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(3 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"status code: 401", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := resty.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err := resty.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -1627,7 +1678,20 @@ func TestBasicAuth(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(3 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't get registry credentials from", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err := destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -1874,6 +1938,21 @@ func TestInvalidRegex(t *testing.T) {
dcm := test.NewControllerManager(dctlr) dcm := test.NewControllerManager(dctlr)
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't compile regex", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
}) })
} }
@ -2755,7 +2834,20 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(2 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"finished syncing", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
// should not be synced nor sync on demand // should not be synced nor sync on demand
resp, err := resty.R().Get(destBaseURL + "/v2/" + repoName + "/manifests/1.0") resp, err := resty.R().Get(destBaseURL + "/v2/" + repoName + "/manifests/1.0")
@ -2790,7 +2882,20 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(2 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"finished syncing", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
// should not be synced nor sync on demand // should not be synced nor sync on demand
resp, err := resty.R().Get(destBaseURL + "/v2/" + repoName + "/manifests/" + cosignTag) resp, err := resty.R().Get(destBaseURL + "/v2/" + repoName + "/manifests/" + cosignTag)
@ -2841,7 +2946,20 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(2 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"finished syncing", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
// should not be synced nor sync on demand // should not be synced nor sync on demand
resp, err = resty.R().SetHeader("Content-Type", "application/json"). resp, err = resty.R().SetHeader("Content-Type", "application/json").
@ -2858,14 +2976,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
So(len(index.Manifests), ShouldEqual, 0) So(len(index.Manifests), ShouldEqual, 0)
}) })
Convey("Trigger error on artifact references", func() { Convey("Trigger error on oci refs of both mediatypes", func() {
// trigger permission denied on image manifest
manifestPath := path.Join(srcDir, repoName, "blobs",
string(imageManifestDigest.Algorithm()), imageManifestDigest.Encoded())
err = os.Chmod(manifestPath, 0o000)
So(err, ShouldBeNil)
// trigger permission error on upstream
artifactURLPath := path.Join("/v2", repoName, "referrers", imageManifestDigest.String()) artifactURLPath := path.Join("/v2", repoName, "referrers", imageManifestDigest.String())
// based on image manifest digest get referrers // based on image manifest digest get referrers
@ -2875,6 +2986,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
Get(srcBaseURL + artifactURLPath) Get(srcBaseURL + artifactURLPath)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp, ShouldNotBeEmpty) So(resp, ShouldNotBeEmpty)
var referrers ispec.Index var referrers ispec.Index
@ -2882,7 +2994,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
err = json.Unmarshal(resp.Body(), &referrers) err = json.Unmarshal(resp.Body(), &referrers)
So(err, ShouldBeNil) So(err, ShouldBeNil)
Convey("of type OCI image", func() { Convey("of type OCI image", func() { //nolint: dupl
// read manifest // read manifest
var artifactManifest ispec.Manifest var artifactManifest ispec.Manifest
for _, ref := range referrers.Manifests { for _, ref := range referrers.Manifests {
@ -2908,15 +3020,34 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(2 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't copy referrer for", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
// should not be synced nor sync on demand // should not be synced nor sync on demand
resp, err = resty.R().Get(destBaseURL + artifactURLPath) resp, err = resty.R().Get(destBaseURL + artifactURLPath)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusOK)
var index ispec.Index
err = json.Unmarshal(resp.Body(), &index)
So(err, ShouldBeNil)
So(len(index.Manifests), ShouldEqual, 0)
}) })
Convey("of type OCI artifact", func() { Convey("of type OCI artifact", func() { //nolint: dupl
// read manifest // read manifest
var artifactManifest ispec.Artifact var artifactManifest ispec.Artifact
for _, ref := range referrers.Manifests { for _, ref := range referrers.Manifests {
@ -2942,12 +3073,31 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(2 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't copy referrer for", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
// should not be synced nor sync on demand // should not be synced nor sync on demand
resp, err = resty.R().Get(destBaseURL + artifactURLPath) resp, err = resty.R().Get(destBaseURL + artifactURLPath)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusOK)
var index ispec.Index
err = json.Unmarshal(resp.Body(), &index)
So(err, ShouldBeNil)
So(len(index.Manifests), ShouldEqual, 0)
}) })
}) })
}) })
@ -3438,7 +3588,20 @@ func TestOnDemandRetryGoroutine(t *testing.T) {
defer scm.StopServer() defer scm.StopServer()
// in the meantime ondemand should retry syncing // in the meantime ondemand should retry syncing
time.Sleep(15 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"successfully synced image", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
// now we should have the image synced // now we should have the image synced
binfo, err := os.Stat(path.Join(destDir, testImage, "index.json")) binfo, err := os.Stat(path.Join(destDir, testImage, "index.json"))
@ -3449,6 +3612,11 @@ func TestOnDemandRetryGoroutine(t *testing.T) {
resp, err = destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err = destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK) So(resp.StatusCode(), ShouldEqual, http.StatusOK)
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}) })
} }
@ -3548,8 +3716,19 @@ func TestOnDemandRetryGoroutineErr(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
// in the meantime ondemand should retry syncing and finish with error found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
time.Sleep(3 * time.Second) "sync routine: error while copying image", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err = destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err = destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -3806,6 +3985,21 @@ func TestError(t *testing.T) {
err = os.Chmod(localRepoPath, 0o000) err = os.Chmod(localRepoPath, 0o000)
So(err, ShouldBeNil) So(err, ShouldBeNil)
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"finished syncing", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := client.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err := client.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
@ -4033,15 +4227,35 @@ func TestSignaturesOnDemand(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK) So(resp.StatusCode(), ShouldEqual, http.StatusOK)
time.Sleep(3 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't find any oci reference", 15*time.Second)
body, err := os.ReadFile(path.Join(destDir, "sync.log"))
if err != nil { if err != nil {
log.Fatalf("unable to read file: %v", err) panic(err)
} }
So(string(body), ShouldContainSubstring, "couldn't find any oci reference") if !found {
So(string(body), ShouldContainSubstring, "couldn't find upstream referrer") data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
found, err = test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't find upstream referrer", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
}) })
} }
@ -4223,14 +4437,20 @@ func TestSyncOnlyDiff(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK) So(resp.StatusCode(), ShouldEqual, http.StatusOK)
time.Sleep(3 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"already synced image", 15*time.Second)
body, err := os.ReadFile(path.Join(destDir, "sync.log"))
if err != nil { if err != nil {
log.Fatalf("unable to read file: %v", err) panic(err)
} }
So(string(body), ShouldContainSubstring, "already synced image") if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
}) })
} }
@ -4579,8 +4799,35 @@ func TestSyncSignaturesDiff(t *testing.T) {
// compare cosign signatures // compare cosign signatures
So(reflect.DeepEqual(cosignManifest, syncedCosignManifest), ShouldEqual, true) So(reflect.DeepEqual(cosignManifest, syncedCosignManifest), ShouldEqual, true)
// let it sync one more time found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
time.Sleep(10 * time.Second) "skipping cosign signature", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
found, err = test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"skipping oci references", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
}) })
} }
@ -4632,7 +4879,20 @@ func TestOnlySignedFlag(t *testing.T) {
dcm.StartAndWait(dctlr.Config.HTTP.Port) dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer() defer dcm.StopServer()
time.Sleep(3 * time.Second) found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"skipping image without signature", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := client.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag) resp, err := client.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -5065,8 +5325,34 @@ func TestSyncOCIArtifactsWithTag(t *testing.T) {
So(reflect.DeepEqual(syncedManifest, manifest), ShouldEqual, true) So(reflect.DeepEqual(syncedManifest, manifest), ShouldEqual, true)
// sync again for coverage resp, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
time.Sleep(5 * time.Second) Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "2.0"))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Body(), ShouldNotBeEmpty)
So(resp.Header().Get("Content-Type"), ShouldNotBeEmpty)
var syncedArtifact ispec.Artifact
err = json.Unmarshal(resp.Body(), &syncedArtifact)
So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedArtifact, artifactManifest), ShouldEqual, true)
// for coverage
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"skipping OCI artifact", 15*time.Second)
if err != nil {
panic(err)
}
// if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
// }
So(found, ShouldBeTrue)
}) })
Convey("sync on demand", func() { Convey("sync on demand", func() {
@ -5092,6 +5378,19 @@ func TestSyncOCIArtifactsWithTag(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedArtifact, artifactManifest), ShouldEqual, true) So(reflect.DeepEqual(syncedArtifact, artifactManifest), ShouldEqual, true)
resp, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeImageManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "1.0"))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Body(), ShouldNotBeEmpty)
So(resp.Header().Get("Content-Type"), ShouldNotBeEmpty)
var syncedManifest ispec.Manifest
err = json.Unmarshal(resp.Body(), &syncedManifest)
So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedManifest, manifest), ShouldEqual, true)
}) })
Convey("sync periodically error on mediatype", func() { Convey("sync periodically error on mediatype", func() {
@ -5110,13 +5409,40 @@ func TestSyncOCIArtifactsWithTag(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
}() }()
// give it time to set up sync found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
time.Sleep(3 * time.Second) "finished syncing", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest). resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String())) Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound) So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
found, err = test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't get upstream image", 5*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
}) })
Convey("sync on demand error on mediatype", func() { Convey("sync on demand error on mediatype", func() {
@ -5159,6 +5485,8 @@ func TestSyncOCIArtifactsWithTag(t *testing.T) {
destConfig.Extensions.Search = nil destConfig.Extensions.Search = nil
destConfig.Extensions.Sync = syncConfig destConfig.Extensions.Sync = syncConfig
destConfig.Log.Output = path.Join(destDir, "zot.log")
dctlr := api.NewController(destConfig) dctlr := api.NewController(destConfig)
dcm := test.NewControllerManager(dctlr) dcm := test.NewControllerManager(dctlr)
@ -5175,6 +5503,21 @@ func TestSyncOCIArtifactsWithTag(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
}() }()
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't upload OCI artifact manifest", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest). resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String())) Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
So(err, ShouldBeNil) So(err, ShouldBeNil)

View file

@ -682,6 +682,9 @@ func syncImageWithRefs(ctx context.Context, localRepo, upstreamRepo, reference s
if mediaType == ispec.MediaTypeArtifactManifest { if mediaType == ispec.MediaTypeArtifactManifest {
err = sig.syncOCIArtifact(localRepo, upstreamRepo, reference, manifestBuf) //nolint err = sig.syncOCIArtifact(localRepo, upstreamRepo, reference, manifestBuf) //nolint
if err != nil { if err != nil {
log.Error().Err(err).Msgf("couldn't sync oci artifact with artifact mediaType: %s",
upstreamImageRef.DockerReference())
return skipped, err return skipped, err
} }
} }
@ -786,5 +789,7 @@ func syncImageWithRefs(ctx context.Context, localRepo, upstreamRepo, reference s
return skipped, err return skipped, err
} }
log.Info().Msgf("successfully synced image %s", upstreamImageRef.DockerReference())
return skipped, nil return skipped, nil
} }