gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/cmd/fabric-ca-server/main_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package main
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"os"
    14  	"path"
    15  	"path/filepath"
    16  	"regexp"
    17  	"testing"
    18  
    19  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/api"
    20  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/util"
    21  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib"
    22  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/metadata"
    23  	"gitee.com/zhaochuninhefei/gmgo/x509"
    24  	log "gitee.com/zhaochuninhefei/zcgolog/zclog"
    25  	"github.com/spf13/viper"
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  const (
    30  	initYaml    = "i.yaml"
    31  	startYaml   = "s.yaml"
    32  	ldapTestDir = "ldapTestDir"
    33  )
    34  
    35  var (
    36  	longUserName = util.RandomString(1025)
    37  )
    38  
    39  var (
    40  	longFileName = util.RandomString(261)
    41  )
    42  
    43  // Create a config element in unexpected format
    44  var badSyntaxYaml = "bad.yaml"
    45  
    46  // Unsupported file type
    47  var unsupportedFileType = "config.txt"
    48  
    49  type TestData struct {
    50  	input    []string // input
    51  	expected string   // expected result
    52  }
    53  
    54  // checkTest validates success cases
    55  func checkTest(in *TestData, t *testing.T) {
    56  	os.Args = in.input
    57  	scmd := NewCommand(in.input[1], blockingStart)
    58  	// Execute the command
    59  	err := scmd.Execute()
    60  	if err != nil {
    61  		t.Errorf("FAILED:\n \tin: %v;\n \tout: %v\n \texpected: SUCCESS\n", in.input, err.Error())
    62  	} else {
    63  		signingProfile := scmd.cfg.CAcfg.Signing.Default
    64  		ku, eku, unk := signingProfile.Usages()
    65  		// expected key usage is digital signature
    66  		assert.Equal(t, x509.KeyUsageDigitalSignature, ku, "Expected KeyUsageDigitalSignature")
    67  		assert.Equal(t, 0, len(eku), "Found %d extended usages but expected 0", len(eku))
    68  		assert.Equal(t, 0, len(unk), "Found %d unknown key usages", len(unk))
    69  	}
    70  }
    71  
    72  func TestMain(m *testing.M) {
    73  	os.Setenv("FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS", "localhost:0")
    74  	defer os.Unsetenv("FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS")
    75  
    76  	metadata.Version = "1.1.0"
    77  	os.Exit(m.Run())
    78  }
    79  
    80  func TestNoArguments(t *testing.T) {
    81  	err := RunMain([]string{cmdName})
    82  	if err == nil {
    83  		assert.Error(t, errors.New("Should have resulted in an error as no arguments provided"))
    84  	}
    85  }
    86  
    87  func TestErrors(t *testing.T) {
    88  	os.Unsetenv(homeEnvVar)
    89  	_ = ioutil.WriteFile(badSyntaxYaml, []byte("signing: true\n"), 0644)
    90  
    91  	// errorTest validates error cases
    92  	errorTest := func(in *TestData, t *testing.T) {
    93  		err := RunMain(in.input)
    94  		if err != nil {
    95  			matched, _ := regexp.MatchString(in.expected, err.Error())
    96  			if !matched {
    97  				t.Errorf("FAILED:\n \tin: %v;\n \tout: %v;\n \texpected: %v\n", in.input, err.Error(), in.expected)
    98  			}
    99  		} else {
   100  			t.Errorf("FAILED:\n \tin: %v;\n \tout: <nil>\n \texpected: %v\n", in.input, in.expected)
   101  		}
   102  	}
   103  
   104  	errorCases := []TestData{
   105  		{[]string{cmdName, "init", "-c", initYaml}, "option is required"},
   106  		{[]string{cmdName, "init", "-c", initYaml, "-n", "acme.com", "-b", "user::"}, "Failed to read"},
   107  		{[]string{cmdName, "init", "-b", "user:pass", "-n", "acme.com", "ca.key"}, "Unrecognized arguments found"},
   108  		{[]string{cmdName, "init", "-c", badSyntaxYaml, "-b", "user:pass"}, "Incorrect format"},
   109  		{[]string{cmdName, "init", "-c", initYaml, "-b", fmt.Sprintf("%s:foo", longUserName)}, "than 1024 characters"},
   110  		{[]string{cmdName, "init", "-c", fmt.Sprintf("/tmp/%s.yaml", longFileName), "-b", "user:pass"}, "file name too long"},
   111  		{[]string{cmdName, "init", "-b", "user:pass", "-c", unsupportedFileType}, "Unsupported Config Type"},
   112  		{[]string{cmdName, "init", "-c", initYaml, "-b", "user"}, "missing a colon"},
   113  		{[]string{cmdName, "init", "-c", initYaml, "-b", "user:"}, "empty password"},
   114  		{[]string{cmdName, "bogus", "-c", initYaml, "-b", "user:pass"}, "unknown command"},
   115  		{[]string{cmdName, "start", "-c"}, "needs an argument:"},
   116  		{[]string{cmdName, "start", "--csr.keyrequest.algo", "fakeAlgo"}, "Invalid algorithm: fakeAlgo"},
   117  		{[]string{cmdName, "start", "--csr.keyrequest.algo", "ecdsa", "--csr.keyrequest.size", "12345"}, "Invalid ECDSA key size: 12345"},
   118  		{[]string{cmdName, "start", "-c", startYaml, "-b", "user:pass", "ca.key"}, "Unrecognized arguments found"},
   119  	}
   120  
   121  	for _, e := range errorCases {
   122  		errorTest(&e, t)
   123  		_ = os.Remove(initYaml)
   124  	}
   125  }
   126  
   127  func TestOneTimePass(t *testing.T) {
   128  	testDir := "oneTimePass"
   129  	os.RemoveAll(testDir)
   130  	defer os.RemoveAll(testDir)
   131  	// Test with "-b" option
   132  	err := RunMain([]string{cmdName, "init", "-b", "admin:adminpw", "--registry.maxenrollments", "1", "-H", testDir})
   133  	if err != nil {
   134  		t.Fatalf("Failed to init server with one time passwords: %s", err)
   135  	}
   136  }
   137  
   138  func TestLDAP(t *testing.T) {
   139  	os.RemoveAll(ldapTestDir)
   140  	defer os.RemoveAll(ldapTestDir)
   141  	// Test with "-b" option
   142  	err := RunMain([]string{cmdName, "init", "-c", path.Join(ldapTestDir, "config.yaml"),
   143  		"-b", "a:b", "--ldap.enabled", "--ldap.url", "ldap://CN=admin@localhost:389/dc=example,dc=com"})
   144  	if err != nil {
   145  		t.Errorf("Failed to init server with LDAP enabled and -b: %s", err)
   146  	}
   147  	// Try without "-b" option
   148  	os.RemoveAll(ldapTestDir)
   149  	err = RunMain([]string{cmdName, "init", "-c", path.Join(ldapTestDir, "config.yaml"),
   150  		"--ldap.enabled", "--ldap.url", "ldap://CN=admin@localhost:389/dc=example,dc=com"})
   151  	if err != nil {
   152  		t.Errorf("Failed to init server with LDAP enabled and no -b: %s", err)
   153  	}
   154  }
   155  
   156  func TestValid(t *testing.T) {
   157  	os.Unsetenv(homeEnvVar)
   158  	blockingStart = false
   159  
   160  	os.Setenv("CA_CFG_PATH", ".")
   161  	validCases := []TestData{
   162  		{[]string{cmdName, "init", "-b", "admin:a:d:m:i:n:p:w"}, ""},
   163  		{[]string{cmdName, "init", "-d"}, ""},
   164  		{[]string{cmdName, "start", "-c", startYaml, "-b", "admin:admin"}, ""},
   165  	}
   166  
   167  	for _, v := range validCases {
   168  		checkTest(&v, t)
   169  	}
   170  }
   171  
   172  // Test to check that config and datasource files are created in correct location
   173  // based on the arguments passed to the fabric-ca-server and environment variables
   174  func TestDBLocation(t *testing.T) {
   175  	blockingStart = false
   176  	envs := []string{"FABRIC_CA_SERVER_HOME", "FABRIC_CA_HOME", "CA_CFG_PATH",
   177  		"FABRIC_CA_SERVER_DB_DATASOURCE"}
   178  	for _, env := range envs {
   179  		os.Unsetenv(env)
   180  	}
   181  
   182  	// Invoke server with -c arg set to serverConfig/config.yml (relative path)
   183  	cfgFile := "serverConfig/config.yml"
   184  	dsFile := "serverConfig/fabric-ca-server.db"
   185  	args := TestData{[]string{cmdName, "start", "-b", "admin:admin", "-c", cfgFile, "-p", "7091"}, ""}
   186  	checkConfigAndDBLoc(t, args, cfgFile, dsFile)
   187  	os.RemoveAll("serverConfig")
   188  
   189  	// Invoke server with -c arg set to serverConfig1/config.yml (relative path)
   190  	// and FABRIC_CA_SERVER_DB_DATASOURCE env variable set to fabric-ca-srv.db (relative path)
   191  	os.Setenv("FABRIC_CA_SERVER_DB_DATASOURCE", "fabric-ca-srv.db")
   192  	cfgFile = "serverConfig1/config.yml"
   193  	dsFile = "serverConfig1/fabric-ca-srv.db"
   194  	args = TestData{[]string{cmdName, "start", "-b", "admin:admin", "-c", cfgFile, "-p", "7092"}, ""}
   195  	checkConfigAndDBLoc(t, args, cfgFile, dsFile)
   196  	os.RemoveAll("serverConfig1")
   197  
   198  	// Invoke server with -c arg set to serverConfig2/config.yml (relative path)
   199  	// and FABRIC_CA_SERVER_DB_DATASOURCE env variable set to /tmp/fabric-ca-srv.db (absolute path)
   200  	cfgFile = "serverConfig2/config.yml"
   201  	dsFile = os.TempDir() + "/fabric-ca-srv.db"
   202  	os.Setenv("FABRIC_CA_SERVER_DB_DATASOURCE", dsFile)
   203  	args = TestData{[]string{cmdName, "start", "-b", "admin:admin", "-c", cfgFile, "-p", "7093"}, ""}
   204  	checkConfigAndDBLoc(t, args, cfgFile, dsFile)
   205  	os.RemoveAll("serverConfig2")
   206  	os.Remove(dsFile)
   207  
   208  	// Invoke server with -c arg set to /tmp/config/config.yml (absolute path)
   209  	// and FABRIC_CA_SERVER_DB_DATASOURCE env variable set to fabric-ca-srv.db (relative path)
   210  	cfgDir := os.TempDir() + "/config/"
   211  	cfgFile = cfgDir + "config.yml"
   212  	dsFile = "fabric-ca-srv.db"
   213  	os.Setenv("FABRIC_CA_SERVER_DB_DATASOURCE", dsFile)
   214  	args = TestData{[]string{cmdName, "start", "-b", "admin:admin", "-c", cfgFile, "-p", "7094"}, ""}
   215  	checkConfigAndDBLoc(t, args, cfgFile, cfgDir+dsFile)
   216  	os.RemoveAll(os.TempDir() + "/config")
   217  
   218  	// Invoke server with -c arg set to /tmp/config/config.yml (absolute path)
   219  	// and FABRIC_CA_SERVER_DB_DATASOURCE env variable set to /tmp/fabric-ca-srv.db (absolute path)
   220  	cfgFile = os.TempDir() + "/config/config.yml"
   221  	dsFile = os.TempDir() + "/fabric-ca-srv.db"
   222  	os.Setenv("FABRIC_CA_SERVER_DB_DATASOURCE", dsFile)
   223  	args = TestData{[]string{cmdName, "start", "-b", "admin:admin", "-c", cfgFile, "-p", "7095"}, ""}
   224  	checkConfigAndDBLoc(t, args, cfgFile, dsFile)
   225  	os.RemoveAll(os.TempDir() + "/config")
   226  	os.Remove(dsFile)
   227  	os.Unsetenv("FABRIC_CA_SERVER_DB_DATASOURCE")
   228  }
   229  
   230  func TestDefaultMultiCAs(t *testing.T) {
   231  	blockingStart = false
   232  
   233  	err := RunMain([]string{cmdName, "start", "-p", "7055", "-c", startYaml, "-d", "-b", "user:pass", "--cacount", "4"})
   234  	if err != nil {
   235  		t.Error("Failed to start server with multiple default CAs using the --cacount flag from command line: ", err)
   236  	}
   237  
   238  	if !util.FileExists("ca/ca4/fabric-ca-server_ca4.db") {
   239  		t.Error("Failed to create 4 default CA instances")
   240  	}
   241  
   242  	os.RemoveAll("ca")
   243  }
   244  
   245  func TestCACountWithAbsPath(t *testing.T) {
   246  	testDir := "myTestDir"
   247  	defer os.RemoveAll(testDir)
   248  	// Run init to create the ca-cert.pem
   249  	err := RunMain([]string{cmdName, "init", "-H", testDir, "-b", "user:pass"})
   250  	if err != nil {
   251  		t.Fatalf("Failed to init CA: %s", err)
   252  	}
   253  	// Set the complete path to the ca-cert.pem file
   254  	cwd, err := os.Getwd()
   255  	if err != nil {
   256  		t.Fatalf("Failed to get current working directory: %s", err)
   257  	}
   258  	certFilePath := path.Join(cwd, testDir, "ca-cert.pem")
   259  	// Init again with the absolute path to ca-cert.pem and --cacount to make sure this works
   260  	err = RunMain([]string{cmdName, "init", "-H", testDir, "--ca.certfile", certFilePath, "--cacount", "2"})
   261  	if err != nil {
   262  		t.Fatalf("Failed to init multi CA with absolute path: %s", err)
   263  	}
   264  }
   265  
   266  func TestMultiCA(t *testing.T) {
   267  	blockingStart = false
   268  
   269  	cleanUpMultiCAFiles()
   270  	defer cleanUpMultiCAFiles()
   271  
   272  	err := RunMain([]string{cmdName, "start", "-d", "-p", "7056", "-c", "../../testdata/test.yaml", "-b", "user:pass", "--cafiles", "ca/rootca/ca1/fabric-ca-server-config.yaml", "--cafiles", "ca/rootca/ca2/fabric-ca-server-config.yaml"})
   273  	if err != nil {
   274  		t.Error("Failed to start server with multiple CAs using the --cafiles flag from command line: ", err)
   275  	}
   276  
   277  	if !util.FileExists("../../testdata/ca/rootca/ca2/fabric-ca2-server.db") {
   278  		t.Error("Failed to create 2 CA instances")
   279  	}
   280  
   281  	err = RunMain([]string{cmdName, "start", "-d", "-p", "7056", "-c", "../../testdata/test.yaml", "-b", "user:pass", "--cacount", "1", "--cafiles", "ca/rootca/ca1/fabric-ca-server-config.yaml", "--cafiles", "ca/rootca/ca2/fabric-ca-server-config.yaml"})
   282  	if err == nil {
   283  		t.Error("Should have failed to start server, can't specify values for both --cacount and --cafiles")
   284  	}
   285  }
   286  
   287  // Tests to see that the bootstrap by default has permission to register any attribute
   288  func TestRegistrarAttribute(t *testing.T) {
   289  	var err error
   290  	blockingStart = false
   291  
   292  	err = os.Setenv("FABRIC_CA_SERVER_HOME", "testregattr/server")
   293  	if !assert.NoError(t, err, "Failed to set environment variable") {
   294  		t.Fatal("Failed to set environment variable")
   295  	}
   296  
   297  	args := TestData{[]string{cmdName, "start", "-b", "admin:admin", "-p", "7096", "-d"}, ""}
   298  	os.Args = args.input
   299  	scmd := NewCommand(args.input[1], blockingStart)
   300  	// Execute the command
   301  	err = scmd.Execute()
   302  	if !assert.NoError(t, err, "Failed to start server") {
   303  		t.Fatal("Failed to start server")
   304  	}
   305  
   306  	client := getTestClient(7096, "testregattr/client")
   307  
   308  	resp, err := client.Enroll(&api.EnrollmentRequest{
   309  		Name:   "admin",
   310  		Secret: "admin",
   311  	})
   312  	if !assert.NoError(t, err, "Failed to enroll 'admin'") {
   313  		t.Fatal("Failed to enroll 'admin'")
   314  	}
   315  
   316  	adminIdentity := resp.Identity
   317  
   318  	_, err = adminIdentity.Register(&api.RegistrationRequest{
   319  		Name: "testuser",
   320  		Attributes: []api.Attribute{
   321  			api.Attribute{
   322  				Name:  "hf.Revoker",
   323  				Value: "true",
   324  			},
   325  			api.Attribute{
   326  				Name:  "hf.IntermediateCA",
   327  				Value: "true",
   328  			},
   329  			api.Attribute{
   330  				Name:  "hf.Registrar.Roles",
   331  				Value: "peer,client",
   332  			},
   333  		},
   334  	})
   335  	assert.NoError(t, err, "Bootstrap user 'admin' should have been able to register a user with attributes")
   336  }
   337  
   338  // TestTLSEnabledButCertfileNotSpecified tests if the server with default config starts
   339  // fine with --tls.enabled and with or without --tls.certfile flag. When
   340  // --tls.certfile is not specified, it should use default name 'tls-cert.pem'
   341  func TestTLSEnabledButCertfileNotSpecified(t *testing.T) {
   342  	blockingStart = false
   343  	rootHomeDir := "tlsintCATestRootSrvHome"
   344  	err := os.RemoveAll(rootHomeDir)
   345  	if err != nil {
   346  		t.Fatalf("Failed to remove directory %s: %s", rootHomeDir, err)
   347  	}
   348  	defer os.RemoveAll(rootHomeDir)
   349  
   350  	err = RunMain([]string{cmdName, "start", "-p", "7100", "-H", rootHomeDir, "-d", "-b", "admin:admin", "--tls.enabled"})
   351  	if err != nil {
   352  		t.Error("Server should not have failed to start when TLS is enabled and TLS cert file name is not specified...it should have used default TLS cert file name 'tls-cert.pem'", err)
   353  	}
   354  
   355  	// start the root server with TLS enabled
   356  	err = RunMain([]string{cmdName, "start", "-p", "7101", "-H", rootHomeDir, "-d", "-b", "admin:admin", "--tls.enabled",
   357  		"--tls.certfile", "tls-cert.pem"})
   358  	if err != nil {
   359  		t.Error("Server should not have failed to start when TLS is enabled and TLS cert file name is specified.", err)
   360  	}
   361  }
   362  
   363  func TestVersion(t *testing.T) {
   364  	err := RunMain([]string{cmdName, "version"})
   365  	if err != nil {
   366  		t.Error("Failed to get fabric-ca-server version: ", err)
   367  	}
   368  }
   369  
   370  func TestServerLogLevelCLI(t *testing.T) {
   371  	// Not passing in -b flag, don't need for the server to completely start to
   372  	// verify that the log level is correctly getting set
   373  	RunMain([]string{cmdName, "start", "--loglevel", "info"})
   374  	assert.Equal(t, log.Level, log.LOG_LEVEL_INFO)
   375  
   376  	RunMain([]string{cmdName, "start", "--loglevel", "debug"})
   377  	assert.Equal(t, log.Level, log.LOG_LEVEL_DEBUG)
   378  
   379  	RunMain([]string{cmdName, "start", "--loglevel", "warning"})
   380  	assert.Equal(t, log.Level, log.LOG_LEVEL_WARNING)
   381  
   382  	RunMain([]string{cmdName, "start", "--loglevel", "fatal"})
   383  	assert.Equal(t, log.Level, log.LOG_LEVEL_FATAL)
   384  
   385  	RunMain([]string{cmdName, "start", "--loglevel", "panic"})
   386  	assert.Equal(t, log.Level, log.LOG_LEVEL_PANIC)
   387  }
   388  
   389  func TestServerLogLevelEnvVar(t *testing.T) {
   390  	// Not passing in -b flag, don't need for the server to completely start to
   391  	// verify that the log level is correctly getting set
   392  	os.Setenv("FABRIC_CA_SERVER_LOGLEVEL", "info")
   393  	RunMain([]string{cmdName, "start"})
   394  	assert.Equal(t, log.LOG_LEVEL_INFO, log.Level)
   395  
   396  	os.Setenv("FABRIC_CA_SERVER_LOGLEVEL", "debug")
   397  	RunMain([]string{cmdName, "start"})
   398  	assert.Equal(t, log.LOG_LEVEL_DEBUG, log.Level)
   399  
   400  	os.Setenv("FABRIC_CA_SERVER_LOGLEVEL", "warning")
   401  	RunMain([]string{cmdName, "start"})
   402  	assert.Equal(t, log.LOG_LEVEL_WARNING, log.Level)
   403  
   404  	os.Setenv("FABRIC_CA_SERVER_LOGLEVEL", "fatal")
   405  	RunMain([]string{cmdName, "start"})
   406  	assert.Equal(t, log.LOG_LEVEL_FATAL, log.Level)
   407  
   408  	os.Setenv("FABRIC_CA_SERVER_LOGLEVEL", "panic")
   409  	RunMain([]string{cmdName, "start"})
   410  	assert.Equal(t, log.LOG_LEVEL_PANIC, log.Level)
   411  }
   412  
   413  // Run server with specified args and check if the configuration and datasource
   414  // files exist in the specified locations
   415  func checkConfigAndDBLoc(t *testing.T, args TestData, cfgFile string, dsFile string) {
   416  	checkTest(&args, t)
   417  	if _, err := os.Stat(cfgFile); os.IsNotExist(err) {
   418  		t.Errorf("Server configuration file is not found in the expected location: %v, TestData: %v",
   419  			err.Error(), args)
   420  	} else if _, err := os.Stat(dsFile); os.IsNotExist(err) {
   421  		t.Errorf("Datasource is not located in the location %s: %v, TestData: %v",
   422  			dsFile, err.Error(), args)
   423  	}
   424  }
   425  
   426  func TestClean(t *testing.T) {
   427  	defYaml := util.GetDefaultConfigFile(cmdName)
   428  	os.Remove(defYaml)
   429  	os.Remove(initYaml)
   430  	os.Remove(startYaml)
   431  	os.Remove(badSyntaxYaml)
   432  	os.Remove(fmt.Sprintf("/tmp/%s.yaml", longFileName))
   433  	os.Remove(unsupportedFileType)
   434  	os.Remove("ca-key.pem")
   435  	os.Remove("ca-cert.pem")
   436  	os.Remove("IssuerSecretKey")
   437  	os.Remove("IssuerPublicKey")
   438  	os.Remove("IssuerRevocationPublicKey")
   439  	os.Remove("fabric-ca-server.db")
   440  	os.RemoveAll("keystore")
   441  	os.RemoveAll("msp")
   442  	os.RemoveAll("../../testdata/msp")
   443  	os.Remove("../../testdata/fabric-ca-server.db")
   444  	os.Remove("../../testdata/ca-cert.pem")
   445  	os.Remove("../../testdata/IssuerSecretKey")
   446  	os.Remove("../../testdata/IssuerPublicKey")
   447  	os.Remove("../../testdata/IssuerRevocationPublicKey")
   448  	os.RemoveAll(ldapTestDir)
   449  	os.RemoveAll("testregattr")
   450  }
   451  
   452  func cleanUpMultiCAFiles() {
   453  	caFolder := "../../testdata/ca/rootca"
   454  	nestedFolders := []string{"ca1", "ca2"}
   455  	removeFiles := []string{"msp", "ca-cert.pem", "ca-key.pem", "fabric-ca-server.db",
   456  		"fabric-ca2-server.db", "IssuerSecretKey", "IssuerPublicKey", "IssuerRevocationPublicKey"}
   457  
   458  	for _, nestedFolder := range nestedFolders {
   459  		path := filepath.Join(caFolder, nestedFolder)
   460  		for _, file := range removeFiles {
   461  			os.RemoveAll(filepath.Join(path, file))
   462  		}
   463  		os.RemoveAll(filepath.Join(path, "msp"))
   464  	}
   465  
   466  	os.Remove("../../testdata/test.yaml")
   467  }
   468  
   469  func getTestClient(port int, homeDir string) *lib.Client {
   470  	return &lib.Client{
   471  		Config:  &lib.ClientConfig{URL: fmt.Sprintf("http://localhost:%d", port)},
   472  		HomeDir: homeDir,
   473  	}
   474  }
   475  
   476  func TestConfigInit(t *testing.T) {
   477  	cwd, err := os.Getwd()
   478  	if err != nil {
   479  		t.Fatalf("failed to get current working directory: %s", err)
   480  	}
   481  	certFile := "testdata/tls_server-cert.pem"
   482  	keyFile := "testdata/tls_server-key.pem"
   483  	homeDir := filepath.Join(cwd, "../../")
   484  	absCertFile := filepath.Join(homeDir, certFile)
   485  	absKeyFile := filepath.Join(homeDir, keyFile)
   486  
   487  	cases := []struct {
   488  		enabled bool
   489  		cert    string
   490  		key     string
   491  		err     bool
   492  	}{
   493  		{
   494  			enabled: true,
   495  			cert:    certFile,
   496  			key:     keyFile,
   497  			err:     true,
   498  		},
   499  		{
   500  			enabled: true,
   501  			cert:    "noexit.pem",
   502  			key:     keyFile,
   503  			err:     false,
   504  		},
   505  		{
   506  			enabled: true,
   507  			cert:    certFile,
   508  			key:     "noexit.pem",
   509  			err:     false,
   510  		},
   511  		{
   512  			enabled: false,
   513  			cert:    certFile,
   514  			key:     keyFile,
   515  			err:     true,
   516  		},
   517  		{
   518  			enabled: true,
   519  			cert:    absCertFile,
   520  			key:     absKeyFile,
   521  			err:     true,
   522  		},
   523  	}
   524  
   525  	for _, tt := range cases {
   526  		var s ServerCmd
   527  		s.cfg = &lib.ServerConfig{}
   528  		s.homeDirectory = homeDir
   529  		s.myViper = viper.New()
   530  		s.myViper.SetEnvPrefix(envVarPrefix)
   531  		s.myViper.Set("operations.tls.enabled", tt.enabled)
   532  		s.myViper.Set("operations.tls.cert.file", tt.cert)
   533  		s.myViper.Set("operations.tls.key.file", tt.key)
   534  		s.myViper.Set("boot", "user:pass")
   535  		err := s.configInit()
   536  		if err != nil && tt.err {
   537  			t.Error(err)
   538  		}
   539  		defYaml := util.GetDefaultConfigFile(cmdName)
   540  		os.Remove(defYaml)
   541  	}
   542  }
   543  
   544  func TestOperationsTLSCertKeyConfig(t *testing.T) {
   545  	certFile := "tls_server-cert.pem"
   546  	keyFile := "tls_server-key.pem"
   547  
   548  	cmd := &ServerCmd{
   549  		myViper:     viper.New(),
   550  		cfgFileName: "../../testdata/testviperunmarshal.yaml",
   551  		cfg:         &lib.ServerConfig{},
   552  	}
   553  	cmd.myViper.Set("boot", "user:pass")
   554  
   555  	err := cmd.configInit()
   556  	if err != nil {
   557  		t.Error(err)
   558  	}
   559  
   560  	cwd, err := os.Getwd()
   561  	if err != nil {
   562  		t.Fatalf("failed to get current working directory: %s", err)
   563  	}
   564  	homeDir := filepath.Join(cwd, "../../testdata")
   565  
   566  	assert.Equal(t, cmd.cfg.Operations.TLS.CertFile, filepath.Join(homeDir, certFile))
   567  	assert.Equal(t, cmd.cfg.Operations.TLS.KeyFile, filepath.Join(homeDir, keyFile))
   568  }