summaryrefslogtreecommitdiffstats
path: root/client/go/cmd/config_test.go
blob: 7059bfa78ccb2db059148f85961c265b64381480 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package cmd

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/vespa-engine/vespa/client/go/mock"
	"github.com/vespa-engine/vespa/client/go/vespa"
)

func TestConfig(t *testing.T) {
	configHome := t.TempDir()
	assertConfigCommandErr(t, configHome, "Error: invalid option or value: foo = bar\n", "config", "set", "foo", "bar")
	assertConfigCommand(t, configHome, "foo = <unset>\n", "config", "get", "foo")
	assertConfigCommand(t, configHome, "target = local\n", "config", "get", "target")
	assertConfigCommand(t, configHome, "", "config", "set", "target", "hosted")
	assertConfigCommand(t, configHome, "target = hosted\n", "config", "get", "target")
	assertConfigCommand(t, configHome, "", "config", "set", "target", "cloud")
	assertConfigCommand(t, configHome, "target = cloud\n", "config", "get", "target")
	assertConfigCommand(t, configHome, "", "config", "set", "target", "http://127.0.0.1:8080")
	assertConfigCommand(t, configHome, "", "config", "set", "target", "https://127.0.0.1")
	assertConfigCommand(t, configHome, "target = https://127.0.0.1\n", "config", "get", "target")

	assertConfigCommandErr(t, configHome, "Error: invalid application: \"foo\"\n", "config", "set", "application", "foo")
	assertConfigCommand(t, configHome, "application = <unset>\n", "config", "get", "application")
	assertConfigCommand(t, configHome, "", "config", "set", "application", "t1.a1.i1")
	assertConfigCommand(t, configHome, "application = t1.a1.i1\n", "config", "get", "application")

	assertConfigCommand(t, configHome, "", "config", "set", "wait", "60")
	assertConfigCommandErr(t, configHome, "Error: wait option must be an integer >= 0, got \"foo\"\n", "config", "set", "wait", "foo")
	assertConfigCommand(t, configHome, "wait = 60\n", "config", "get", "wait")
	assertConfigCommand(t, configHome, "wait = 30\n", "config", "get", "--wait", "30", "wait") // flag overrides global config

	assertConfigCommand(t, configHome, "", "config", "set", "quiet", "true")
	assertConfigCommand(t, configHome, "", "config", "set", "quiet", "false")

	assertConfigCommand(t, configHome, "", "config", "set", "instance", "i2")
	assertConfigCommand(t, configHome, "instance = i2\n", "config", "get", "instance")

	assertConfigCommand(t, configHome, "", "config", "set", "application", "t1.a1")
	assertConfigCommand(t, configHome, "application = t1.a1.default\n", "config", "get", "application")
}

func TestLocalConfig(t *testing.T) {
	configHome := t.TempDir()
	assertConfigCommand(t, configHome, "", "config", "set", "instance", "main")

	// Change directory to an application package and write local configuration
	_, rootDir := mock.ApplicationPackageDir(t, false, false)
	wd, err := os.Getwd()
	require.Nil(t, err)
	t.Cleanup(func() { os.Chdir(wd) })
	require.Nil(t, os.Chdir(rootDir))
	assertConfigCommand(t, configHome, "", "config", "set", "--local", "instance", "foo")
	assertConfigCommand(t, configHome, "instance = foo\n", "config", "get", "instance")
	assertConfigCommand(t, configHome, "instance = bar\n", "config", "get", "--instance", "bar", "instance") // flag overrides local config

	// get --local prints only options set in local config
	assertConfigCommand(t, configHome, "", "config", "set", "--local", "target", "hosted")
	assertConfigCommand(t, configHome, "instance = foo\ntarget = hosted\n", "config", "get", "--local")

	// only locally set options are written
	localConfig, err := os.ReadFile(filepath.Join(rootDir, ".vespa", "config.yaml"))
	require.Nil(t, err)
	assert.Equal(t, "instance: foo\ntarget: hosted\n", string(localConfig))

	// Changing back to original directory reads from global config
	require.Nil(t, os.Chdir(wd))
	assertConfigCommand(t, configHome, "instance = main\n", "config", "get", "instance")
}

func assertConfigCommand(t *testing.T, configHome, expected string, args ...string) {
	t.Helper()
	assertEnvConfigCommand(t, configHome, expected, nil, args...)
}

func assertEnvConfigCommand(t *testing.T, configHome, expected string, env []string, args ...string) {
	t.Helper()
	env = append(env, "VESPA_CLI_HOME="+configHome)
	cli, stdout, _ := newTestCLI(t, env...)
	err := cli.Run(args...)
	assert.Nil(t, err)
	assert.Equal(t, expected, stdout.String())
}

func assertConfigCommandErr(t *testing.T, configHome, expected string, args ...string) {
	t.Helper()
	cli, _, stderr := newTestCLI(t)
	err := cli.Run(args...)
	assert.NotNil(t, err)
	assert.Equal(t, expected, stderr.String())
}

func TestUseAPIKey(t *testing.T) {
	cli, _, _ := newTestCLI(t)
	assert.False(t, cli.config.useAPIKey(cli, vespa.PublicSystem, "t1"))

	cli, _, _ = newTestCLI(t, "VESPA_CLI_API_KEY_FILE=/tmp/foo")
	assert.True(t, cli.config.useAPIKey(cli, vespa.PublicSystem, "t1"))

	cli, _, _ = newTestCLI(t, "VESPA_CLI_API_KEY=foo")
	assert.True(t, cli.config.useAPIKey(cli, vespa.PublicSystem, "t1"))

	// Prefer Auth0, if configured
	authContent := `
{
    "version": 1,
    "providers": {
        "auth0": {
            "version": 1,
            "systems": {
                "public": {
					"access_token": "...",
					"scopes": ["openid", "offline_access"],
					"expires_at": "2030-01-01T01:01:01.000001+01:00"
				}
			}
		}
	}
}`
	cli, _, _ = newTestCLI(t, "VESPA_CLI_CLOUD_SYSTEM=public")
	_, err := os.Create(filepath.Join(cli.config.homeDir, "t2.api-key.pem"))
	require.Nil(t, err)
	assert.True(t, cli.config.useAPIKey(cli, vespa.PublicSystem, "t2"))
	require.Nil(t, os.WriteFile(filepath.Join(cli.config.homeDir, "auth.json"), []byte(authContent), 0600))
	assert.False(t, cli.config.useAPIKey(cli, vespa.PublicSystem, "t2"))
}