test: add helper for ioutil.TempDir/TempFile

This creates a simplified helper for temporary directories and files.
All path names are prefixed with the name of the current test.
All files and directories are stored either in /tmp/consul-test
or /tmp if the former could not be created.

Using the system temp dir breaks some tests on macOS where the unix
socket path becomes too long.
This commit is contained in:
Frank Schroeder 2017-05-12 15:41:13 +02:00 committed by Frank Schröder
parent 9993095448
commit 65b5c51ec7
25 changed files with 198 additions and 262 deletions

View File

@ -32,10 +32,7 @@ func TestAgent_Reload(t *testing.T) {
t.Parallel() t.Parallel()
// Create our initial empty config file, to be overwritten later // Create our initial empty config file, to be overwritten later
configFile, err := ioutil.TempFile("", t.Name()+"-reload") configFile := testutil.TempFile(t, "reload")
if err != nil {
t.Fatalf("err: %s", err)
}
if _, err := configFile.Write([]byte("{}")); err != nil { if _, err := configFile.Write([]byte("{}")); err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
@ -50,7 +47,7 @@ func TestAgent_Reload(t *testing.T) {
// Update the config file with a service definition // Update the config file with a service definition
config := `{"service":{"name":"redis", "port":1234}}` config := `{"service":{"name":"redis", "port":1234}}`
err = ioutil.WriteFile(configFile.Name(), []byte(config), 0644) err := ioutil.WriteFile(configFile.Name(), []byte(config), 0644)
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }

View File

@ -4,7 +4,6 @@ import (
crand "crypto/rand" crand "crypto/rand"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -44,7 +43,7 @@ func makeClientWithConfig(
cb1(conf) cb1(conf)
} }
// Create server // Create server
server, err := testutil.NewTestServerConfig(t.Name(), cb2) server, err := testutil.NewTestServerConfigT(t, cb2)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -481,10 +480,7 @@ func TestAPI_UnixSocket(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
tempDir, err := ioutil.TempDir("", t.Name()+"-consul") tempDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tempDir) defer os.RemoveAll(tempDir)
socket := filepath.Join(tempDir, "test.sock") socket := filepath.Join(tempDir, "test.sock")

View File

@ -3,7 +3,6 @@ package agent
import ( import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"strings" "strings"
"testing" "testing"
@ -12,6 +11,7 @@ import (
rawacl "github.com/hashicorp/consul/acl" rawacl "github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/serf/serf" "github.com/hashicorp/serf/serf"
) )
@ -21,10 +21,7 @@ func TestACL_Bad_Config(t *testing.T) {
config.ACLDownPolicy = "nope" config.ACLDownPolicy = "nope"
var err error var err error
config.DataDir, err = ioutil.TempDir("", t.Name()+"-agent") config.DataDir = testutil.TempDir(t, "agent")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(config.DataDir) defer os.RemoveAll(config.DataDir)
_, err = Create(config, nil, nil, nil) _, err = Create(config, nil, nil, nil)

View File

@ -17,6 +17,7 @@ import (
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/testutil/retry" "github.com/hashicorp/consul/testutil/retry"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/serf/serf" "github.com/hashicorp/serf/serf"
@ -243,18 +244,12 @@ func TestAgent_Self_ACLDeny(t *testing.T) {
func TestAgent_Reload(t *testing.T) { func TestAgent_Reload(t *testing.T) {
conf := nextConfig() conf := nextConfig()
tmpDir, err := ioutil.TempDir("", t.Name()+"-consul") tmpDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// Write initial config, to be reloaded later // Write initial config, to be reloaded later
tmpFile, err := ioutil.TempFile(tmpDir, "config") tmpFile := testutil.TempFile(t, "config")
if err != nil { _, err := tmpFile.WriteString(`{"acl_enforce_version_8": false, "service":{"name":"redis"}}`)
t.Fatalf("err: %s", err)
}
_, err = tmpFile.WriteString(`{"acl_enforce_version_8": false, "service":{"name":"redis"}}`)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }

View File

@ -21,6 +21,7 @@ import (
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/consul/version" "github.com/hashicorp/consul/version"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
@ -96,10 +97,7 @@ func nextConfig() *Config {
} }
func makeAgentLog(t *testing.T, conf *Config, l io.Writer, writer *logger.LogWriter) (string, *Agent) { func makeAgentLog(t *testing.T, conf *Config, l io.Writer, writer *logger.LogWriter) (string, *Agent) {
dir, err := ioutil.TempDir("", t.Name()+"-agent") dir := testutil.TempDir(t, "agent")
if err != nil {
t.Fatalf(fmt.Sprintf("err: %v", err))
}
conf.DataDir = dir conf.DataDir = dir
agent, err := Create(conf, l, writer, nil) agent, err := Create(conf, l, writer, nil)
@ -112,10 +110,7 @@ func makeAgentLog(t *testing.T, conf *Config, l io.Writer, writer *logger.LogWri
} }
func makeAgentKeyring(t *testing.T, conf *Config, key string) (string, *Agent) { func makeAgentKeyring(t *testing.T, conf *Config, key string) (string, *Agent) {
dir, err := ioutil.TempDir("", t.Name()+"-agent") dir := testutil.TempDir(t, "agent")
if err != nil {
t.Fatalf("err: %v", err)
}
conf.DataDir = dir conf.DataDir = dir

View File

@ -2,7 +2,6 @@ package agent
import ( import (
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os" "os"
"os/exec" "os/exec"
@ -12,6 +11,7 @@ import (
"testing" "testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/testutil/retry" "github.com/hashicorp/consul/testutil/retry"
"github.com/hashicorp/consul/version" "github.com/hashicorp/consul/version"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
@ -103,10 +103,7 @@ func TestRetryJoin(t *testing.T) {
defer agent.Shutdown() defer agent.Shutdown()
conf2 := nextConfig() conf2 := nextConfig()
tmpDir, err := ioutil.TempDir("", t.Name()+"-consul") tmpDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
doneCh := make(chan struct{}) doneCh := make(chan struct{})
@ -162,10 +159,7 @@ func TestRetryJoin(t *testing.T) {
} }
func TestReadCliConfig(t *testing.T) { func TestReadCliConfig(t *testing.T) {
tmpDir, err := ioutil.TempDir("", t.Name()+"-consul") tmpDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
shutdownCh := make(chan struct{}) shutdownCh := make(chan struct{})
@ -294,10 +288,7 @@ func TestReadCliConfig(t *testing.T) {
func TestRetryJoinFail(t *testing.T) { func TestRetryJoinFail(t *testing.T) {
conf := nextConfig() conf := nextConfig()
tmpDir, err := ioutil.TempDir("", t.Name()+"-consul") tmpDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
shutdownCh := make(chan struct{}) shutdownCh := make(chan struct{})
@ -325,10 +316,7 @@ func TestRetryJoinFail(t *testing.T) {
func TestRetryJoinWanFail(t *testing.T) { func TestRetryJoinWanFail(t *testing.T) {
conf := nextConfig() conf := nextConfig()
tmpDir, err := ioutil.TempDir("", t.Name()+"-consul") tmpDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
shutdownCh := make(chan struct{}) shutdownCh := make(chan struct{})
@ -413,24 +401,18 @@ func TestDiscoverGCEHosts(t *testing.T) {
} }
func TestProtectDataDir(t *testing.T) { func TestProtectDataDir(t *testing.T) {
dir, err := ioutil.TempDir("", t.Name()+"-consul") dir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
if err := os.MkdirAll(filepath.Join(dir, "mdb"), 0700); err != nil { if err := os.MkdirAll(filepath.Join(dir, "mdb"), 0700); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
cfgFile, err := ioutil.TempFile("", t.Name()+"-consul") cfgFile := testutil.TempFile(t, "consul")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.Remove(cfgFile.Name()) defer os.Remove(cfgFile.Name())
content := fmt.Sprintf(`{"server": true, "data_dir": "%s"}`, dir) content := fmt.Sprintf(`{"server": true, "data_dir": "%s"}`, dir)
_, err = cfgFile.Write([]byte(content)) _, err := cfgFile.Write([]byte(content))
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -449,10 +431,7 @@ func TestProtectDataDir(t *testing.T) {
} }
func TestBadDataDirPermissions(t *testing.T) { func TestBadDataDirPermissions(t *testing.T) {
dir, err := ioutil.TempDir("", t.Name()+"-consul") dir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
dataDir := filepath.Join(dir, "mdb") dataDir := filepath.Join(dir, "mdb")

View File

@ -14,6 +14,7 @@ import (
"time" "time"
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/testutil"
) )
func TestConfigEncryptBytes(t *testing.T) { func TestConfigEncryptBytes(t *testing.T) {
@ -1797,10 +1798,7 @@ func TestReadConfigPaths_badPath(t *testing.T) {
} }
func TestReadConfigPaths_file(t *testing.T) { func TestReadConfigPaths_file(t *testing.T) {
tf, err := ioutil.TempFile("", t.Name()+"-consul") tf := testutil.TempFile(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
tf.Write([]byte(`{"node_name":"bar"}`)) tf.Write([]byte(`{"node_name":"bar"}`))
tf.Close() tf.Close()
defer os.Remove(tf.Name()) defer os.Remove(tf.Name())
@ -1816,13 +1814,10 @@ func TestReadConfigPaths_file(t *testing.T) {
} }
func TestReadConfigPaths_dir(t *testing.T) { func TestReadConfigPaths_dir(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
err = ioutil.WriteFile(filepath.Join(td, "a.json"), err := ioutil.WriteFile(filepath.Join(td, "a.json"),
[]byte(`{"node_name": "bar"}`), 0644) []byte(`{"node_name": "bar"}`), 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)

View File

@ -22,6 +22,7 @@ import (
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-cleanhttp"
) )
@ -77,12 +78,9 @@ func TestHTTPServer_UnixSocket(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
tempDir, err := ioutil.TempDir("", t.Name()+"-consul") tempDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tempDir) defer os.RemoveAll(tempDir)
socket := filepath.Join(tempDir, t.Name()+".sock") socket := filepath.Join(tempDir, "test.sock")
dir, srv := makeHTTPServerWithConfig(t, func(c *Config) { dir, srv := makeHTTPServerWithConfig(t, func(c *Config) {
c.Addresses.HTTP = "unix://" + socket c.Addresses.HTTP = "unix://" + socket
@ -139,12 +137,9 @@ func TestHTTPServer_UnixSocket_FileExists(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
tempDir, err := ioutil.TempDir("", t.Name()+"-consul") tempDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tempDir) defer os.RemoveAll(tempDir)
socket := filepath.Join(tempDir, t.Name()+".sock") socket := filepath.Join(tempDir, "test.sock")
// Create a regular file at the socket path // Create a regular file at the socket path
if err := ioutil.WriteFile(socket, []byte("hello world"), 0644); err != nil { if err := ioutil.WriteFile(socket, []byte("hello world"), 0644); err != nil {

View File

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
) )
func TestAgent_LoadKeyrings(t *testing.T) { func TestAgent_LoadKeyrings(t *testing.T) {
@ -81,10 +82,7 @@ func TestAgent_InitKeyring(t *testing.T) {
key2 := "4leC33rgtXKIVUr9Nr0snQ==" key2 := "4leC33rgtXKIVUr9Nr0snQ=="
expected := fmt.Sprintf(`["%s"]`, key1) expected := fmt.Sprintf(`["%s"]`, key1)
dir, err := ioutil.TempDir("", t.Name()+"-consul") dir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
file := filepath.Join(dir, "keyring") file := filepath.Join(dir, "keyring")

View File

@ -15,15 +15,13 @@ import (
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-cleanhttp"
) )
func TestUiIndex(t *testing.T) { func TestUiIndex(t *testing.T) {
// Make a test dir to serve UI files // Make a test dir to serve UI files
uiDir, err := ioutil.TempDir("", t.Name()+"-consul") uiDir := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(uiDir) defer os.RemoveAll(uiDir)
// Make the server // Make the server

View File

@ -1,11 +1,12 @@
package agent package agent
import ( import (
"io/ioutil"
"os" "os"
"runtime" "runtime"
"testing" "testing"
"time" "time"
"github.com/hashicorp/consul/testutil"
) )
func TestAEScale(t *testing.T) { func TestAEScale(t *testing.T) {
@ -37,10 +38,7 @@ func TestSetFilePermissions(t *testing.T) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
t.SkipNow() t.SkipNow()
} }
tempFile, err := ioutil.TempFile("", t.Name()+"-consul") tempFile := testutil.TempFile(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
path := tempFile.Name() path := tempFile.Name()
defer os.Remove(path) defer os.Remove(path)

View File

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -25,10 +26,7 @@ func TestConfigTestCommand_implements(t *testing.T) {
} }
func TestConfigTestCommandFailOnEmptyFile(t *testing.T) { func TestConfigTestCommandFailOnEmptyFile(t *testing.T) {
tmpFile, err := ioutil.TempFile("", t.Name()+"-consul") tmpFile := testutil.TempFile(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpFile.Name()) defer os.RemoveAll(tmpFile.Name())
_, cmd := testConfigTestCommand(t) _, cmd := testConfigTestCommand(t)
@ -43,10 +41,7 @@ func TestConfigTestCommandFailOnEmptyFile(t *testing.T) {
} }
func TestConfigTestCommandSucceedOnEmptyDir(t *testing.T) { func TestConfigTestCommandSucceedOnEmptyDir(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
ui, cmd := testConfigTestCommand(t) ui, cmd := testConfigTestCommand(t)
@ -61,14 +56,11 @@ func TestConfigTestCommandSucceedOnEmptyDir(t *testing.T) {
} }
func TestConfigTestCommandSucceedOnMinimalConfigFile(t *testing.T) { func TestConfigTestCommandSucceedOnMinimalConfigFile(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
fp := filepath.Join(td, "config.json") fp := filepath.Join(td, "config.json")
err = ioutil.WriteFile(fp, []byte(`{}`), 0644) err := ioutil.WriteFile(fp, []byte(`{}`), 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
@ -85,13 +77,10 @@ func TestConfigTestCommandSucceedOnMinimalConfigFile(t *testing.T) {
} }
func TestConfigTestCommandSucceedOnMinimalConfigDir(t *testing.T) { func TestConfigTestCommandSucceedOnMinimalConfigDir(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
err = ioutil.WriteFile(filepath.Join(td, "config.json"), []byte(`{}`), 0644) err := ioutil.WriteFile(filepath.Join(td, "config.json"), []byte(`{}`), 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
@ -108,13 +97,10 @@ func TestConfigTestCommandSucceedOnMinimalConfigDir(t *testing.T) {
} }
func TestConfigTestCommandSucceedOnConfigDirWithEmptyFile(t *testing.T) { func TestConfigTestCommandSucceedOnConfigDirWithEmptyFile(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
err = ioutil.WriteFile(filepath.Join(td, "config.json"), []byte{}, 0644) err := ioutil.WriteFile(filepath.Join(td, "config.json"), []byte{}, 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }

View File

@ -2,9 +2,10 @@ package command
import ( import (
"encoding/base64" "encoding/base64"
"testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"testing"
) )
func TestKeygenCommand_implements(t *testing.T) { func TestKeygenCommand_implements(t *testing.T) {

View File

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"io" "io"
"io/ioutil"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@ -12,6 +11,7 @@ import (
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -179,10 +179,7 @@ func TestKVPutCommand_File(t *testing.T) {
ui, c := testKVPutCommand(t) ui, c := testKVPutCommand(t)
f, err := ioutil.TempFile("", t.Name()+"-kv-put-command-file") f := testutil.TempFile(t, "kv-put-command-file")
if err != nil {
t.Fatalf("err: %#v", err)
}
defer os.Remove(f.Name()) defer os.Remove(f.Name())
if _, err := f.WriteString("bar"); err != nil { if _, err := f.WriteString("bar"); err != nil {
t.Fatalf("err: %#v", err) t.Fatalf("err: %#v", err)

View File

@ -2,10 +2,11 @@ package command
import ( import (
"fmt" "fmt"
"github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli"
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli"
) )
func testMembersCommand(t *testing.T) (*cli.MockUi, *MembersCommand) { func testMembersCommand(t *testing.T) (*cli.MockUi, *MembersCommand) {

View File

@ -2,13 +2,13 @@ package command
import ( import (
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -73,10 +73,7 @@ func TestSnapshotInspectCommand_Run(t *testing.T) {
defer srv.Shutdown() defer srv.Shutdown()
waitForLeader(t, srv.httpAddr) waitForLeader(t, srv.httpAddr)
dir, err := ioutil.TempDir("", t.Name()+"-snapshot") dir := testutil.TempDir(t, "snapshot")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
file := path.Join(dir, "backup.tgz") file := path.Join(dir, "backup.tgz")

View File

@ -2,13 +2,13 @@ package command
import ( import (
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -75,10 +75,7 @@ func TestSnapshotRestoreCommand_Run(t *testing.T) {
ui, c := testSnapshotRestoreCommand(t) ui, c := testSnapshotRestoreCommand(t)
dir, err := ioutil.TempDir("", t.Name()+"-snapshot") dir := testutil.TempDir(t, "snapshot")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
file := path.Join(dir, "backup.tgz") file := path.Join(dir, "backup.tgz")

View File

@ -1,13 +1,13 @@
package command package command
import ( import (
"io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -74,10 +74,7 @@ func TestSnapshotSaveCommand_Run(t *testing.T) {
ui, c := testSnapshotSaveCommand(t) ui, c := testSnapshotSaveCommand(t)
dir, err := ioutil.TempDir("", t.Name()+"-snapshot") dir := testutil.TempDir(t, "snapshot")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
file := path.Join(dir, "backup.tgz") file := path.Join(dir, "backup.tgz")

View File

@ -2,7 +2,6 @@ package command
import ( import (
"fmt" "fmt"
"io/ioutil"
"math/rand" "math/rand"
"os" "os"
"strings" "strings"
@ -14,6 +13,7 @@ import (
"github.com/hashicorp/consul/command/agent" "github.com/hashicorp/consul/command/agent"
"github.com/hashicorp/consul/consul" "github.com/hashicorp/consul/consul"
"github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/consul/version" "github.com/hashicorp/consul/version"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
@ -67,10 +67,7 @@ func testAgentWithConfigReload(t *testing.T, cb func(c *agent.Config), reloadCh
cb(conf) cb(conf)
} }
dir, err := ioutil.TempDir("", t.Name()+"-agent") dir := testutil.TempDir(t, "agent")
if err != nil {
t.Fatalf(fmt.Sprintf("err: %v", err))
}
conf.DataDir = dir conf.DataDir = dir
a, err := agent.Create(conf, lw, nil, reloadCh) a, err := agent.Create(conf, lw, nil, reloadCh)

View File

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/testutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -25,10 +26,7 @@ func TestValidateCommand_implements(t *testing.T) {
} }
func TestValidateCommandFailOnEmptyFile(t *testing.T) { func TestValidateCommandFailOnEmptyFile(t *testing.T) {
tmpFile, err := ioutil.TempFile("", t.Name()+"-consul") tmpFile := testutil.TempFile(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpFile.Name()) defer os.RemoveAll(tmpFile.Name())
_, cmd := testValidateCommand(t) _, cmd := testValidateCommand(t)
@ -41,10 +39,7 @@ func TestValidateCommandFailOnEmptyFile(t *testing.T) {
} }
func TestValidateCommandSucceedOnEmptyDir(t *testing.T) { func TestValidateCommandSucceedOnEmptyDir(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
ui, cmd := testValidateCommand(t) ui, cmd := testValidateCommand(t)
@ -57,14 +52,11 @@ func TestValidateCommandSucceedOnEmptyDir(t *testing.T) {
} }
func TestValidateCommandSucceedOnMinimalConfigFile(t *testing.T) { func TestValidateCommandSucceedOnMinimalConfigFile(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
fp := filepath.Join(td, "config.json") fp := filepath.Join(td, "config.json")
err = ioutil.WriteFile(fp, []byte(`{}`), 0644) err := ioutil.WriteFile(fp, []byte(`{}`), 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
@ -79,13 +71,10 @@ func TestValidateCommandSucceedOnMinimalConfigFile(t *testing.T) {
} }
func TestValidateCommandSucceedOnMinimalConfigDir(t *testing.T) { func TestValidateCommandSucceedOnMinimalConfigDir(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
err = ioutil.WriteFile(filepath.Join(td, "config.json"), []byte(`{}`), 0644) err := ioutil.WriteFile(filepath.Join(td, "config.json"), []byte(`{}`), 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
@ -100,13 +89,10 @@ func TestValidateCommandSucceedOnMinimalConfigDir(t *testing.T) {
} }
func TestValidateCommandSucceedOnConfigDirWithEmptyFile(t *testing.T) { func TestValidateCommandSucceedOnConfigDirWithEmptyFile(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
err = ioutil.WriteFile(filepath.Join(td, "config.json"), []byte{}, 0644) err := ioutil.WriteFile(filepath.Join(td, "config.json"), []byte{}, 0644)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
@ -121,10 +107,7 @@ func TestValidateCommandSucceedOnConfigDirWithEmptyFile(t *testing.T) {
} }
func TestValidateCommandQuiet(t *testing.T) { func TestValidateCommandQuiet(t *testing.T) {
td, err := ioutil.TempDir("", t.Name()+"-consul") td := testutil.TempDir(t, "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(td) defer os.RemoveAll(td)
ui, cmd := testValidateCommand(t) ui, cmd := testValidateCommand(t)

View File

@ -11,13 +11,14 @@ import (
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/testutil/retry" "github.com/hashicorp/consul/testutil/retry"
"github.com/hashicorp/net-rpc-msgpackrpc" "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/serf/serf" "github.com/hashicorp/serf/serf"
) )
func testClientConfig(t *testing.T, NodeName string) (string, *Config) { func testClientConfig(t *testing.T, NodeName string) (string, *Config) {
dir := tmpDir(t) dir := testutil.TempDir(t, "consul")
config := DefaultConfig() config := DefaultConfig()
config.Datacenter = "dc1" config.Datacenter = "dc1"
config.DataDir = dir config.DataDir = dir

View File

@ -2,7 +2,6 @@ package consul
import ( import (
"fmt" "fmt"
"io/ioutil"
"net" "net"
"os" "os"
"strings" "strings"
@ -12,6 +11,7 @@ import (
"github.com/hashicorp/consul/consul/agent" "github.com/hashicorp/consul/consul/agent"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/testutil/retry" "github.com/hashicorp/consul/testutil/retry"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
@ -23,14 +23,6 @@ func getPort() int {
return int(atomic.AddInt32(&nextPort, 1)) return int(atomic.AddInt32(&nextPort, 1))
} }
func tmpDir(t *testing.T) string {
dir, err := ioutil.TempDir("", t.Name()+"-consul")
if err != nil {
t.Fatalf("err: %v", err)
}
return dir
}
func configureTLS(config *Config) { func configureTLS(config *Config) {
config.CAFile = "../test/ca/root.cer" config.CAFile = "../test/ca/root.cer"
config.CertFile = "../test/key/ourdomain.cer" config.CertFile = "../test/key/ourdomain.cer"
@ -38,7 +30,7 @@ func configureTLS(config *Config) {
} }
func testServerConfig(t *testing.T, NodeName string) (string, *Config) { func testServerConfig(t *testing.T, NodeName string) (string, *Config) {
dir := tmpDir(t) dir := testutil.TempDir(t, "consul")
config := DefaultConfig() config := DefaultConfig()
config.NodeName = NodeName config.NodeName = NodeName

View File

@ -5,7 +5,6 @@ import (
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"path" "path"
@ -14,6 +13,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/go-msgpack/codec" "github.com/hashicorp/go-msgpack/codec"
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
) )
@ -126,10 +126,7 @@ func makeRaft(t *testing.T, dir string) (*raft.Raft, *MockFSM) {
} }
func TestSnapshot(t *testing.T) { func TestSnapshot(t *testing.T) {
dir, err := ioutil.TempDir("", t.Name()+"-snapshot") dir := testutil.TempDir(t, "snapshot")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
// Make a Raft and populate it with some data. We tee everything we // Make a Raft and populate it with some data. We tee everything we
@ -238,10 +235,7 @@ func TestSnapshot_BadVerify(t *testing.T) {
} }
func TestSnapshot_BadRestore(t *testing.T) { func TestSnapshot_BadRestore(t *testing.T) {
dir, err := ioutil.TempDir("", t.Name()+"-snapshot") dir := testutil.TempDir(t, "snapshot")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
// Make a Raft and populate it with some data. // Make a Raft and populate it with some data.

59
testutil/io.go Normal file
View File

@ -0,0 +1,59 @@
package testutil
import (
"fmt"
"io/ioutil"
"os"
"testing"
)
// tmpdir is the base directory for all temporary directories
// and files created with TempDir and TempFile. This could be
// achieved by setting a system environment variable but then
// the test execution would depend on whether or not the
// environment variable is set.
//
// On macOS the temp base directory is quite long and that
// triggers a problem with some tests that bind to UNIX sockets
// where the filename seems to be too long. Using a shorter name
// fixes this and makes the paths more readable.
//
// It also provides a single base directory for cleanup.
var tmpdir = "/tmp/consul-test"
func init() {
if err := os.MkdirAll(tmpdir, 0755); err != nil {
fmt.Println("Cannot create %s. Reverting to /tmp", tmpdir)
tmpdir = "/tmp"
}
}
// TempDir creates a temporary directory within tmpdir
// with the name 'testname-name'. If the directory cannot
// be created t.Fatal is called.
func TempDir(t *testing.T, name string) string {
if t != nil && t.Name() != "" {
name = t.Name() + "-" + name
}
d, err := ioutil.TempDir(tmpdir, name)
if err != nil {
t.Fatalf("err: %s", err)
}
return d
}
// TempFile creates a temporary file within tmpdir
// with the name 'testname-name'. If the file cannot
// be created t.Fatal is called. If a temporary directory
// has been created before consider storing the file
// inside this directory to avoid double cleanup.
func TempFile(t *testing.T, name string) *os.File {
if t != nil && t.Name() != "" {
name = t.Name() + "-" + name
}
f, err := ioutil.TempFile(tmpdir, name)
if err != nil {
t.Fatalf("err: %s", err)
}
return f
}

View File

@ -21,8 +21,10 @@ import (
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"testing"
"time" "time"
"github.com/hashicorp/consul/testutil/retry" "github.com/hashicorp/consul/testutil/retry"
@ -169,67 +171,61 @@ type TestServer struct {
WANAddr string WANAddr string
HTTPClient *http.Client HTTPClient *http.Client
tmpdir string
} }
// NewTestServer is an easy helper method to create a new Consul // NewTestServer is an easy helper method to create a new Consul
// test server with the most basic configuration. // test server with the most basic configuration.
func NewTestServer(name string) (*TestServer, error) { func NewTestServer() (*TestServer, error) {
return NewTestServerConfig(name, nil) return NewTestServerConfigT(nil, nil)
}
func NewTestServerConfig(cb ServerConfigCallback) (*TestServer, error) {
return NewTestServerConfigT(nil, cb)
} }
// NewTestServerConfig creates a new TestServer, and makes a call to an optional // NewTestServerConfig creates a new TestServer, and makes a call to an optional
// callback function to modify the configuration. If there is an error // callback function to modify the configuration. If there is an error
// configuring or starting the server, the server will NOT be running when the // configuring or starting the server, the server will NOT be running when the
// function returns (thus you do not need to stop it). // function returns (thus you do not need to stop it).
func NewTestServerConfig(name string, cb ServerConfigCallback) (*TestServer, error) { func NewTestServerConfigT(t *testing.T, cb ServerConfigCallback) (*TestServer, error) {
if path, err := exec.LookPath("consul"); err != nil || path == "" { path, err := exec.LookPath("consul")
if err != nil || path == "" {
return nil, fmt.Errorf("consul not found on $PATH - download and install " + return nil, fmt.Errorf("consul not found on $PATH - download and install " +
"consul or skip this test") "consul or skip this test")
} }
dataDir, err := ioutil.TempDir("", name+"-consul") tmpdir := TempDir(t, "consul")
if err != nil { cfg := defaultServerConfig()
return nil, errors.Wrap(err, "failed creating tempdir") cfg.DataDir = filepath.Join(tmpdir, "data")
}
configFile, err := ioutil.TempFile(dataDir, name+"-config")
if err != nil {
defer os.RemoveAll(dataDir)
return nil, errors.Wrap(err, "failed creating temp config")
}
consulConfig := defaultServerConfig()
consulConfig.DataDir = dataDir
if cb != nil { if cb != nil {
cb(consulConfig) cb(cfg)
} }
configContent, err := json.Marshal(consulConfig) b, err := json.Marshal(cfg)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed marshaling json") return nil, errors.Wrap(err, "failed marshaling json")
} }
if _, err := configFile.Write(configContent); err != nil { configFile := filepath.Join(tmpdir, "config.json")
defer configFile.Close() if err := ioutil.WriteFile(configFile, b, 0644); err != nil {
defer os.RemoveAll(dataDir) defer os.RemoveAll(tmpdir)
return nil, errors.Wrap(err, "failed writing config content") return nil, errors.Wrap(err, "failed writing config content")
} }
configFile.Close()
stdout := io.Writer(os.Stdout) stdout := io.Writer(os.Stdout)
if consulConfig.Stdout != nil { if cfg.Stdout != nil {
stdout = consulConfig.Stdout stdout = cfg.Stdout
} }
stderr := io.Writer(os.Stderr) stderr := io.Writer(os.Stderr)
if consulConfig.Stderr != nil { if cfg.Stderr != nil {
stderr = consulConfig.Stderr stderr = cfg.Stderr
} }
// Start the server // Start the server
args := []string{"agent", "-config-file", configFile.Name()} args := []string{"agent", "-config-file", configFile}
args = append(args, consulConfig.Args...) args = append(args, cfg.Args...)
cmd := exec.Command("consul", args...) cmd := exec.Command("consul", args...)
cmd.Stdout = stdout cmd.Stdout = stdout
cmd.Stderr = stderr cmd.Stderr = stderr
@ -237,68 +233,63 @@ func NewTestServerConfig(name string, cb ServerConfigCallback) (*TestServer, err
return nil, errors.Wrap(err, "failed starting command") return nil, errors.Wrap(err, "failed starting command")
} }
var httpAddr string httpAddr := fmt.Sprintf("127.0.0.1:%d", cfg.Ports.HTTP)
var client *http.Client client := cleanhttp.DefaultClient()
if strings.HasPrefix(consulConfig.Addresses.HTTP, "unix://") { if strings.HasPrefix(cfg.Addresses.HTTP, "unix://") {
httpAddr = consulConfig.Addresses.HTTP httpAddr = cfg.Addresses.HTTP
trans := cleanhttp.DefaultTransport() tr := cleanhttp.DefaultTransport()
trans.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) { tr.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
return net.Dial("unix", httpAddr[7:]) return net.Dial("unix", httpAddr[len("unix://"):])
} }
client = &http.Client{ client = &http.Client{Transport: tr}
Transport: trans,
}
} else {
httpAddr = fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.HTTP)
client = cleanhttp.DefaultClient()
} }
server := &TestServer{ server := &TestServer{
Config: consulConfig, Config: cfg,
cmd: cmd, cmd: cmd,
HTTPAddr: httpAddr, HTTPAddr: httpAddr,
HTTPSAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.HTTPS), HTTPSAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.HTTPS),
LANAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.SerfLan), LANAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.SerfLan),
WANAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.SerfWan), WANAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.SerfWan),
HTTPClient: client, HTTPClient: client,
tmpdir: tmpdir,
} }
// Wait for the server to be ready // Wait for the server to be ready
var startErr error if cfg.Bootstrap {
if consulConfig.Bootstrap { err = server.waitForLeader()
startErr = server.waitForLeader()
} else { } else {
startErr = server.waitForAPI() err = server.waitForAPI()
} }
if startErr != nil { if err != nil {
defer server.Stop() defer server.Stop()
return nil, errors.Wrap(startErr, "failed waiting for server to start") return nil, errors.Wrap(err, "failed waiting for server to start")
} }
return server, nil return server, nil
} }
// Stop stops the test Consul server, and removes the Consul data // Stop stops the test Consul server, and removes the Consul data
// directory once we are done. // directory once we are done.
func (s *TestServer) Stop() error { func (s *TestServer) Stop() error {
defer os.RemoveAll(s.Config.DataDir) defer os.RemoveAll(s.tmpdir)
if s.cmd != nil {
if s.cmd.Process != nil {
if err := s.cmd.Process.Kill(); err != nil {
return errors.Wrap(err, "failed to kill consul server")
}
}
// wait for the process to exit to be sure that the data dir can be
// deleted on all platforms.
return s.cmd.Wait()
}
// There was no process // There was no process
return nil if s.cmd == nil {
return nil
}
if s.cmd.Process != nil {
if err := s.cmd.Process.Kill(); err != nil {
return errors.Wrap(err, "failed to kill consul server")
}
}
// wait for the process to exit to be sure that the data dir can be
// deleted on all platforms.
return s.cmd.Wait()
} }
type failer struct { type failer struct {