forgejo/modules/setting/forgejo_storage_test.go
Earl Warren 227d42a1b6
[TESTS] verify facts for the admin storage documentation
(cherry picked from commit 57e597bf7e)
(cherry picked from commit 643a2b0e81)
(cherry picked from commit f10faffb4f)
(cherry picked from commit b440c5767e)

[TESTS] verify facts for the admin storage documentation (squash)

(cherry picked from commit d83d8ce57b)
(cherry picked from commit d8855ef27c)
(cherry picked from commit 11230466ec)
(cherry picked from commit b2cdd9d971)
(cherry picked from commit a0a5e78524)
(cherry picked from commit 846413110f)
(cherry picked from commit 72b92d5a78)
(cherry picked from commit 7e039a9427)
2023-10-23 14:16:24 +02:00

263 lines
8.2 KiB
Go

// SPDX-License-Identifier: MIT
//
// Tests verifying the Forgejo documentation on storage settings is correct
//
// https://forgejo.org/docs/v1.20/admin/storage/
//
package setting
import (
"fmt"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestForgejoDocs_StorageTypes(t *testing.T) {
iniStr := `
[server]
APP_DATA_PATH = /
`
testStorageTypesDefaultAndSpecificStorage(t, iniStr)
}
func testStorageGetPath(storage *Storage) string {
if storage.Type == MinioStorageType {
return storage.MinioConfig.BasePath
}
return storage.Path
}
var testSectionToBasePath = map[string]string{
"attachment": "attachments",
"lfs": "lfs",
"avatar": "avatars",
"repo-avatar": "repo-avatars",
"repo-archive": "repo-archive",
"packages": "packages",
"storage.actions_log": "actions_log",
"actions.artifacts": "actions_artifacts",
}
type testSectionToPathFun func(StorageType, string) string
func testBuildPath(t StorageType, path string) string {
if t == LocalStorageType {
return "/" + path
}
return path + "/"
}
func testSectionToPath(t StorageType, section string) string {
return testBuildPath(t, testSectionToBasePath[section])
}
func testSpecificPath(t StorageType, section string) string {
if t == LocalStorageType {
return "/specific_local_path"
}
return "specific_s3_base_path/"
}
func testDefaultDir(t StorageType) string {
if t == LocalStorageType {
return "default_local_path"
}
return "default_s3_base_path"
}
func testDefaultPath(t StorageType) string {
return testBuildPath(t, testDefaultDir(t))
}
func testSectionToDefaultPath(t StorageType, section string) string {
return testBuildPath(t, filepath.Join(testDefaultDir(t), testSectionToPath(t, section)))
}
func testLegacyPath(t StorageType, section string) string {
return testBuildPath(t, fmt.Sprintf("legacy_%s_path", section))
}
func testStorageTypeToSetting(t StorageType) string {
if t == LocalStorageType {
return "PATH"
}
return "MINIO_BASE_PATH"
}
var testSectionToLegacy = map[string]string{
"lfs": fmt.Sprintf(`
[server]
APP_DATA_PATH = /
LFS_CONTENT_PATH = %s
`, testLegacyPath(LocalStorageType, "lfs")),
"avatar": fmt.Sprintf(`
[picture]
AVATAR_UPLOAD_PATH = %s
`, testLegacyPath(LocalStorageType, "avatar")),
"repo-avatar": fmt.Sprintf(`
[picture]
REPOSITORY_AVATAR_UPLOAD_PATH = %s
`, testLegacyPath(LocalStorageType, "repo-avatar")),
}
func testStorageTypesDefaultAndSpecificStorage(t *testing.T, iniStr string) {
storageType := MinioStorageType
t.Run(string(storageType), func(t *testing.T) {
t.Run("override type minio", func(t *testing.T) {
storageSection := `
[storage]
STORAGE_TYPE = minio
`
testStorageTypesSpecificStorages(t, iniStr+storageSection, storageType, testSectionToPath, testSectionToPath)
})
})
storageType = LocalStorageType
t.Run(string(storageType), func(t *testing.T) {
storageSection := ""
testStorageTypesSpecificStorages(t, iniStr+storageSection, storageType, testSectionToPath, testSectionToPath)
t.Run("override type local", func(t *testing.T) {
storageSection := `
[storage]
STORAGE_TYPE = local
`
testStorageTypesSpecificStorages(t, iniStr+storageSection, storageType, testSectionToPath, testSectionToPath)
storageSection = fmt.Sprintf(`
[storage]
STORAGE_TYPE = local
PATH = %s
`, testDefaultPath(LocalStorageType))
testStorageTypesSpecificStorageSections(t, iniStr+storageSection, storageType, testSectionToDefaultPath, testSectionToPath)
})
})
}
func testStorageTypesSpecificStorageSections(t *testing.T, iniStr string, defaultStorageType StorageType, defaultStorageTypePath, testSectionToPath testSectionToPathFun) {
testSectionsMap := map[string]**Storage{
"attachment": &Attachment.Storage,
"lfs": &LFS.Storage,
"avatar": &Avatar.Storage,
"repo-avatar": &RepoAvatar.Storage,
"repo-archive": &RepoArchive.Storage,
"packages": &Packages.Storage,
// there are inconsistencies in how actions storage is determined in v1.20
// it is still alpha and undocumented and is ignored for now
//"storage.actions_log": &Actions.LogStorage,
//"actions.artifacts": &Actions.ArtifactStorage,
}
for sectionName, storage := range testSectionsMap {
t.Run(sectionName, func(t *testing.T) {
testStorageTypesSpecificStorage(t, iniStr, defaultStorageType, defaultStorageTypePath, testSectionToPath, sectionName, storage)
})
}
}
func testStorageTypesSpecificStorages(t *testing.T, iniStr string, defaultStorageType StorageType, defaultStorageTypePath, testSectionToPath testSectionToPathFun) {
testSectionsMap := map[string]**Storage{
"attachment": &Attachment.Storage,
"lfs": &LFS.Storage,
"avatar": &Avatar.Storage,
"repo-avatar": &RepoAvatar.Storage,
"repo-archive": &RepoArchive.Storage,
"packages": &Packages.Storage,
"storage.actions_log": &Actions.LogStorage,
"actions.artifacts": &Actions.ArtifactStorage,
}
for sectionName, storage := range testSectionsMap {
t.Run(sectionName, func(t *testing.T) {
if legacy, ok := testSectionToLegacy[sectionName]; ok {
if defaultStorageType == LocalStorageType {
t.Run("legacy local", func(t *testing.T) {
testStorageTypesSpecificStorage(t, iniStr+legacy, LocalStorageType, testLegacyPath, testSectionToPath, sectionName, storage)
testStorageTypesSpecificStorageTypeOverride(t, iniStr+legacy, LocalStorageType, testLegacyPath, testSectionToPath, sectionName, storage)
})
} else {
t.Run("legacy minio", func(t *testing.T) {
testStorageTypesSpecificStorage(t, iniStr+legacy, MinioStorageType, defaultStorageTypePath, testSectionToPath, sectionName, storage)
testStorageTypesSpecificStorageTypeOverride(t, iniStr+legacy, LocalStorageType, testLegacyPath, testSectionToPath, sectionName, storage)
})
}
}
for _, specificStorageType := range storageTypes {
testStorageTypesSpecificStorageTypeOverride(t, iniStr, specificStorageType, defaultStorageTypePath, testSectionToPath, sectionName, storage)
}
})
}
}
func testStorageTypesSpecificStorage(t *testing.T, iniStr string, defaultStorageType StorageType, defaultStorageTypePath, testSectionToPath testSectionToPathFun, sectionName string, storage **Storage) {
var section string
//
// Specific section is absent
//
testStoragePathMatch(t, iniStr, defaultStorageType, defaultStorageTypePath, sectionName, storage)
//
// Specific section is empty
//
section = fmt.Sprintf(`
[%s]
`,
sectionName)
testStoragePathMatch(t, iniStr+section, defaultStorageType, defaultStorageTypePath, sectionName, storage)
//
// Specific section with a path override
//
section = fmt.Sprintf(`
[%s]
%s = %s
`,
sectionName,
testStorageTypeToSetting(defaultStorageType),
testSpecificPath(defaultStorageType, ""))
testStoragePathMatch(t, iniStr+section, defaultStorageType, testSpecificPath, sectionName, storage)
}
func testStorageTypesSpecificStorageTypeOverride(t *testing.T, iniStr string, overrideStorageType StorageType, defaultStorageTypePath, testSectionToPath testSectionToPathFun, sectionName string, storage **Storage) {
var section string
t.Run("specific-"+string(overrideStorageType), func(t *testing.T) {
//
// Specific section with a path and storage type override
//
section = fmt.Sprintf(`
[%s]
STORAGE_TYPE = %s
%s = %s
`,
sectionName,
overrideStorageType,
testStorageTypeToSetting(overrideStorageType),
testSpecificPath(overrideStorageType, ""))
testStoragePathMatch(t, iniStr+section, overrideStorageType, testSpecificPath, sectionName, storage)
//
// Specific section with type override
//
section = fmt.Sprintf(`
[%s]
STORAGE_TYPE = %s
`,
sectionName,
overrideStorageType)
testStoragePathMatch(t, iniStr+section, overrideStorageType, defaultStorageTypePath, sectionName, storage)
})
}
func testStoragePathMatch(t *testing.T, iniStr string, storageType StorageType, testSectionToPath testSectionToPathFun, section string, storage **Storage) {
cfg, err := NewConfigProviderFromData(iniStr)
assert.NoError(t, err, iniStr)
assert.NoError(t, loadCommonSettingsFrom(cfg), iniStr)
assert.EqualValues(t, testSectionToPath(storageType, section), testStorageGetPath(*storage), iniStr)
assert.EqualValues(t, storageType, (*storage).Type, iniStr)
}