feat(sync): move stream from global to per upstream

Signed-off-by: Vishwas Rajashekar <dev@vrajashkr.com>
This commit is contained in:
Vishwas Rajashekar
2026-05-19 00:55:07 +05:30
parent 63b7654d50
commit 14cd52e993
12 changed files with 198 additions and 28 deletions
+98
View File
@@ -3446,3 +3446,101 @@ func TestBearerASMConfigValidation(t *testing.T) {
})
})
}
func TestValidateStreamingSync(t *testing.T) {
Convey("Test streaming sync config validation", t, func() {
Convey("Valid streaming sync with onDemand enabled", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"onDemand": true, "stream": true}]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldBeNil)
})
Convey("Reject streaming sync when onDemand is false", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"onDemand": false, "stream": true}]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldNotBeNil)
So(err, ShouldWrap, zerr.ErrBadConfig)
So(err.Error(), ShouldContainSubstring, "streaming sync requires onDemand to be enabled")
})
Convey("Reject streaming sync when maxRetries is set", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"onDemand": true, "stream": true, "maxRetries": 3, "retryDelay": "10s"}]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldNotBeNil)
So(err, ShouldWrap, zerr.ErrBadConfig)
So(err.Error(), ShouldContainSubstring, "maxRetries cannot be used when streaming sync is enabled")
})
Convey("Reject streaming sync when retryDelay is set without maxRetries", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"onDemand": true, "stream": true, "retryDelay": "10s"}]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldNotBeNil)
So(err, ShouldWrap, zerr.ErrBadConfig)
So(err.Error(), ShouldContainSubstring, "retryDelay cannot be used when streaming sync is enabled")
})
Convey("Non-streaming sync allows maxRetries with retryDelay", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"onDemand": true, "maxRetries": 3, "retryDelay": "10s"}]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldBeNil)
})
Convey("Streaming registry and non-streaming registry can coexist", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [
{"urls":["localhost:9999"], "onDemand": true, "stream": true},
{"urls":["localhost:9998"], "onDemand": true, "maxRetries": 3, "retryDelay": "10s"}
]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldBeNil)
})
Convey("Streaming upstream and periodic sync upstreams can coexist", func() {
content := `{"storage":{"rootDirectory":"/tmp/zot"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [
{"urls":["localhost:9999"], "onDemand": true, "stream": true},
{"urls":["localhost:9998"], "onDemand": false, "pollInterval": "12h"}
]}}}`
cfg := config.New()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(cfg, tmpfile)
So(err, ShouldBeNil)
})
})
}