refactor(test): new apis for creating temporary files (#3605)

Replace MakeTempFile usage with MakeTempFilePath and MakeTempFileWithContent
helpers that automatically handle file lifecycle. This prevents resource
leaks by ensuring temporary files are properly closed.

Shoudld also make the tests easier to read.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
This commit is contained in:
Andrei Aaron
2025-12-05 09:54:38 +02:00
committed by GitHub
parent 92aee8ebce
commit 9dfa7c3ae6
46 changed files with 1321 additions and 2612 deletions
+43 -79
View File
@@ -24,16 +24,12 @@ func TestConfigReloader(t *testing.T) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
logPath := test.MakeTempFilePath(t, "zot-log.txt")
username := "alice"
password := "alice"
htpasswdPath := test.MakeHtpasswdFileFromString(test.GetBcryptCredString(username, password))
defer os.Remove(htpasswdPath)
defer os.Remove(logFile.Name()) // clean up
htpasswdPath := test.MakeHtpasswdFileFromString(t, test.GetBcryptCredString(username, password))
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -72,19 +68,13 @@ func TestConfigReloader(t *testing.T) {
"level": "debug",
"output": "%s"
}
}`, t.TempDir(), port, htpasswdPath, logFile.Name())
}`, t.TempDir(), port, htpasswdPath, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
cfgfile := test.MakeTempFile(t, "zot-test.json")
defer cfgfile.Close()
_, err := cfgfile.WriteString(content)
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
// err = cfgfile.Close()
// So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
go func() {
@@ -95,7 +85,7 @@ func TestConfigReloader(t *testing.T) {
test.WaitTillServerReady(baseURL)
// verify initial startup authentication logs
initialData, err := os.ReadFile(logFile.Name())
initialData, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(initialData), ShouldContainSubstring, "configuration settings")
// verify authentication methods status messages are present in initial startup
@@ -145,7 +135,7 @@ func TestConfigReloader(t *testing.T) {
"level": "debug",
"output": "%s"
}
}`, t.TempDir(), port, htpasswdPath, logFile.Name())
}`, t.TempDir(), port, htpasswdPath, logPath)
err = cfgfile.Truncate(0)
So(err, ShouldBeNil)
@@ -162,7 +152,7 @@ func TestConfigReloader(t *testing.T) {
// wait for config reload
time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
t.Logf("log file: %s", data)
@@ -185,10 +175,8 @@ func TestConfigReloader(t *testing.T) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
logFile := test.MakeTempFile(t, "zot-log.txt")
defer logFile.Close()
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -214,17 +202,12 @@ func TestConfigReloader(t *testing.T) {
}
}`, t.TempDir(), t.TempDir(), port, logFile.Name())
cfgfile, err := os.CreateTemp("", "zot-test*.json")
cfgfile := test.MakeTempFile(t, "zot-test.json")
defer cfgfile.Close()
_, err := cfgfile.WriteString(content)
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
// err = cfgfile.Close()
// So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
go func() {
@@ -280,6 +263,8 @@ func TestConfigReloader(t *testing.T) {
// truncate log before changing config, for the ShouldNotContainString
So(logFile.Truncate(0), ShouldBeNil)
err = logFile.Close()
So(err, ShouldBeNil)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
@@ -315,10 +300,7 @@ func TestConfigReloader(t *testing.T) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
logPath := test.MakeTempFilePath(t, "zot-log.txt")
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -354,19 +336,14 @@ func TestConfigReloader(t *testing.T) {
}]
}
}
}`, t.TempDir(), port, logFile.Name())
}`, t.TempDir(), port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
cfgfile := test.MakeTempFile(t, "zot-test.json")
defer cfgfile.Close()
_, err := cfgfile.WriteString(content)
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
// err = cfgfile.Close()
// So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
go func() {
@@ -377,7 +354,7 @@ func TestConfigReloader(t *testing.T) {
test.WaitTillServerReady(baseURL)
// verify initial startup authentication logs (no auth configured)
initialData, err := os.ReadFile(logFile.Name())
initialData, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(initialData), ShouldContainSubstring, "configuration settings")
// verify authentication methods status messages are present in initial startup
@@ -424,7 +401,7 @@ func TestConfigReloader(t *testing.T) {
}]
}
}
}`, t.TempDir(), port, logFile.Name())
}`, t.TempDir(), port, logPath)
err = cfgfile.Truncate(0)
So(err, ShouldBeNil)
@@ -441,7 +418,7 @@ func TestConfigReloader(t *testing.T) {
// wait for config reload
time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
t.Logf("log file: %s", data)
@@ -471,10 +448,7 @@ func TestConfigReloader(t *testing.T) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
logPath := test.MakeTempFilePath(t, "zot-log.txt")
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -503,14 +477,12 @@ func TestConfigReloader(t *testing.T) {
"interval": "24h"
}
}
}`, t.TempDir(), port, logFile.Name())
}`, t.TempDir(), port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
cfgfile := test.MakeTempFile(t, "zot-test.json")
defer cfgfile.Close()
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
_, err := cfgfile.WriteString(content)
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
@@ -523,7 +495,7 @@ func TestConfigReloader(t *testing.T) {
test.WaitTillServerReady(baseURL)
// verify initial startup authentication logs (no auth configured)
initialData, err := os.ReadFile(logFile.Name())
initialData, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(initialData), ShouldContainSubstring, "configuration settings")
// verify authentication methods status messages are present in initial startup
@@ -559,7 +531,7 @@ func TestConfigReloader(t *testing.T) {
}
}
}
}`, t.TempDir(), port, logFile.Name())
}`, t.TempDir(), port, logPath)
err = cfgfile.Truncate(0)
So(err, ShouldBeNil)
@@ -577,13 +549,13 @@ func TestConfigReloader(t *testing.T) {
time.Sleep(5 * time.Second)
// Wait for the async trivy download to fail and log the error
found, err := test.ReadLogFileAndSearchString(logFile.Name(),
found, err := test.ReadLogFileAndSearchString(logPath,
"failed to download trivy-db to destination dir", 30*time.Second)
So(err, ShouldBeNil)
So(found, ShouldBeTrue)
// Now read the file once and check all the expected log content
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
t.Logf("log file: %s", data)
@@ -605,7 +577,7 @@ func TestConfigReloader(t *testing.T) {
// Just verify the new URL appears in the logs to confirm config reload worked and ignore
// the order of json message formatting that can change independent of this functional
// test.
found, err = test.ReadLogFileAndSearchString(logFile.Name(),
found, err = test.ReadLogFileAndSearchString(logPath,
"index.docker.io/another/unreachable/trivy/url2", 1*time.Minute)
So(err, ShouldBeNil)
So(found, ShouldBeTrue)
@@ -615,10 +587,7 @@ func TestConfigReloader(t *testing.T) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
logPath := test.MakeTempFilePath(t, "zot-log.txt")
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -654,19 +623,14 @@ func TestConfigReloader(t *testing.T) {
}]
}
}
}`, t.TempDir(), port, logFile.Name())
}`, t.TempDir(), port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
cfgfile := test.MakeTempFile(t, "zot-test.json")
defer cfgfile.Close()
_, err := cfgfile.WriteString(content)
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
// err = cfgfile.Close()
// So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
go func() {
@@ -693,7 +657,7 @@ func TestConfigReloader(t *testing.T) {
// wait for config reload
time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
t.Logf("log file: %s", data)
+100 -309
View File
@@ -26,10 +26,6 @@ func TestVerifyExtensionsConfig(t *testing.T) {
defer func() { os.Args = oldArgs }()
Convey("Test verify CVE warn for remote storage", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{
"storage":{
"rootDirectory":"%s",
@@ -58,10 +54,9 @@ func TestVerifyExtensionsConfig(t *testing.T) {
}
}`, t.TempDir())
err = os.WriteFile(tmpfile.Name(), []byte(content), 0o0600)
So(err, ShouldBeNil)
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldNotBeNil)
@@ -98,149 +93,99 @@ func TestVerifyExtensionsConfig(t *testing.T) {
}
}
}`, t.TempDir(), t.TempDir())
err = os.WriteFile(tmpfile.Name(), []byte(content), 0o0600)
So(err, ShouldBeNil)
tmpfile = MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldNotBeNil)
})
Convey("Test verify w/ sync and w/o filesystem storage", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s", "storageDriver": {"name": "s3"}},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 1, "retryDelay": "10s"}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldNotBeNil)
})
Convey("Test verify w/ sync and w/ filesystem storage", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 1, "retryDelay": "10s"}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldBeNil)
})
Convey("Test verify with bad sync prefixes", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 1, "retryDelay": "10s",
"content": [{"prefix":"[repo^&["}]}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldNotBeNil)
})
Convey("Test verify with bad sync content config", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 1, "retryDelay": "10s",
"content": [{"prefix":"zot-repo","stripPrefix":true,"destination":"/"}]}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldNotBeNil)
})
Convey("Test verify with good sync content config", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 1, "retryDelay": "10s",
"content": [{"prefix":"zot-repo/*","stripPrefix":true,"destination":"/"}]}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
err = cli.NewServerRootCmd().Execute()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile}
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
Convey("Test verify sync config default tls value", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 1, "retryDelay": "10s",
"content": [{"prefix":"repo**"}]}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
err = cli.NewServerRootCmd().Execute()
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile}
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
Convey("Test verify sync without retry options", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := fmt.Sprintf(`{"storage":{"rootDirectory":"%s"},
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
"maxRetries": 10, "content": [{"prefix":"repo**"}]}]}}}`, t.TempDir())
_, err = tmpfile.WriteString(content)
So(err, ShouldBeNil)
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "verify", tmpfile}
So(cli.NewServerRootCmd().Execute(), ShouldNotBeNil)
})
@@ -249,12 +194,8 @@ func TestVerifyExtensionsConfig(t *testing.T) {
func TestValidateExtensionsConfig(t *testing.T) {
Convey("Legacy extensions should not error", t, func(c C) {
config := config.New()
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name())
content := []byte(`{
content := `{
"storage": {
"rootDirectory": "%/tmp/zot"
},
@@ -273,22 +214,16 @@ func TestValidateExtensionsConfig(t *testing.T) {
"enable": "true"
}
}
}`)
err = os.WriteFile(tmpfile.Name(), content, 0o0600)
So(err, ShouldBeNil)
err = cli.LoadConfiguration(config, tmpfile.Name())
}`
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(config, tmpfile)
So(err, ShouldBeNil)
})
Convey("Test missing extensions for UI to work", t, func(c C) {
config := config.New()
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name())
content := []byte(`{
content := `{
"storage": {
"rootDirectory": "%/tmp/zot"
},
@@ -304,21 +239,15 @@ func TestValidateExtensionsConfig(t *testing.T) {
"enable": "true"
}
}
}`)
err = os.WriteFile(tmpfile.Name(), content, 0o0600)
So(err, ShouldBeNil)
err = cli.LoadConfiguration(config, tmpfile.Name())
}`
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(config, tmpfile)
So(err, ShouldNotBeNil)
})
Convey("Test enabling UI extension with all prerequisites", t, func(c C) {
config := config.New()
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name())
content := []byte(`{
content := `{
"storage": {
"rootDirectory": "%/tmp/zot"
},
@@ -337,21 +266,15 @@ func TestValidateExtensionsConfig(t *testing.T) {
"enable": "true"
}
}
}`)
err = os.WriteFile(tmpfile.Name(), content, 0o0600)
So(err, ShouldBeNil)
err = cli.LoadConfiguration(config, tmpfile.Name())
}`
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(config, tmpfile)
So(err, ShouldBeNil)
})
Convey("Test extension are implicitly enabled", t, func(c C) {
config := config.New()
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name())
content := []byte(`{
content := `{
"storage": {
"rootDirectory": "%/tmp/zot"
},
@@ -369,10 +292,9 @@ func TestValidateExtensionsConfig(t *testing.T) {
"trust": {},
"scrub": {}
}
}`)
err = os.WriteFile(tmpfile.Name(), content, 0o0600)
So(err, ShouldBeNil)
err = cli.LoadConfiguration(config, tmpfile.Name())
}`
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
err := cli.LoadConfiguration(config, tmpfile)
So(err, ShouldBeNil)
So(config.Extensions.UI, ShouldNotBeNil)
So(*config.Extensions.UI.Enable, ShouldBeTrue)
@@ -395,10 +317,7 @@ func TestServeExtensions(t *testing.T) {
Convey("config file with no extensions", t, func(c C) {
port := GetFreePort()
baseURL := GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
logPath := MakeTempFilePath(t, "zot-log.txt")
tmpFile := t.TempDir()
@@ -414,29 +333,22 @@ func TestServeExtensions(t *testing.T) {
"level": "debug",
"output": "%s"
}
}`, tmpFile, port, logFile.Name())
}`, tmpFile, port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
cfgfile := MakeTempFileWithContent(t, "zot-test.json", content)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
os.Args = []string{"cli_test", "serve", cfgfile}
go func() {
Convey("run", t, func() {
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
}()
WaitTillServerReady(baseURL)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "\"Extensions\":null")
@@ -445,10 +357,7 @@ func TestServeExtensions(t *testing.T) {
Convey("config file with empty extensions", t, func(c C) {
port := GetFreePort()
baseURL := GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
logPath := MakeTempFilePath(t, "zot-log.txt")
tmpFile := t.TempDir()
@@ -466,28 +375,21 @@ func TestServeExtensions(t *testing.T) {
},
"extensions": {
}
}`, tmpFile, port, logFile.Name())
}`, tmpFile, port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
cfgfile := MakeTempFileWithContent(t, "zot-test.json", content)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
os.Args = []string{"cli_test", "serve", cfgfile}
go func() {
Convey("run", t, func() {
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
}()
WaitTillServerReady(baseURL)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":null,\"UI\":null,\"Mgmt\":null") //nolint:lll // gofumpt conflicts with lll
@@ -498,27 +400,16 @@ func testWithMetricsEnabled(t *testing.T, rootDir string, cfgContentFormat strin
t.Helper()
port := GetFreePort()
baseURL := GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
logPath := MakeTempFilePath(t, "zot-log.txt")
defer os.Remove(logFile.Name()) // clean up
content := fmt.Sprintf(cfgContentFormat, rootDir, port, logPath)
cfgfile := MakeTempFileWithContent(t, "zot-test.json", content)
content := fmt.Sprintf(cfgContentFormat, rootDir, port, logFile.Name())
cfgfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
os.Args = []string{"cli_test", "serve", cfgfile}
go func() {
Convey("run", t, func() {
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
}()
@@ -532,7 +423,7 @@ func testWithMetricsEnabled(t *testing.T, rootDir string, cfgContentFormat strin
respStr := string(resp.Body())
So(respStr, ShouldContainSubstring, "zot_info")
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring,
"\"Metrics\":{\"Enable\":true,\"Prometheus\":{\"Path\":\"/metrics\"}}")
@@ -619,11 +510,9 @@ func TestServeMetricsExtension(t *testing.T) {
Convey("with explicit disable", t, func(c C) {
port := GetFreePort()
baseURL := GetBaseURL(port)
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
tmpFile := t.TempDir()
logPath := MakeTempFilePath(t, "zot-log.txt")
defer os.Remove(logFile.Name()) // clean up
tmpFile := t.TempDir()
content := fmt.Sprintf(`{
"storage": {
@@ -642,22 +531,15 @@ func TestServeMetricsExtension(t *testing.T) {
"enable": false
}
}
}`, tmpFile, port, logFile.Name())
}`, tmpFile, port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
cfgfile := MakeTempFileWithContent(t, "zot-test.json", content)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
os.Args = []string{"cli_test", "serve", cfgfile}
go func() {
Convey("run", t, func() {
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
}()
@@ -669,7 +551,7 @@ func TestServeMetricsExtension(t *testing.T) {
So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring,
"\"Metrics\":{\"Enable\":false,\"Prometheus\":{\"Path\":\"/metrics\"}}") //nolint:lll // gofumpt conflicts with lll
@@ -717,13 +599,11 @@ func TestServeSyncExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":{\"Enable\":true")
})
@@ -765,13 +645,11 @@ func TestServeSyncExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":{\"Enable\":true")
})
@@ -803,13 +681,11 @@ func TestServeSyncExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":{\"Enable\":false")
})
@@ -839,13 +715,11 @@ func TestServeScrubExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
dataStr := string(data)
So(dataStr, ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":{\"Enable\":true,\"Interval\":86400000000000},\"Lint\":null") //nolint:lll // gofumpt conflicts with lll
@@ -873,13 +747,11 @@ func TestServeScrubExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
// Even if in config we specified scrub interval=1h, the minimum interval is 2h
dataStr := string(data)
So(dataStr, ShouldContainSubstring, "\"Scrub\":{\"Enable\":true,\"Interval\":7200000000000}")
@@ -907,13 +779,11 @@ func TestServeScrubExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
dataStr := string(data)
So(dataStr, ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":{\"Enable\":true,\"Interval\":86400000000000},\"Lint\":null") //nolint:lll // gofumpt conflicts with lll
@@ -941,13 +811,11 @@ func TestServeScrubExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
dataStr := string(data)
So(dataStr, ShouldContainSubstring, "\"Scrub\":{\"Enable\":false,\"Interval\":86400000000000}")
So(dataStr, ShouldContainSubstring, "scrub config not provided, skipping scrub")
@@ -982,13 +850,11 @@ func TestServeLintExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":{\"Enable\":true,\"MandatoryAnnotations\":") //nolint:lll // gofumpt conflicts with lll
})
@@ -1013,13 +879,11 @@ func TestServeLintExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null,\"Lint\":{\"Enable\":false,\"MandatoryAnnotations\":null}") //nolint:lll // gofumpt conflicts with lll
})
@@ -1049,11 +913,9 @@ func TestServeSearchEnabled(t *testing.T) {
}
}`
tempDir := t.TempDir()
logPath, err := runCLIWithConfig(tempDir, content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
// to avoid data race when multiple go routines write to trivy DB instance.
defer os.Remove(logPath) // clean up
substring := `"Extensions":{"Search":{"Enable":true,"CVE":null}`
@@ -1097,14 +959,11 @@ func TestServeSearchEnabledDefaultCVEDB(t *testing.T) {
}
}`
tempDir := t.TempDir()
logPath, err := runCLIWithConfig(tempDir, content)
logPath, rootDir, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
// to avoid data race when multiple go routines write to trivy DB instance.
WaitTillTrivyDBDownloadStarted(tempDir)
WaitTillTrivyDBDownloadStarted(rootDir)
// The default config handling logic will convert the 1h interval to a 2h interval
substring := "\"Search\":{\"Enable\":true,\"CVE\":{\"UpdateInterval\":7200000000000,\"Trivy\":" +
@@ -1154,12 +1013,9 @@ func TestServeSearchEnabledNoCVE(t *testing.T) {
}
}`
tempDir := t.TempDir()
logPath, err := runCLIWithConfig(tempDir, content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
substring := `"Extensions":{"Search":{"Enable":true,"CVE":null}` //nolint:lll // gofumpt conflicts with lll
found, err := ReadLogFileAndSearchString(logPath, substring, readLogFileTimeout)
@@ -1202,13 +1058,11 @@ func TestServeSearchDisabled(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
dataStr := string(data)
So(dataStr, ShouldContainSubstring,
`"Search":{"Enable":false,"CVE":{"UpdateInterval":10800000000000,"Trivy":null}`)
@@ -1243,9 +1097,8 @@ func TestServeMgmtExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath, "setting up mgmt routes", 10*time.Second)
@@ -1276,9 +1129,8 @@ func TestServeMgmtExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath,
"skip enabling the mgmt route as the config prerequisites are not met", 10*time.Second)
@@ -1308,9 +1160,8 @@ func TestServeMgmtExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath,
"skip enabling the mgmt route as the config prerequisites are not met", 10*time.Second)
@@ -1351,9 +1202,8 @@ func TestServeImageTrustExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath,
"skip enabling the image trust routes as the config prerequisites are not met", 10*time.Second)
@@ -1388,9 +1238,8 @@ func TestServeImageTrustExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath,
"skip enabling the image trust routes as the config prerequisites are not met", 10*time.Second)
@@ -1427,9 +1276,8 @@ func TestServeImageTrustExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath,
"setting up image trust routes", 10*time.Second)
@@ -1463,10 +1311,6 @@ func TestOverlappingSyncRetentionConfig(t *testing.T) {
defer func() { os.Args = oldArgs }()
Convey("Test verify without overlapping sync and retention", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := `{
"distSpecVersion": "1.1.1",
"storage": {
@@ -1521,21 +1365,15 @@ func TestOverlappingSyncRetentionConfig(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldNotContainSubstring, "overlapping sync content")
})
Convey("Test verify with overlapping sync and retention - retention would remove v4 tags", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := `{
"distSpecVersion": "1.1.1",
"storage": {
@@ -1588,21 +1426,15 @@ func TestOverlappingSyncRetentionConfig(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring, "overlapping sync content\":{\"Prefix\":\"infra/*")
})
Convey("Test verify with overlapping sync and retention - retention would remove tags from repo", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := `{
"distSpecVersion": "1.1.1",
"storage": {
@@ -1653,21 +1485,15 @@ func TestOverlappingSyncRetentionConfig(t *testing.T) {
}
`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring, "overlapping sync content\":{\"Prefix\":\"**")
})
Convey("Test verify with overlapping sync and retention - retention would remove tags from subpath", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := `{
"distSpecVersion": "1.1.1",
"storage": {
@@ -1721,13 +1547,11 @@ func TestOverlappingSyncRetentionConfig(t *testing.T) {
}
`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldContainSubstring, "overlapping sync content\":{\"Prefix\":\"prod/*")
})
}
@@ -1738,10 +1562,6 @@ func TestSyncWithRemoteStorageConfig(t *testing.T) {
defer func() { os.Args = oldArgs }()
Convey("Test verify sync with remote storage works if sync.tmpdir is provided", t, func(c C) {
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
content := `{
"distSpecVersion": "1.1.1",
"storage": {
@@ -1787,29 +1607,19 @@ func TestSyncWithRemoteStorageConfig(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
So(string(data), ShouldNotContainSubstring,
"using both sync and remote storage features needs config.Extensions.Sync.DownloadDir to be specified")
})
Convey("Test verify sync with remote storage panics if sync.tmpdir is not provided", t, func(c C) {
port := GetFreePort()
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
logPath := MakeTempFilePath(t, "zot-log.txt")
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -1853,35 +1663,24 @@ func TestSyncWithRemoteStorageConfig(t *testing.T) {
]
}
}
}`, t.TempDir(), port, logFile.Name())
}`, t.TempDir(), port, logPath)
err = os.WriteFile(tmpfile.Name(), []byte(content), 0o0600)
So(err, ShouldBeNil)
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "serve", tmpfile.Name()}
err = cli.NewServerRootCmd().Execute()
os.Args = []string{"cli_test", "serve", tmpfile}
err := cli.NewServerRootCmd().Execute()
So(err, ShouldNotBeNil)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
So(string(data), ShouldContainSubstring,
"using both sync and remote storage features needs config.Extensions.Sync.DownloadDir to be specified")
})
Convey("Test verify sync with remote storage on subpath panics if sync.tmpdir is not provided", t, func(c C) {
port := GetFreePort()
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
tmpfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(tmpfile.Name()) // clean up
logPath := MakeTempFilePath(t, "zot-log.txt")
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
@@ -1929,18 +1728,16 @@ func TestSyncWithRemoteStorageConfig(t *testing.T) {
]
}
}
}`, t.TempDir(), t.TempDir(), port, logFile.Name())
}`, t.TempDir(), t.TempDir(), port, logPath)
err = os.WriteFile(tmpfile.Name(), []byte(content), 0o0600)
So(err, ShouldBeNil)
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
os.Args = []string{"cli_test", "serve", tmpfile.Name()}
err = cli.NewServerRootCmd().Execute()
os.Args = []string{"cli_test", "serve", tmpfile}
err := cli.NewServerRootCmd().Execute()
So(err, ShouldNotBeNil)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
So(string(data), ShouldContainSubstring,
"using both sync and remote storage features needs config.Extensions.Sync.DownloadDir to be specified")
@@ -1972,9 +1769,8 @@ func TestEventsExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
logPath, _, err := runCLIWithConfig(t, content)
So(err, ShouldBeNil)
defer os.Remove(logPath) // clean up
found, err := ReadLogFileAndSearchString(logPath,
"events disabled in configuration", 10*time.Second)
@@ -2012,12 +1808,7 @@ func TestEventsExtension(t *testing.T) {
}
}`
logPath, err := runCLIWithConfig(t.TempDir(), content)
defer func(p string) {
if p != "" {
os.Remove(p)
}
}(logPath) // clean up
_, _, err := runCLIWithConfig(t, content)
So(err, ShouldNotBeNil)
So(err.Error(), ShouldContainSubstring, zerr.ErrUnsupportedEventSink.Error())
})
+500 -1080
View File
File diff suppressed because it is too large Load Diff
+11 -19
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"sync"
"syscall"
"testing"
@@ -43,20 +44,19 @@ func TestStressTooManyOpenFiles(t *testing.T) {
conf.Storage.Dedupe = false
conf.Storage.GC = true
logFile, err := os.CreateTemp("", "zot-log*.txt")
So(err, ShouldBeNil)
tempDir := t.TempDir()
logPath := test.MakeTempFilePath(t, "zot-log.txt")
defer func() {
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
if err != nil {
t.Logf("error when reading zot log file:\n%s\n", err)
}
t.Logf("\n\n Zot log file content:\n%s\n", string(data))
os.Remove(logFile.Name())
}()
t.Log("Log file is: ", logFile.Name())
conf.Log.Output = logFile.Name()
t.Log("Log file is: ", logPath)
conf.Log.Output = logPath
ctlr := api.NewController(conf)
dir := t.TempDir()
@@ -92,16 +92,9 @@ func TestStressTooManyOpenFiles(t *testing.T) {
"level": "debug",
"output": "%s"
}
}`, dir, conf.Storage.Dedupe, conf.Storage.GC, port, logFile.Name())
}`, dir, conf.Storage.Dedupe, conf.Storage.GC, port, logPath)
cfgfile, err := os.CreateTemp("", "zot-test*.json")
So(err, ShouldBeNil)
defer os.Remove(cfgfile.Name()) // clean up
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
cfgfile := test.MakeTempFileWithContent(t, "zot-test.json", content)
skopeoArgs := []string{
"copy", "--format=oci", "--insecure-policy", "--dest-tls-verify=false",
@@ -134,14 +127,14 @@ func TestStressTooManyOpenFiles(t *testing.T) {
_, err = setMaxOpenFilesLimit(initialLimit)
So(err, ShouldBeNil)
data, err := os.ReadFile(logFile.Name())
data, err := os.ReadFile(logPath)
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "too many open files")
ctrlManager.StopServer()
time.Sleep(2 * time.Second)
scrubFile, err := os.CreateTemp("", "zot-scrub*.txt")
scrubFile, err := os.Create(filepath.Join(tempDir, "zot-scrub.txt"))
So(err, ShouldBeNil)
defer func() {
@@ -151,11 +144,10 @@ func TestStressTooManyOpenFiles(t *testing.T) {
}
t.Logf("\n\n Zot scrub file content:\n%s\n", string(data))
os.Remove(scrubFile.Name())
}()
t.Log("Scrub file is: ", scrubFile.Name())
os.Args = []string{"cli_test", "scrub", cfgfile.Name()}
os.Args = []string{"cli_test", "scrub", cfgfile}
cobraCmd := cli.NewServerRootCmd()
cobraCmd.SetOut(scrubFile)
err = cobraCmd.Execute()
+44 -67
View File
@@ -50,37 +50,33 @@ func TestRetentionCheckNegative(t *testing.T) {
})
Convey("non-existent config", t, func(c C) {
os.Args = []string{"cli_test", "verify-feature", "retention", path.Join(os.TempDir(), "/x.yaml")}
tempDir := t.TempDir()
os.Args = []string{"cli_test", "verify-feature", "retention", path.Join(tempDir, "/x.yaml")}
err := cli.NewServerRootCmd().Execute()
So(err, ShouldNotBeNil)
})
Convey("unknown config", t, func(c C) {
os.Args = []string{"cli_test", "verify-feature", "retention", path.Join(os.TempDir(), "/x")}
tempDir := t.TempDir()
os.Args = []string{"cli_test", "verify-feature", "retention", path.Join(tempDir, "/x")}
err := cli.NewServerRootCmd().Execute()
So(err, ShouldNotBeNil)
})
Convey("bad config", t, func(c C) {
testDir := t.TempDir()
configFile := path.Join(testDir, "zot-config.json")
content := []byte(`{"log":{}}`)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", `{"log":{}}`)
os.Args = []string{"cli_test", "verify-feature", "retention", "-t", "30s", configFile}
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldNotBeNil)
})
Convey("config with GC disabled", t, func(c C) {
testDir := t.TempDir()
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
port := GetFreePort()
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -91,11 +87,10 @@ func TestRetentionCheckNegative(t *testing.T) {
"port": "%s"
}
}`, testDir, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
os.Args = []string{"cli_test", "verify-feature", "retention", "-l", logFile, "-t", "30s", configFile}
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
// Verify the specific error
So(err, ShouldNotBeNil)
@@ -118,8 +113,7 @@ func TestRetentionCheckNegative(t *testing.T) {
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
controller.Config.Storage.RootDirectory = storageDir
controller.Config.Storage.GC = true
@@ -128,7 +122,7 @@ func TestRetentionCheckNegative(t *testing.T) {
defer ctrlManager.StopServer()
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"storage": {
"rootDirectory": "%s",
"gc": true,
@@ -155,11 +149,10 @@ func TestRetentionCheckNegative(t *testing.T) {
}
}
`, storageDir, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
os.Args = []string{"cli_test", "verify-feature", "retention", "-l", logFile, "-t", "30s", configFile}
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldNotBeNil)
So(err, ShouldEqual, zerr.ErrServerIsRunning)
@@ -184,10 +177,9 @@ func TestRetentionCheckNegative(t *testing.T) {
for _, testCase := range testCases {
Convey(testCase.name, func() {
testDir := t.TempDir()
configFile := path.Join(testDir, "zot-config.json")
port := GetFreePort()
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -198,8 +190,7 @@ func TestRetentionCheckNegative(t *testing.T) {
"port": "%s"
}
}`, testDir, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
os.Args = []string{"cli_test", "verify-feature", "retention", "-l", testCase.logFile, "-t", "30s", configFile}
// This panics during logger initialization due to invalid log file location
@@ -223,11 +214,10 @@ func TestRetentionCheckNegative(t *testing.T) {
for _, testCase := range testCases {
Convey(testCase.name, func() {
testDir := t.TempDir()
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
port := GetFreePort()
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -238,8 +228,7 @@ func TestRetentionCheckNegative(t *testing.T) {
"port": "%s"
}
}`, testDir, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
args := []string{
"cli_test", "verify-feature", "retention", "-l", logFile,
@@ -253,7 +242,7 @@ func TestRetentionCheckNegative(t *testing.T) {
args = append(args, configFile)
os.Args = args
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
// Flag parsing should fail before reaching RunE
So(err, ShouldNotBeNil)
So(err.Error(), ShouldContainSubstring, "invalid duration")
@@ -272,10 +261,9 @@ func TestRetentionCheckWithRetentionEnabledAndRedisDriver(t *testing.T) {
port := GetFreePort()
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -311,12 +299,11 @@ func TestRetentionCheckWithRetentionEnabledAndRedisDriver(t *testing.T) {
}
}
`, storageDir, testGCDelay, miniRedis.Addr(), port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
// Create complex image setup before running verify-feature retention
conf := config.New()
err = cli.LoadConfiguration(conf, configFile)
err := cli.LoadConfiguration(conf, configFile)
So(err, ShouldBeNil)
// Initialize storage and metaDB using the same approach as gc tests
@@ -510,10 +497,9 @@ func TestRetentionCheckWithRetentionEnabled(t *testing.T) {
port := GetFreePort()
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -544,12 +530,11 @@ func TestRetentionCheckWithRetentionEnabled(t *testing.T) {
}
}
`, storageDir, testGCDelay, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
// Create complex image setup before running verify-feature retention
conf := config.New()
err = cli.LoadConfiguration(conf, configFile)
err := cli.LoadConfiguration(conf, configFile)
So(err, ShouldBeNil)
// Initialize storage and metaDB using the same approach as gc tests
@@ -801,10 +786,9 @@ func TestRetentionCheckWithDeleteReferrers(t *testing.T) {
port := GetFreePort()
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -836,12 +820,11 @@ func TestRetentionCheckWithDeleteReferrers(t *testing.T) {
}
}
`, storageDir, testGCDelay, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
// Create image setup before running verify-feature retention
conf := config.New()
err = cli.LoadConfiguration(conf, configFile)
err := cli.LoadConfiguration(conf, configFile)
So(err, ShouldBeNil)
// Initialize storage and metaDB
@@ -982,10 +965,9 @@ func TestRetentionCheckWithRetentionDisabled(t *testing.T) {
port := GetFreePort()
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -1002,12 +984,11 @@ func TestRetentionCheckWithRetentionDisabled(t *testing.T) {
}
}
`, storageDir, testGCDelay, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
// Create image setup for GC testing (no retention, no MetaDB needed)
conf := config.New()
err = cli.LoadConfiguration(conf, configFile)
err := cli.LoadConfiguration(conf, configFile)
So(err, ShouldBeNil)
// Initialize storage only (no MetaDB needed when retention is disabled)
@@ -1139,10 +1120,9 @@ func TestRetentionCheckWithSubpaths(t *testing.T) {
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
subpathStoreDir := path.Join(testDir, "storage2")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -1197,12 +1177,11 @@ func TestRetentionCheckWithSubpaths(t *testing.T) {
}
}
`, storageDir, testGCDelay, subpathStoreDir, testGCDelay, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
// Create image setup before running verify-feature retention
conf := config.New()
err = cli.LoadConfiguration(conf, configFile)
err := cli.LoadConfiguration(conf, configFile)
So(err, ShouldBeNil)
// Initialize storage and metaDB
@@ -1440,11 +1419,10 @@ func TestRetentionCheckWithGCIntervalOverride(t *testing.T) {
testDir := t.TempDir()
storageDir := path.Join(testDir, "storage")
subpathStoreDir := path.Join(testDir, "storage2")
configFile := path.Join(testDir, "zot-config.json")
logFile := path.Join(testDir, "retention-check.log")
logFile := MakeTempFilePath(t, "retention-check.log")
port := GetFreePort()
content := fmt.Appendf([]byte{}, `{
content := fmt.Sprintf(`{
"distSpecVersion": "1.1.1",
"storage": {
"rootDirectory": "%s",
@@ -1469,15 +1447,14 @@ func TestRetentionCheckWithGCIntervalOverride(t *testing.T) {
}
}
`, storageDir, testGCDelay, subpathStoreDir, testGCDelay, port)
err := os.WriteFile(configFile, content, 0o600)
So(err, ShouldBeNil)
configFile := MakeTempFileWithContent(t, "zot-config.json", content)
gcDelay, _ := time.ParseDuration(testGCDelay)
time.Sleep(gcDelay + 50*time.Millisecond) // wait for GC delay to pass
// Override GC interval from 1m to 30s using -i flag
os.Args = []string{"cli_test", "verify-feature", "retention", "-l", logFile, "-i", "30s", "-t", "5ms", configFile}
err = cli.NewServerRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
// Verify log file was created and contains expected messages