dc3969cd05
Instead of re-inventing the wheel regarding configuration location handling and validation, this introduces a new command flag `--config` allowing for full flexibility of configuration filename and location. This flag can also be defined via environment variable which allows an easy way of starting the bot from command line, inside a Docker container or using the Helm Chart. It makes the custom environment lookup unnecessary and reduces some complexity during startup and for writing tests. Resolves: #10 Signed-off-by: Steven Kriegler <sk.bunsenbrenner@gmail.com>
292 lines
7.2 KiB
Go
292 lines
7.2 KiB
Go
package settings
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var defaultConfig []byte = []byte(
|
|
`gitea:
|
|
url: https://example.com/gitea
|
|
token:
|
|
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
|
webhook:
|
|
secret: haxxor-gitea-secret
|
|
sonarqube:
|
|
url: https://example.com/sonarqube
|
|
token:
|
|
value: a09eb5785b25bb2cbacf48808a677a0709f02d8e
|
|
webhook:
|
|
secret: haxxor-sonarqube-secret
|
|
additionalMetrics: []
|
|
projects:
|
|
- sonarqube:
|
|
key: gitea-sonarqube-pr-bot
|
|
gitea:
|
|
owner: example-organization
|
|
name: pr-bot
|
|
`)
|
|
|
|
func WriteConfigFile(t *testing.T, content []byte) string {
|
|
dir := os.TempDir()
|
|
config := path.Join(dir, "config.yaml")
|
|
|
|
t.Cleanup(func() {
|
|
os.Remove(config)
|
|
})
|
|
|
|
_ = ioutil.WriteFile(config, content, 0444)
|
|
|
|
return config
|
|
}
|
|
|
|
func TestLoadWithMissingFile(t *testing.T) {
|
|
assert.Panics(t, func() { Load(path.Join(os.TempDir(), "config.yaml")) }, "No panic while reading missing file")
|
|
}
|
|
|
|
func TestLoadWithExistingFile(t *testing.T) {
|
|
c := WriteConfigFile(t, defaultConfig)
|
|
|
|
assert.NotPanics(t, func() { Load(c) }, "Unexpected panic while reading existing file")
|
|
}
|
|
|
|
func TestLoadGiteaStructure(t *testing.T) {
|
|
c := WriteConfigFile(t, defaultConfig)
|
|
Load(c)
|
|
|
|
expected := GiteaConfig{
|
|
Url: "https://example.com/gitea",
|
|
Token: &Token{
|
|
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "haxxor-gitea-secret",
|
|
},
|
|
}
|
|
|
|
assert.EqualValues(t, expected, Gitea)
|
|
}
|
|
|
|
func TestLoadGiteaStructureInjectedEnvs(t *testing.T) {
|
|
os.Setenv("PRBOT_GITEA_WEBHOOK_SECRET", "injected-webhook-secret")
|
|
os.Setenv("PRBOT_GITEA_TOKEN_VALUE", "injected-token")
|
|
c := WriteConfigFile(t, defaultConfig)
|
|
Load(c)
|
|
|
|
expected := GiteaConfig{
|
|
Url: "https://example.com/gitea",
|
|
Token: &Token{
|
|
Value: "injected-token",
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "injected-webhook-secret",
|
|
},
|
|
}
|
|
|
|
assert.EqualValues(t, expected, Gitea)
|
|
|
|
t.Cleanup(func() {
|
|
os.Unsetenv("PRBOT_GITEA_WEBHOOK_SECRET")
|
|
os.Unsetenv("PRBOT_GITEA_TOKEN_VALUE")
|
|
})
|
|
}
|
|
|
|
func TestLoadSonarQubeStructure(t *testing.T) {
|
|
c := WriteConfigFile(t, defaultConfig)
|
|
Load(c)
|
|
|
|
expected := SonarQubeConfig{
|
|
Url: "https://example.com/sonarqube",
|
|
Token: &Token{
|
|
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "haxxor-sonarqube-secret",
|
|
},
|
|
}
|
|
|
|
assert.EqualValues(t, expected, SonarQube)
|
|
assert.EqualValues(t, expected.GetMetricsList(), "bugs,vulnerabilities,code_smells")
|
|
}
|
|
|
|
func TestLoadSonarQubeStructureWithAdditionalMetrics(t *testing.T) {
|
|
c := WriteConfigFile(t, []byte(
|
|
`gitea:
|
|
url: https://example.com/gitea
|
|
token:
|
|
value: fake-gitea-token
|
|
sonarqube:
|
|
url: https://example.com/sonarqube
|
|
token:
|
|
value: fake-sonarqube-token
|
|
additionalMetrics: "new_security_hotspots"
|
|
projects:
|
|
- sonarqube:
|
|
key: gitea-sonarqube-pr-bot
|
|
gitea:
|
|
owner: example-organization
|
|
name: pr-bot
|
|
`))
|
|
Load(c)
|
|
|
|
expected := SonarQubeConfig{
|
|
Url: "https://example.com/sonarqube",
|
|
Token: &Token{
|
|
Value: "fake-sonarqube-token",
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "",
|
|
},
|
|
AdditionalMetrics: []string{
|
|
"new_security_hotspots",
|
|
},
|
|
}
|
|
|
|
assert.EqualValues(t, expected, SonarQube)
|
|
assert.EqualValues(t, expected.AdditionalMetrics, []string{"new_security_hotspots"})
|
|
assert.EqualValues(t, "bugs,vulnerabilities,code_smells,new_security_hotspots", SonarQube.GetMetricsList())
|
|
}
|
|
|
|
func TestLoadSonarQubeStructureInjectedEnvs(t *testing.T) {
|
|
os.Setenv("PRBOT_SONARQUBE_WEBHOOK_SECRET", "injected-webhook-secret")
|
|
os.Setenv("PRBOT_SONARQUBE_TOKEN_VALUE", "injected-token")
|
|
c := WriteConfigFile(t, defaultConfig)
|
|
Load(c)
|
|
|
|
expected := SonarQubeConfig{
|
|
Url: "https://example.com/sonarqube",
|
|
Token: &Token{
|
|
Value: "injected-token",
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "injected-webhook-secret",
|
|
},
|
|
}
|
|
|
|
assert.EqualValues(t, expected, SonarQube)
|
|
|
|
t.Cleanup(func() {
|
|
os.Unsetenv("PRBOT_SONARQUBE_WEBHOOK_SECRET")
|
|
os.Unsetenv("PRBOT_SONARQUBE_TOKEN_VALUE")
|
|
})
|
|
}
|
|
|
|
func TestLoadStructureWithFileReferenceResolving(t *testing.T) {
|
|
giteaWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-gitea")
|
|
_ = ioutil.WriteFile(giteaWebhookSecretFile, []byte(`gitea-totally-secret`), 0444)
|
|
|
|
giteaTokenFile := path.Join(os.TempDir(), "token-secret-gitea")
|
|
_ = ioutil.WriteFile(giteaTokenFile, []byte(`d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565`), 0444)
|
|
|
|
sonarqubeWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-sonarqube")
|
|
_ = ioutil.WriteFile(sonarqubeWebhookSecretFile, []byte(`sonarqube-totally-secret`), 0444)
|
|
|
|
sonarqubeTokenFile := path.Join(os.TempDir(), "token-secret-sonarqube")
|
|
_ = ioutil.WriteFile(sonarqubeTokenFile, []byte(`a09eb5785b25bb2cbacf48808a677a0709f02d8e`), 0444)
|
|
|
|
c := WriteConfigFile(t, []byte(
|
|
`gitea:
|
|
url: https://example.com/gitea
|
|
token:
|
|
value: fake-gitea-token
|
|
sonarqube:
|
|
url: https://example.com/sonarqube
|
|
token:
|
|
value: fake-sonarqube-token
|
|
projects:
|
|
- sonarqube:
|
|
key: gitea-sonarqube-pr-bot
|
|
gitea:
|
|
owner: example-organization
|
|
name: pr-bot
|
|
`))
|
|
os.Setenv("PRBOT_GITEA_WEBHOOK_SECRETFILE", giteaWebhookSecretFile)
|
|
os.Setenv("PRBOT_GITEA_TOKEN_FILE", giteaTokenFile)
|
|
os.Setenv("PRBOT_SONARQUBE_WEBHOOK_SECRETFILE", sonarqubeWebhookSecretFile)
|
|
os.Setenv("PRBOT_SONARQUBE_TOKEN_FILE", sonarqubeTokenFile)
|
|
|
|
expectedGitea := GiteaConfig{
|
|
Url: "https://example.com/gitea",
|
|
Token: &Token{
|
|
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
|
file: giteaTokenFile,
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "gitea-totally-secret",
|
|
secretFile: giteaWebhookSecretFile,
|
|
},
|
|
}
|
|
|
|
expectedSonarQube := SonarQubeConfig{
|
|
Url: "https://example.com/sonarqube",
|
|
Token: &Token{
|
|
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
|
|
file: sonarqubeTokenFile,
|
|
},
|
|
Webhook: &Webhook{
|
|
Secret: "sonarqube-totally-secret",
|
|
secretFile: sonarqubeWebhookSecretFile,
|
|
},
|
|
AdditionalMetrics: []string{},
|
|
}
|
|
|
|
Load(c)
|
|
assert.EqualValues(t, expectedGitea, Gitea)
|
|
assert.EqualValues(t, expectedSonarQube, SonarQube)
|
|
|
|
t.Cleanup(func() {
|
|
os.Remove(giteaWebhookSecretFile)
|
|
os.Remove(giteaTokenFile)
|
|
os.Remove(sonarqubeWebhookSecretFile)
|
|
os.Remove(sonarqubeTokenFile)
|
|
os.Unsetenv("PRBOT_GITEA_WEBHOOK_SECRETFILE")
|
|
os.Unsetenv("PRBOT_GITEA_TOKEN_FILE")
|
|
os.Unsetenv("PRBOT_SONARQUBE_WEBHOOK_SECRETFILE")
|
|
os.Unsetenv("PRBOT_SONARQUBE_TOKEN_FILE")
|
|
})
|
|
}
|
|
|
|
func TestLoadProjectsStructure(t *testing.T) {
|
|
c := WriteConfigFile(t, defaultConfig)
|
|
Load(c)
|
|
|
|
expectedProjects := []Project{
|
|
{
|
|
SonarQube: struct{ Key string }{
|
|
Key: "gitea-sonarqube-pr-bot",
|
|
},
|
|
Gitea: GiteaRepository{
|
|
Owner: "example-organization",
|
|
Name: "pr-bot",
|
|
},
|
|
},
|
|
}
|
|
|
|
assert.EqualValues(t, expectedProjects, Projects)
|
|
}
|
|
|
|
func TestLoadProjectsStructureWithNoMapping(t *testing.T) {
|
|
invalidConfig := []byte(
|
|
`gitea:
|
|
url: https://example.com/gitea
|
|
token:
|
|
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
|
webhook:
|
|
secret: haxxor-gitea-secret
|
|
sonarqube:
|
|
url: https://example.com/sonarqube
|
|
token:
|
|
value: a09eb5785b25bb2cbacf48808a677a0709f02d8e
|
|
webhook:
|
|
secret: haxxor-sonarqube-secret
|
|
projects: []
|
|
`)
|
|
c := WriteConfigFile(t, invalidConfig)
|
|
|
|
assert.Panics(t, func() { Load(c) }, "No panic for empty project mapping that is required")
|
|
}
|