Files
trivy/pkg/cloud/config_test.go

346 lines
6.9 KiB
Go

package cloud
import (
"context"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zalando/go-keyring"
)
func TestSave(t *testing.T) {
tests := []struct {
name string
config *Config
wantErr bool
}{
{
name: "empty config",
config: &Config{},
wantErr: true,
},
{
name: "config with all fields",
config: &Config{
Token: "test-token-123",
Server: Server{
URL: "https://example.com",
},
Api: Api{
URL: "https://api.example.com",
},
},
wantErr: false,
},
{
name: "config without token",
config: &Config{
Server: Server{
URL: "https://example.com",
},
Api: Api{
URL: "https://api.example.com",
},
},
wantErr: false,
},
}
tempDir := t.TempDir()
t.Setenv("XDG_DATA_HOME", tempDir)
keyring.MockInit()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer keyring.DeleteAll(ServiceName)
defer Clear()
err := tt.config.Save()
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
config, err := Load()
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
assert.Equal(t, tt.config, config)
configPath := getConfigPath()
if tt.config.Server.URL != "" || tt.config.Api.URL != "" {
assert.FileExists(t, configPath)
}
})
}
}
func TestClear(t *testing.T) {
tests := []struct {
name string
createConfig bool
wantErr bool
}{
{
name: "success when nothing to clear",
wantErr: false,
},
{
name: "success when there is config to clear",
createConfig: true,
wantErr: false,
},
}
tempDir := t.TempDir()
t.Setenv("XDG_DATA_HOME", tempDir)
keyring.MockInit()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer keyring.DeleteAll(ServiceName)
defer Clear()
if tt.createConfig {
config := &Config{
Token: "testtoken",
Server: Server{
URL: "https://example.com",
},
}
err := config.Save()
require.NoError(t, err)
configPath := getConfigPath()
assert.FileExists(t, configPath)
}
err := Clear()
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
configPath := getConfigPath()
assert.NoFileExists(t, configPath)
})
}
}
func TestLoad(t *testing.T) {
tests := []struct {
name string
createConfig bool
expectDefault bool
}{
{
name: "success when there is config to load",
createConfig: true,
expectDefault: false,
},
{
name: "error when there is no config to load",
expectDefault: true,
},
}
tempDir := t.TempDir()
t.Setenv("XDG_DATA_HOME", tempDir)
keyring.MockInit()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer keyring.DeleteAll(ServiceName)
defer Clear()
token := "testtoken"
if tt.createConfig {
config := &Config{
Token: token,
Server: Server{
URL: "https://example.com",
},
Api: Api{
URL: "https://api.example.com",
},
}
err := config.Save()
require.NoError(t, err)
}
config, err := Load()
if tt.expectDefault {
assert.Equal(t, defaultConfig, config)
return
}
require.NotNil(t, config)
require.NoError(t, err)
assert.Equal(t, token, config.Token)
assert.Equal(t, "https://example.com", config.Server.URL)
assert.Equal(t, "https://api.example.com", config.Api.URL)
})
}
}
func TestVerify(t *testing.T) {
tests := []struct {
name string
config *Config
status int
wantErr bool
}{
{
name: "success with valid config",
config: &Config{Token: "testtoken", Server: Server{URL: "https://example.com"}, Api: Api{URL: "https://api.example.com"}},
status: http.StatusOK,
wantErr: false,
},
{
name: "error with invalid config",
config: &Config{},
status: http.StatusUnauthorized,
wantErr: true,
},
}
tempDir := t.TempDir()
t.Setenv("XDG_DATA_HOME", tempDir)
keyring.MockInit()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer keyring.DeleteAll(ServiceName)
defer Clear()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
assert.Equal(t, "/verify", r.URL.Path)
w.WriteHeader(tt.status)
}))
defer server.Close()
tt.config.Server.URL = server.URL
err := tt.config.Verify(context.Background())
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}
func TestListConfig(t *testing.T) {
tests := []struct {
name string
primeToken bool
setupConfig *Config
wantErr string
wantContains []string
}{
{
name: "success with valid config",
primeToken: true,
setupConfig: &Config{
Token: "testtoken",
Server: Server{
URL: "https://example.com",
Scanning: Scanning{
Enabled: true,
UploadResults: false,
SecretConfig: true,
MisconfigConfig: false,
},
},
Api: Api{URL: "https://api.example.com"},
},
wantContains: []string{
"Trivy Cloud Configuration",
"Logged In: No",
"Filepath:",
"api.url",
"https://api.example.com",
"server.url",
"https://example.com",
"server.scanning.enabled",
"Enabled",
"server.scanning.upload-results",
"Disabled",
"server.scanning.secret-config",
"server.scanning.misconfig-config",
},
},
{
name: "success with default config",
setupConfig: nil,
wantContains: []string{
"Trivy Cloud Configuration",
"Logged In: No",
"api.url",
DefaultApiUrl,
"server.url",
DefaultTrivyServerUrl,
"server.scanning.enabled",
"server.scanning.upload-results",
"server.scanning.secret-config",
"server.scanning.misconfig-config",
},
},
}
tempDir := t.TempDir()
t.Setenv("XDG_DATA_HOME", tempDir)
keyring.MockInit()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer keyring.DeleteAll(ServiceName)
defer Clear()
if tt.primeToken {
// prime the token in the keyring so the custom config doesn't get overwritten
require.NoError(t, keyring.Set(ServiceName, TokenKey, tt.setupConfig.Token))
}
if tt.setupConfig != nil {
err := tt.setupConfig.Save()
require.NoError(t, err)
}
r, w, err := os.Pipe()
require.NoError(t, err)
originalStdout := os.Stdout
os.Stdout = w
errChan := make(chan error, 1)
go func() {
errChan <- ListConfig()
w.Close()
}()
output, _ := io.ReadAll(r)
os.Stdout = originalStdout
err = <-errChan
if tt.wantErr != "" {
require.ErrorContains(t, err, tt.wantErr)
return
}
require.NoError(t, err)
outputStr := string(output)
for _, want := range tt.wantContains {
assert.Contains(t, outputStr, want)
}
})
}
}