package start
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"reflect"
"strconv"
"strings"
"testing"
"github.com/spf13/cobra"
configapi "github.com/openshift/origin/pkg/cmd/server/api"
configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest"
// install all APIs
_ "github.com/openshift/origin/pkg/api/install"
_ "k8s.io/kubernetes/pkg/api/install"
)
// this groups of methods force all the unit tests to share the same config directory
// the non-cert parts of the directory are cleaned up with every execution, but the certs
// remain in order to speed up the tests.
var configDir = ""
const nodeConfigGlob = "node-*/node-config.yaml"
func getNodeConfigGlob() string {
return path.Join(getNodeConfigDir(), nodeConfigGlob)
}
func getConfigDir() string {
if len(configDir) == 0 {
configDir, _ = ioutil.TempDir("", "")
}
return configDir
}
func getAllInOneConfigDir() string {
return getConfigDir()
}
func getMasterConfigDir() string {
return path.Join(getConfigDir(), "master")
}
func getCleanAllInOneConfigDir() string {
cleanupMasterConfigDir()
return getAllInOneConfigDir()
}
func getCleanMasterConfigDir() string {
cleanupMasterConfigDir()
cleanupNodeConfigDirs()
return getMasterConfigDir()
}
func getNodeConfigDir() string {
return path.Join(getConfigDir(), "node")
}
func cleanupMasterConfigDir() {
os.Remove(path.Join(getMasterConfigDir(), "policy.json"))
os.Remove(path.Join(getMasterConfigDir(), "master-config.yaml"))
}
func cleanupNodeConfigDirs() {
// no errors reported, just best effort
nodeConfigs, _ := filepath.Glob(getNodeConfigGlob())
for _, file := range nodeConfigs {
os.Remove(file)
}
}
func TestCommandBindingListen(t *testing.T) {
valueToSet := "http://example.org:9123"
actualCfg := executeMasterCommand([]string{"--listen=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.ListenArg.ListenAddr.Set(valueToSet)
if expectedArgs.ListenArg.ListenAddr.String() != actualCfg.ListenArg.ListenAddr.String() {
t.Errorf("expected %v, got %v", expectedArgs.ListenArg.ListenAddr.String(), actualCfg.ListenArg.ListenAddr.String())
}
}
func TestCommandBindingMaster(t *testing.T) {
valueToSet := "http://example.org:9123"
actualCfg := executeMasterCommand([]string{"--master=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.MasterAddr.Set(valueToSet)
if expectedArgs.MasterAddr.String() != actualCfg.MasterAddr.String() {
t.Errorf("expected %v, got %v", expectedArgs.MasterAddr.String(), actualCfg.MasterAddr.String())
}
}
func TestCommandBindingMasterPublic(t *testing.T) {
valueToSet := "http://example.org:9123"
actualCfg := executeMasterCommand([]string{"--public-master=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.MasterPublicAddr.Set(valueToSet)
if expectedArgs.MasterPublicAddr.String() != actualCfg.MasterPublicAddr.String() {
t.Errorf("expected %v, got %v", expectedArgs.MasterPublicAddr.String(), actualCfg.MasterPublicAddr.String())
}
}
func TestCommandBindingEtcd(t *testing.T) {
valueToSet := "http://example.org:9123"
actualCfg := executeMasterCommand([]string{"--etcd=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.EtcdAddr.Set(valueToSet)
if expectedArgs.EtcdAddr.String() != actualCfg.EtcdAddr.String() {
t.Errorf("expected %v, got %v", expectedArgs.EtcdAddr.String(), actualCfg.EtcdAddr.String())
}
}
func TestCommandBindingPortalNet(t *testing.T) {
valueToSet := "192.168.0.0/16"
actualCfg := executeMasterCommand([]string{"--portal-net=" + valueToSet})
if valueToSet != actualCfg.NetworkArgs.ServiceNetworkCIDR {
t.Errorf("expected %v, got %v", valueToSet, actualCfg.NetworkArgs.ServiceNetworkCIDR)
}
}
func TestCommandBindingImageTemplateFormat(t *testing.T) {
valueToSet := "some-format-string"
actualCfg := executeMasterCommand([]string{"--images=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.ImageFormatArgs.ImageTemplate.Format = valueToSet
if expectedArgs.ImageFormatArgs.ImageTemplate.Format != actualCfg.ImageFormatArgs.ImageTemplate.Format {
t.Errorf("expected %v, got %v", expectedArgs.ImageFormatArgs.ImageTemplate.Format, actualCfg.ImageFormatArgs.ImageTemplate.Format)
}
}
func TestCommandBindingImageLatest(t *testing.T) {
expectedArgs := NewDefaultMasterArgs()
valueToSet := strconv.FormatBool(!expectedArgs.ImageFormatArgs.ImageTemplate.Latest)
actualCfg := executeMasterCommand([]string{"--latest-images=" + valueToSet})
expectedArgs.ImageFormatArgs.ImageTemplate.Latest = !expectedArgs.ImageFormatArgs.ImageTemplate.Latest
if expectedArgs.ImageFormatArgs.ImageTemplate.Latest != actualCfg.ImageFormatArgs.ImageTemplate.Latest {
t.Errorf("expected %v, got %v", expectedArgs.ImageFormatArgs.ImageTemplate.Latest, actualCfg.ImageFormatArgs.ImageTemplate.Latest)
}
}
func TestCommandBindingEtcdDir(t *testing.T) {
valueToSet := "some-string"
actualCfg := executeMasterCommand([]string{"--etcd-dir=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.EtcdDir = valueToSet
if expectedArgs.EtcdDir != actualCfg.EtcdDir {
t.Errorf("expected %v, got %v", expectedArgs.EtcdDir, actualCfg.EtcdDir)
}
}
func TestCommandBindingCors(t *testing.T) {
valueToSet := "first,second,third"
actualCfg := executeMasterCommand([]string{"--cors-allowed-origins=" + valueToSet})
expectedArgs := NewDefaultMasterArgs()
expectedArgs.CORSAllowedOrigins = append(expectedArgs.CORSAllowedOrigins, strings.Split(valueToSet, ",")...)
if !reflect.DeepEqual(expectedArgs.CORSAllowedOrigins, actualCfg.CORSAllowedOrigins) {
t.Errorf("expected %v, got %v", expectedArgs.CORSAllowedOrigins, actualCfg.CORSAllowedOrigins)
}
}
func executeMasterCommand(args []string) *MasterArgs {
argsToUse := make([]string, 0, 4+len(args))
argsToUse = append(argsToUse, "master")
argsToUse = append(argsToUse, args...)
argsToUse = append(argsToUse, "--write-config="+getCleanMasterConfigDir())
argsToUse = append(argsToUse, "--create-certs=false")
root := &cobra.Command{
Use: "openshift",
Short: "test",
Long: "",
Run: func(c *cobra.Command, args []string) {
c.Help()
},
}
openshiftStartCommand, cfg := NewCommandStartMaster("openshift", os.Stdout, os.Stderr)
root.AddCommand(openshiftStartCommand)
root.SetArgs(argsToUse)
root.Execute()
return cfg.MasterArgs
}
func executeAllInOneCommand(args []string) (*MasterArgs, *NodeArgs) {
masterArgs, _, _, nodeArgs, _, _ := executeAllInOneCommandWithConfigs(args)
return masterArgs, nodeArgs
}
func executeAllInOneCommandWithConfigs(args []string) (*MasterArgs, *configapi.MasterConfig, error, *NodeArgs, *configapi.NodeConfig, error) {
argsToUse := make([]string, 0, 4+len(args))
argsToUse = append(argsToUse, "start")
argsToUse = append(argsToUse, args...)
argsToUse = append(argsToUse, "--write-config="+getCleanAllInOneConfigDir())
argsToUse = append(argsToUse, "--create-certs=false")
root := &cobra.Command{
Use: "openshift",
Short: "test",
Long: "",
Run: func(c *cobra.Command, args []string) {
c.Help()
},
}
openshiftStartCommand, cfg := NewCommandStartAllInOne("openshift start", os.Stdout, os.Stderr)
root.AddCommand(openshiftStartCommand)
root.SetArgs(argsToUse)
root.Execute()
masterCfg, masterErr := configapilatest.ReadAndResolveMasterConfig(path.Join(getAllInOneConfigDir(), "master", "master-config.yaml"))
var nodeCfg *configapi.NodeConfig
var nodeErr error
nodeConfigs, nodeErr := filepath.Glob(getNodeConfigGlob())
if nodeErr == nil {
if len(nodeConfigs) != 1 {
nodeErr = fmt.Errorf("found wrong number of node configs: %v", nodeConfigs)
} else {
nodeCfg, nodeErr = configapilatest.ReadAndResolveNodeConfig(nodeConfigs[0])
}
}
if nodeCfg == nil && nodeErr == nil {
nodeErr = errors.New("did not find node config")
}
return cfg.MasterOptions.MasterArgs, masterCfg, masterErr, cfg.NodeArgs, nodeCfg, nodeErr
}