mirror of https://github.com/docker/docs.git
Add some more tests for notary CLI
Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
parent
d67a7e128c
commit
718002acea
|
@ -72,17 +72,13 @@ func (n *notaryCommander) parseConfig() (*viper.Viper, error) {
|
|||
|
||||
// If there was a commandline configFile set, we parse that.
|
||||
// If there wasn't we attempt to find it on the default location ~/.notary/config.json
|
||||
configFileName, configFileExt, configPath := "config", "json", defaultTrustDir
|
||||
if n.configFile != "" {
|
||||
configFileExt = strings.TrimPrefix(filepath.Ext(n.configFile), ".")
|
||||
configFileName = strings.TrimSuffix(filepath.Base(n.configFile), filepath.Ext(n.configFile))
|
||||
configPath = filepath.Dir(n.configFile)
|
||||
config.SetConfigFile(n.configFile)
|
||||
} else {
|
||||
config.SetConfigFile(filepath.Join(defaultTrustDir, "config.json"))
|
||||
}
|
||||
|
||||
// Setup the configuration details into viper
|
||||
config.SetConfigName(configFileName)
|
||||
config.SetConfigType(configFileExt)
|
||||
config.AddConfigPath(configPath)
|
||||
config.SetDefault("trust_dir", defaultTrustDir)
|
||||
config.SetDefault("remote_server", map[string]string{"url": defaultServerURL})
|
||||
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/notary/passphrase"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// the default location for the config file is in ~/.notary/config.json - even if it doesn't exist.
|
||||
func TestNotaryConfigFileDefault(t *testing.T) {
|
||||
commander := ¬aryCommander{
|
||||
getRetriever: func() passphrase.Retriever { return passphrase.ConstantRetriever("pass") },
|
||||
}
|
||||
|
||||
config, err := commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
configFileUsed := config.ConfigFileUsed()
|
||||
assert.True(t, strings.HasSuffix(configFileUsed,
|
||||
filepath.Join(".notary", "config.json")), "Unknown config file: %s", configFileUsed)
|
||||
}
|
||||
|
||||
// the default server address is notary-server
|
||||
func TestRemoteServerDefault(t *testing.T) {
|
||||
tempDir := tempDirWithConfig(t, "{}")
|
||||
defer os.RemoveAll(tempDir)
|
||||
configFile := filepath.Join(tempDir, "config.json")
|
||||
|
||||
commander := ¬aryCommander{
|
||||
getRetriever: func() passphrase.Retriever { return passphrase.ConstantRetriever("pass") },
|
||||
}
|
||||
|
||||
// set a blank config file, so it doesn't check ~/.notary/config.json by default
|
||||
// and execute a random command so that the flags are parsed
|
||||
cmd := commander.GetCommand()
|
||||
cmd.SetArgs([]string{"-c", configFile, "list"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
cmd.Execute()
|
||||
|
||||
config, err := commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://notary-server:4443", getRemoteTrustServer(config))
|
||||
}
|
||||
|
||||
// providing a config file uses the config file's server url instead
|
||||
func TestRemoteServerUsesConfigFile(t *testing.T) {
|
||||
tempDir := tempDirWithConfig(t, `{"remote_server": {"url": "https://myserver"}}`)
|
||||
defer os.RemoveAll(tempDir)
|
||||
configFile := filepath.Join(tempDir, "config.json")
|
||||
|
||||
commander := ¬aryCommander{
|
||||
getRetriever: func() passphrase.Retriever { return passphrase.ConstantRetriever("pass") },
|
||||
}
|
||||
|
||||
// set a config file, so it doesn't check ~/.notary/config.json by default,
|
||||
// and execute a random command so that the flags are parsed
|
||||
cmd := commander.GetCommand()
|
||||
cmd.SetArgs([]string{"-c", configFile, "list"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
cmd.Execute()
|
||||
|
||||
config, err := commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://myserver", getRemoteTrustServer(config))
|
||||
}
|
||||
|
||||
// a command line flag overrides the config file's server url
|
||||
func TestRemoteServerCommandLineFlagOverridesConfig(t *testing.T) {
|
||||
tempDir := tempDirWithConfig(t, `{"remote_server": {"url": "https://myserver"}}`)
|
||||
defer os.RemoveAll(tempDir)
|
||||
configFile := filepath.Join(tempDir, "config.json")
|
||||
|
||||
commander := ¬aryCommander{
|
||||
getRetriever: func() passphrase.Retriever { return passphrase.ConstantRetriever("pass") },
|
||||
}
|
||||
|
||||
// set a config file, so it doesn't check ~/.notary/config.json by default,
|
||||
// and execute a random command so that the flags are parsed
|
||||
cmd := commander.GetCommand()
|
||||
cmd.SetArgs([]string{"-c", configFile, "-s", "http://overridden", "list"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
cmd.Execute()
|
||||
|
||||
config, err := commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "http://overridden", getRemoteTrustServer(config))
|
||||
}
|
||||
|
||||
var exampleValidCommands = []string{
|
||||
"init repo",
|
||||
"list repo",
|
||||
"status repo",
|
||||
"publish repo",
|
||||
"add repo v1 somefile",
|
||||
"verify repo v1",
|
||||
"key list",
|
||||
"key rotate repo",
|
||||
"key generate rsa",
|
||||
"key backup tempfile.zip",
|
||||
"key export e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 backup.pem",
|
||||
"key restore tempfile.zip",
|
||||
"key import backup.pem",
|
||||
"key remove e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"key passwd e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"cert list",
|
||||
"cert remove e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"delegation list repo",
|
||||
"delegation add repo targets/releases path/to/pem/file.pem",
|
||||
"delegation remove repo targets/releases",
|
||||
}
|
||||
|
||||
// config parsing bugs are propagated in all commands
|
||||
func TestConfigParsingErrorsPropagatedByCommands(t *testing.T) {
|
||||
tempdir, err := ioutil.TempDir("", "empty-dir")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempdir)
|
||||
|
||||
for _, args := range exampleValidCommands {
|
||||
b := new(bytes.Buffer)
|
||||
cmd := NewNotaryCommand()
|
||||
cmd.SetOutput(b)
|
||||
|
||||
cmd.SetArgs(append(
|
||||
[]string{"-c", filepath.Join(tempdir, "idonotexist.json"), "-d", tempdir},
|
||||
strings.Fields(args)...))
|
||||
err = cmd.Execute()
|
||||
|
||||
require.Error(t, err, "expected error when running %s", args)
|
||||
require.Contains(t, err.Error(), "error opening config file", "running %s", args)
|
||||
require.NotContains(t, b.String(), "Usage:")
|
||||
}
|
||||
}
|
||||
|
||||
// insufficient arguments produce an error before any parsing of configs happens
|
||||
func TestInsufficientArgumentsReturnsErrorAndPrintsUsage(t *testing.T) {
|
||||
tempdir, err := ioutil.TempDir("", "empty-dir")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempdir)
|
||||
|
||||
for _, args := range exampleValidCommands {
|
||||
b := new(bytes.Buffer)
|
||||
cmd := NewNotaryCommand()
|
||||
cmd.SetOutput(b)
|
||||
|
||||
arglist := strings.Fields(args)
|
||||
if args == "key list" || args == "cert list" || args == "key generate rsa" {
|
||||
// in these case, "key" or "cert" or "key generate" are valid commands, so add an arg to them instead
|
||||
arglist = append(arglist, "extraArg")
|
||||
} else {
|
||||
arglist = arglist[:len(arglist)-1]
|
||||
}
|
||||
|
||||
invalid := strings.Join(arglist, " ")
|
||||
|
||||
cmd.SetArgs(append(
|
||||
[]string{"-c", filepath.Join(tempdir, "idonotexist.json"), "-d", tempdir}, arglist...))
|
||||
err = cmd.Execute()
|
||||
|
||||
require.NotContains(t, err.Error(), "error opening config file", "running %s", invalid)
|
||||
// it's a usage error, so the usage is printed
|
||||
require.Contains(t, b.String(), "Usage:", "expected usage when running %s", invalid)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue