blob: 6dc099ba55ac0f9de8748dedb97d199d77f5f628 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package lockutil_test contains tests for the lockutil package.
package lockutil_test
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"v.io/x/lib/gosh"
"v.io/x/ref/services/agent/internal/lockutil"
)
// TestCreateLockFile ensures that CreateLockFile writes the file it's supposed
// to.
func TestCreateLockFile(t *testing.T) {
d, err := ioutil.TempDir("", "lockutiltest")
if err != nil {
t.Fatalf("TempDir failed: %v", err)
}
defer os.RemoveAll(d)
f, err := lockutil.CreateLockFile(d, "foo")
if err != nil {
t.Fatalf("createPIDFile failed: %v", err)
}
files, err := ioutil.ReadDir(d)
if err != nil {
t.Fatalf("ReadDir failed: %v", err)
}
if nfiles := len(files); nfiles != 1 {
t.Fatalf("Expected 1 file, found %d", nfiles)
}
if found, want := files[0].Name(), filepath.Base(f); found != want {
t.Fatalf("Expected file %s, found %s instead", want, found)
}
}
var goshCreateLockFile = gosh.RegisterFunc("CreateLockFile", func(dir string) error {
f, err := lockutil.CreateLockFile(dir, "foo")
if err != nil {
return err
}
fmt.Println(f)
return nil
})
// TestStillHeld verifies StillHeld returns the appropriate boolean when
// presented with either a running or a dead process' information.
func TestStillHeld(t *testing.T) {
d, err := ioutil.TempDir("", "lockutiltest")
if err != nil {
t.Fatalf("TempDir failed: %v", err)
}
defer os.RemoveAll(d)
f, err := lockutil.CreateLockFile(d, "foo")
if err != nil {
t.Fatalf("createPIDFile failed: %v", err)
}
if info, err := ioutil.ReadFile(f); err != nil {
t.Fatalf("ReadFile(%v) failed: %v", f, err)
} else if running, err := lockutil.StillHeld(info); err != nil || !running {
t.Fatalf("Expected (true, <nil>) got (%t, %v) instead from StillHeld for:\n%v", running, err, string(info))
}
sh := gosh.NewShell(t)
defer sh.Cleanup()
if out := sh.FuncCmd(goshCreateLockFile, d).Stdout(); filepath.Dir(out) != d {
t.Fatalf("Unexpected output: %s", out)
} else {
f = strings.TrimSuffix(out, "\n")
}
if info, err := ioutil.ReadFile(f); err != nil {
t.Fatalf("ReadFile(%v) failed: %v", f, err)
} else if running, err := lockutil.StillHeld(info); err != nil || running {
t.Fatalf("Expected (false, <nil>) got (%t, %v) instead from StillHeld for:\n%v", running, err, string(info))
}
}
// TestStillHeldManual verifies the behavior of StillHeld using some manually
// generated lock file contents.
func TestStillHeldManual(t *testing.T) {
sysID, err := lockutil.GetSystemID()
if err != nil {
t.Fatalf("Failed to get system ID: %v", err)
}
for i, c := range []struct {
info string
held bool
}{
{
"VERSION:1\nSYSTEM ID:UNKNOWN\n",
true,
},
{
"VERSION:1\nSYSTEM ID:" + sysID + "\nPID:123456\n",
false,
},
{
"VERSION:1\nSYSTEM ID:" + sysID + "\nPID:" + strconv.Itoa(os.Getpid()) + "\n",
true,
},
{
"VERSION:1\nSYSTEM ID:" + sysID + "\nPID:" + strconv.Itoa(os.Getpid()) + "\nBLAH\n",
false,
},
} {
if held, err := lockutil.StillHeld([]byte(c.info)); err != nil {
t.Fatalf("case %d: unexpected error: %v", i, err)
} else if held != c.held {
t.Fatalf("case %d: expected %t, got %t instead", i, c.held, held)
}
}
}
// TestInvalidVersion ensures StillHeld fails when presented with invalid
// versions or incorrectly formatted lock files.
func TestInvalidVersion(t *testing.T) {
sysID, err := lockutil.GetSystemID()
if err != nil {
t.Fatalf("Failed to get system ID: %v", err)
}
for i, c := range []struct {
info, error string
}{
{
"VERSION:1000000\nBLAH\n",
"unknown version: 1000000",
},
{
"VERSION:1\nBLAH\n",
"couldn't parse SYSTEM ID",
},
{
"VERSION:1\nSYSTEM ID:" + sysID + "\nBLAH\n",
"couldn't parse PID",
},
{
"VERSION:1\nSYSTEM ID:" + sysID + "\nPID:abc\n",
"couldn't parse PID",
},
} {
if _, err := lockutil.StillHeld([]byte(c.info)); err == nil {
t.Fatalf("case %d: expected to fail", i)
} else if !strings.Contains(err.Error(), c.error) {
t.Fatalf("case %d: expected error \"...%s...\", got \"%s\" instead", i, c.error, err.Error())
}
}
}
func TestMain(m *testing.M) {
gosh.InitMain()
os.Exit(m.Run())
}