test: split up integration_tests

...into "matrix" and "normal".

Also:
* Make running multiple packages in parallel safe, see
  http://stackoverflow.com/questions/23715302/go-how-to-run-tests-for-multiple-packages
* Don't depent on test_helper.TmpDir and friends to have a terminating slash
This commit is contained in:
Jakob Unterwurzacher 2016-06-30 00:57:14 +02:00
parent ffc000943b
commit 02b6d3067d
7 changed files with 131 additions and 137 deletions

View File

@ -8,4 +8,9 @@ source build.bash
go test ./... $*
# Clean up after ourself, but don't descend into maybe still mounted
# example filesystems
# The tests cannot to this themselves as they are run in parallel
rm -Rf --one-file-system /tmp/gocryptfs-test-parent
go tool vet -shadow=true .

View File

@ -15,20 +15,23 @@ import (
const statusTxtContent = "It works!\n"
var opensslOpt = "-openssl=false"
var opensslOpt string
func TestMain(m *testing.M) {
test_helpers.ResetTmpDir(true)
r := m.Run()
opensslOpt = "-openssl=true"
r2 := m.Run()
os.Exit(r + r2)
for _, opensslOpt = range []string{"-openssl=false", "-openssl=true"} {
test_helpers.ResetTmpDir(true)
r := m.Run()
if r != 0 {
os.Exit(r)
}
}
os.Exit(0)
}
// This filesystem is not supported anymore.
func TestExampleFSv04(t *testing.T) {
cDir := "v0.4"
pDir := test_helpers.TmpDir + cDir
pDir := test_helpers.TmpDir + "/" + cDir
err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt)
if err == nil {
t.Errorf("Mounting too old FS should fail")
@ -38,7 +41,7 @@ func TestExampleFSv04(t *testing.T) {
// This filesystem is not supported anymore.
func TestExampleFSv05(t *testing.T) {
cDir := "v0.5"
pDir := test_helpers.TmpDir + cDir
pDir := test_helpers.TmpDir + "/" + cDir
err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt)
if err == nil {
t.Errorf("Mounting too old FS should fail")
@ -48,7 +51,7 @@ func TestExampleFSv05(t *testing.T) {
// This filesystem is not supported anymore.
func TestExampleFSv06(t *testing.T) {
cDir := "v0.6"
pDir := test_helpers.TmpDir + cDir
pDir := test_helpers.TmpDir + "/" + cDir
err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt)
if err == nil {
t.Errorf("Mounting too old FS should fail")
@ -58,7 +61,7 @@ func TestExampleFSv06(t *testing.T) {
// This filesystem is not supported anymore.
func TestExampleFSv06PlaintextNames(t *testing.T) {
cDir := "v0.6-plaintextnames"
pDir := test_helpers.TmpDir + cDir
pDir := test_helpers.TmpDir + "/" + cDir
err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt)
if err == nil {
t.Errorf("Mounting too old FS should fail")
@ -69,8 +72,8 @@ func TestExampleFSv06PlaintextNames(t *testing.T) {
// with password mount and -masterkey mount
// v0.7 adds 128 bit GCM IVs
func TestExampleFSv07(t *testing.T) {
pDir := test_helpers.TmpDir + "TestExampleFsV07/"
cDir := "v0.7"
pDir := test_helpers.TmpDir + "/" + cDir
err := os.Mkdir(pDir, 0777)
if err != nil {
t.Fatal(err)
@ -83,38 +86,31 @@ func TestExampleFSv07(t *testing.T) {
opensslOpt)
checkExampleFS(t, pDir, true)
test_helpers.Unmount(pDir)
err = os.Remove(pDir)
if err != nil {
t.Error(err)
}
}
// gocryptfs v0.7 filesystem created with "-plaintextnames"
func TestExampleFSv07PlaintextNames(t *testing.T) {
cDir := "v0.7-plaintextnames"
pDir := test_helpers.TmpDir + cDir + ".mnt"
pDir := test_helpers.TmpDir + "/" + cDir + ".mnt"
test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt)
checkExampleFS(t, pDir, true)
test_helpers.Unmount(pDir)
// The actual unmount takes some time, this causes weird problems. Just don't
// reuse the mountpoint.
pDir = pDir + ".2"
test_helpers.MountOrFatal(t, cDir, pDir, "-plaintextnames", "-masterkey",
"6d96397b-585631e1-c7cba69d-61e738b6-4d5ad2c2-e21f0fb3-52f60d3a-b08526f7",
opensslOpt)
checkExampleFS(t, pDir, true)
test_helpers.Unmount(pDir)
err := os.Remove(pDir)
if err != nil {
t.Error(err)
}
}
// Test example_filesystems/v0.9
// (gocryptfs v0.9 introduced long file name support)
func TestExampleFSv09(t *testing.T) {
cDir := "v0.9"
pDir := test_helpers.TmpDir + "TestExampleFsV09/"
pDir := test_helpers.TmpDir + "/" + cDir
err := os.Mkdir(pDir, 0777)
if err != nil {
t.Fatal(err)
@ -122,13 +118,10 @@ func TestExampleFSv09(t *testing.T) {
test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt)
checkExampleFSLongnames(t, pDir)
test_helpers.Unmount(pDir)
pDir = pDir + ".2"
test_helpers.MountOrFatal(t, cDir, pDir, "-masterkey",
"1cafe3f4-bc316466-2214c47c-ecd89bf3-4e078fe4-f5faeea7-8b7cab02-884f5e1c",
opensslOpt)
checkExampleFSLongnames(t, pDir)
test_helpers.Unmount(pDir)
err = os.Remove(pDir)
if err != nil {
t.Error(err)
}
}

View File

@ -1,6 +1,14 @@
package integration_tests
package matrix
// File reading, writing, modification, truncate
//
// Runs everything four times, for all combinations of
// "-plaintextnames" and "-openssl".
//
// Test Matrix:
// openssl=true openssl=false
// plaintextnames=false X X
// plaintextnames=true X X
import (
"bytes"
@ -18,61 +26,38 @@ import (
"github.com/rfjakob/gocryptfs/tests/test_helpers"
)
var plaintextNames bool
// Several tests need to be aware if plaintextnames is active or not, so make this
// a global variable
var plaintextnames bool
// This is the entry point for the tests
func TestMain(m *testing.M) {
var defaultonly bool
flag.BoolVar(&defaultonly, "defaultonly", false, "Only test default configuration (openssl=true, plaintextnames=false)")
// Make "testing.Verbose()" return the correct value
flag.Parse()
for _, openssl := range []bool{true, false} {
for _, plaintextnames = range []bool{true, false} {
if testing.Verbose() {
fmt.Printf("Testing openssl=%v plaintextnames=%v\n", openssl, plaintextnames)
if testing.Verbose() {
fmt.Println("***** Testing with OpenSSL")
}
test_helpers.ResetTmpDir(plaintextnames)
opts := []string{"--zerokey"}
opts = append(opts, fmt.Sprintf("-openssl=%v", openssl))
opts = append(opts, fmt.Sprintf("-plaintextnames=%v", plaintextnames))
test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, opts...)
r := m.Run()
test_helpers.Unmount(test_helpers.DefaultPlainDir)
if r != 0 {
os.Exit(r)
}
}
}
test_helpers.ResetTmpDir(false) // <- this also create gocryptfs.diriv
test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "--zerokey")
r := m.Run()
test_helpers.Unmount(test_helpers.DefaultPlainDir)
if r != 0 {
os.Exit(r)
}
if defaultonly {
os.Exit(r)
}
if testing.Verbose() {
fmt.Println("***** Testing with native Go crypto")
}
test_helpers.ResetTmpDir(false)
test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "--zerokey", "--openssl=false")
r = m.Run()
test_helpers.Unmount(test_helpers.DefaultPlainDir)
if r != 0 {
os.Exit(r)
}
if testing.Verbose() {
fmt.Println("***** Testing \"--plaintextnames\"")
}
test_helpers.ResetTmpDir(true) // do not create gocryptfs.diriv
test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "--zerokey", "--plaintextnames")
plaintextNames = true
r = m.Run()
test_helpers.Unmount(test_helpers.DefaultPlainDir)
if r != 0 {
os.Exit(r)
}
os.Exit(r)
os.Exit(0)
}
// Write "n" zero bytes to filename "fn", read again, compare hash
func testWriteN(t *testing.T, fn string, n int) string {
file, err := os.Create(test_helpers.DefaultPlainDir + fn)
file, err := os.Create(test_helpers.DefaultPlainDir + "/" + fn)
if err != nil {
t.Fatal(err)
}
@ -87,12 +72,12 @@ func testWriteN(t *testing.T, fn string, n int) string {
t.Error(err)
}
test_helpers.VerifySize(t, test_helpers.DefaultPlainDir+fn, n)
test_helpers.VerifySize(t, test_helpers.DefaultPlainDir+"/"+fn, n)
bin := md5.Sum(d)
hashWant := hex.EncodeToString(bin[:])
hashActual := test_helpers.Md5fn(test_helpers.DefaultPlainDir + fn)
hashActual := test_helpers.Md5fn(test_helpers.DefaultPlainDir + "/" + fn)
if hashActual != hashWant {
t.Errorf("Wrong content, hashWant=%s hashActual=%s", hashWant, hashActual)
@ -113,14 +98,14 @@ func TestWrite1M(t *testing.T) {
testWriteN(t, "1M", 1024*1024)
}
func TestWrite1Mx100(t *testing.T) {
hashWant := testWriteN(t, "1Mx100", 1024*1024)
func TestWrite100x100(t *testing.T) {
hashWant := testWriteN(t, "100x100", 100)
// Read and check 100 times to catch race conditions
var i int
for i = 0; i < 100; i++ {
hashActual := test_helpers.Md5fn(test_helpers.DefaultPlainDir + "1M")
hashActual := test_helpers.Md5fn(test_helpers.DefaultPlainDir + "/100")
if hashActual != hashWant {
fmt.Printf("Read corruption in loop # %d\n", i)
fmt.Printf("Read corruption in loop #%d\n", i)
t.FailNow()
} else {
//fmt.Print(".")
@ -129,7 +114,7 @@ func TestWrite1Mx100(t *testing.T) {
}
func TestTruncate(t *testing.T) {
fn := test_helpers.DefaultPlainDir + "truncate"
fn := test_helpers.DefaultPlainDir + "/truncate"
file, err := os.Create(fn)
if err != nil {
t.FailNow()
@ -161,7 +146,7 @@ func TestTruncate(t *testing.T) {
}
func TestAppend(t *testing.T) {
fn := test_helpers.DefaultPlainDir + "append"
fn := test_helpers.DefaultPlainDir + "/append"
file, err := os.Create(fn)
if err != nil {
t.FailNow()
@ -195,7 +180,7 @@ func TestAppend(t *testing.T) {
// Create a file with holes by writing to offset 0 (block #0) and
// offset 4096 (block #1).
func TestFileHoles(t *testing.T) {
fn := test_helpers.DefaultPlainDir + "fileholes"
fn := test_helpers.DefaultPlainDir + "/fileholes"
file, err := os.Create(fn)
if err != nil {
t.Errorf("file create failed")
@ -223,7 +208,7 @@ func TestRmwRace(t *testing.T) {
runtime.GOMAXPROCS(10)
fn := test_helpers.DefaultPlainDir + "rmwrace"
fn := test_helpers.DefaultPlainDir + "/rmwrace"
f1, err := os.Create(fn)
if err != nil {
t.Fatalf("file create failed")
@ -286,42 +271,38 @@ func TestRmwRace(t *testing.T) {
}
*/
}
if testing.Verbose() {
fmt.Println(goodMd5)
}
}
// With "--plaintextnames", the name "/gocryptfs.conf" is reserved.
// Otherwise there should be no restrictions.
func TestFiltered(t *testing.T) {
filteredFile := test_helpers.DefaultPlainDir + "gocryptfs.conf"
filteredFile := test_helpers.DefaultPlainDir + "/gocryptfs.conf"
file, err := os.Create(filteredFile)
if plaintextNames == true && err == nil {
if plaintextnames == true && err == nil {
t.Errorf("should have failed but didn't")
} else if plaintextNames == false && err != nil {
} else if plaintextnames == false && err != nil {
t.Error(err)
}
file.Close()
err = os.Remove(filteredFile)
if plaintextNames == true && err == nil {
if plaintextnames == true && err == nil {
t.Errorf("should have failed but didn't")
} else if plaintextNames == false && err != nil {
} else if plaintextnames == false && err != nil {
t.Error(err)
}
}
func TestFilenameEncryption(t *testing.T) {
file, err := os.Create(test_helpers.DefaultPlainDir + "TestFilenameEncryption.txt")
file, err := os.Create(test_helpers.DefaultPlainDir + "/TestFilenameEncryption.txt")
file.Close()
if err != nil {
t.Fatal(err)
}
_, err = os.Stat(test_helpers.DefaultCipherDir + "TestFilenameEncryption.txt")
if plaintextNames == true && err != nil {
_, err = os.Stat(test_helpers.DefaultCipherDir + "/TestFilenameEncryption.txt")
if plaintextnames == true && err != nil {
t.Errorf("plaintextnames not working: %v", err)
} else if plaintextNames == false && err == nil {
} else if plaintextnames == false && err == nil {
t.Errorf("file name encryption not working")
}
}
@ -338,8 +319,8 @@ func testRename(t *testing.T) {
// Overwrite an empty directory with another directory
func TestDirOverwrite(t *testing.T) {
dir1 := test_helpers.DefaultPlainDir + "DirOverwrite1"
dir2 := test_helpers.DefaultPlainDir + "DirOverwrite2"
dir1 := test_helpers.DefaultPlainDir + "/DirOverwrite1"
dir2 := test_helpers.DefaultPlainDir + "/DirOverwrite2"
err := os.Mkdir(dir1, 0777)
if err != nil {
t.Fatal(err)
@ -360,7 +341,7 @@ func TestLongNames(t *testing.T) {
t.Fatal(err)
}
cnt1 := len(fi)
wd := test_helpers.DefaultPlainDir
wd := test_helpers.DefaultPlainDir + "/"
// Create file with long name
n255x := string(bytes.Repeat([]byte("x"), 255))
f, err := os.Create(wd + n255x)
@ -439,7 +420,7 @@ func TestLongNames(t *testing.T) {
}
func TestLchown(t *testing.T) {
name := test_helpers.DefaultPlainDir + "symlink"
name := test_helpers.DefaultPlainDir + "/symlink"
err := os.Symlink("/target/does/not/exist", name)
if err != nil {
t.Fatal(err)

View File

@ -1,4 +1,4 @@
package integration_tests
package normal
// Test CLI operations like "-init", "-password" etc
@ -13,6 +13,14 @@ import (
"github.com/rfjakob/gocryptfs/tests/test_helpers"
)
func TestMain(m *testing.M) {
test_helpers.ResetTmpDir(false)
test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "--zerokey")
r := m.Run()
test_helpers.Unmount(test_helpers.DefaultPlainDir)
os.Exit(r)
}
// Test -init flag
func TestInit(t *testing.T) {
dir := test_helpers.InitFS(t)
@ -59,7 +67,7 @@ func TestPasswd(t *testing.T) {
// Test -init & -config flag
func TestInitConfig(t *testing.T) {
config := test_helpers.TmpDir + "TestInitConfig.conf"
config := test_helpers.TmpDir + "/TestInitConfig.conf"
dir := test_helpers.InitFS(t, "-config="+config)
_, err := os.Stat(config)

View File

@ -1,4 +1,4 @@
package integration_tests
package normal
// Benchmarks

View File

@ -20,7 +20,9 @@ func TestMain(m *testing.M) {
cDir = test_helpers.InitFS(nil, "-plaintextnames")
pDir = cDir + ".mnt"
test_helpers.MountOrExit(cDir, pDir, "-extpass", "echo test")
os.Exit(m.Run())
r := m.Run()
test_helpers.Unmount(pDir)
os.Exit(r)
}
// Only the PlaintextNames feature flag should be set

View File

@ -10,17 +10,31 @@ import (
"path/filepath"
"syscall"
"testing"
"time"
"github.com/rfjakob/gocryptfs/internal/nametransform"
)
// Note: the code assumes that all have a trailing slash
const TmpDir = "/tmp/gocryptfs_main_test/"
const DefaultPlainDir = TmpDir + "plain/"
const DefaultCipherDir = TmpDir + "cipher/"
const testParentDir = "/tmp/gocryptfs-test-parent"
const GocryptfsBinary = "../../gocryptfs"
// "go test" runs package tests in parallel! We must create a unique TmpDir on
// startup or the tests will interfere horribly
var TmpDir string
var DefaultPlainDir string
var DefaultCipherDir string
func init() {
os.MkdirAll(testParentDir, 0700)
var err error
TmpDir, err = ioutil.TempDir(testParentDir, "")
if err != nil {
panic(err)
}
DefaultPlainDir = TmpDir + "/default-plain"
DefaultCipherDir = TmpDir + "/default-cipher"
}
// ResetTmpDir - delete TmpDir, create new dir tree:
//
// TmpDir
@ -28,38 +42,31 @@ const GocryptfsBinary = "../../gocryptfs"
// *-- DefaultCipherDir
// *-- gocryptfs.diriv
func ResetTmpDir(plaintextNames bool) {
// Try to unmount everything
// Try to unmount and delete everything
entries, err := ioutil.ReadDir(TmpDir)
if err == nil {
for _, e := range entries {
fu := exec.Command("fusermount", "-z", "-u", filepath.Join(TmpDir, e.Name()))
fu.Run()
d := filepath.Join(TmpDir, e.Name())
err = os.Remove(d)
if err != nil {
fu := exec.Command("fusermount", "-z", "-u", d)
fu.Run()
os.RemoveAll(d)
}
}
}
err = os.RemoveAll(TmpDir)
err = os.Mkdir(DefaultPlainDir, 0700)
if err != nil {
fmt.Println("resetTmpDir: RemoveAll:" + err.Error())
os.Exit(1)
panic(err)
}
err = os.MkdirAll(DefaultPlainDir, 0777)
err = os.Mkdir(DefaultCipherDir, 0700)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = os.MkdirAll(DefaultCipherDir, 0777)
if err != nil {
fmt.Println(err)
os.Exit(1)
panic(err)
}
if !plaintextNames {
err = nametransform.WriteDirIV(DefaultCipherDir)
if err != nil {
fmt.Println(err)
os.Exit(1)
panic(err)
}
}
}
@ -73,7 +80,6 @@ func InitFS(t *testing.T, extraArgs ...string) string {
if err != nil {
t.Fatal(err)
}
args := []string{"-q", "-init", "-extpass", "echo test", "-scryptn=10"}
args = append(args, extraArgs...)
args = append(args, dir)
@ -95,7 +101,7 @@ func InitFS(t *testing.T, extraArgs ...string) string {
func Mount(c string, p string, showOutput bool, extraArgs ...string) error {
var args []string
args = append(args, extraArgs...)
args = append(args, "-nosyslog", "-q", "-wpanic")
args = append(args, "-q", "-wpanic")
//args = append(args, "-fusedebug")
//args = append(args, "-d")
args = append(args, c)
@ -142,7 +148,9 @@ func Unmount(p string) error {
err := fu.Run()
if err != nil {
fmt.Println(err)
panic(err)
}
time.Sleep(10 * time.Millisecond)
return err
}
@ -184,7 +192,7 @@ func VerifySize(t *testing.T, path string, want int) {
// Create and delete a directory
func TestMkdirRmdir(t *testing.T, plainDir string) {
dir := plainDir + "dir1"
dir := plainDir + "/dir1"
err := os.Mkdir(dir, 0777)
if err != nil {
t.Fatal(err)
@ -231,8 +239,8 @@ func TestMkdirRmdir(t *testing.T, plainDir string) {
// Create and rename a file
func TestRename(t *testing.T, plainDir string) {
file1 := plainDir + "rename1"
file2 := plainDir + "rename2"
file1 := plainDir + "/rename1"
file2 := plainDir + "/rename2"
err := ioutil.WriteFile(file1, []byte("content"), 0777)
if err != nil {
t.Fatal(err)
@ -247,14 +255,12 @@ func TestRename(t *testing.T, plainDir string) {
// verifyExistence - check in 3 ways that "path" exists:
// stat, open, readdir
func VerifyExistence(path string) bool {
// Check that file can be stated
_, err := os.Stat(path)
if err != nil {
//t.Log(err)
return false
}
// Check that file can be opened
fd, err := os.Open(path)
if err != nil {
@ -262,7 +268,6 @@ func VerifyExistence(path string) bool {
return false
}
fd.Close()
// Check that file shows up in directory listing
dir := filepath.Dir(path)
name := filepath.Base(path)