blob: bd35c652353441865c424a1e9e755ee187adfeb8 [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 testutil
import (
"bytes"
"io/ioutil"
"log"
"os"
"runtime/debug"
"syscall"
"time"
"v.io/x/ref/test/modules"
"v.io/x/ref/test/v23tests"
)
// StartSyncbased starts a syncbased process, intended to be accessed from an
// integration test (run using --v23.tests). The returned cleanup function
// should be called once the syncbased process is no longer needed. See
// StartKillableSyncbased for killing the syncbase with an arbitrary signal.
func StartSyncbased(t *v23tests.T, creds *modules.CustomCredentials, name, rootDir, permsLiteral string) (cleanup func()) {
f := StartKillableSyncbased(t, creds, name, rootDir, permsLiteral)
return func() {
f(syscall.SIGINT)
}
}
// StartKillableSyncbased starts a syncbased process, intended to be accessed
// from an integration test (run using --v23.tests). The returned cleanup
// function should be called once the syncbased process is no longer needed.
func StartKillableSyncbased(t *v23tests.T, creds *modules.CustomCredentials,
name, rootDir, permsLiteral string) (cleanup func(signal syscall.Signal)) {
syncbased := t.BuildV23Pkg("v.io/x/ref/services/syncbase/syncbased")
// Create root dir for the store.
rmRootDir := false
if rootDir == "" {
var err error
rootDir, err = ioutil.TempDir("", "syncbase_leveldb")
if err != nil {
V23Fatalf(t, "can't create temp dir: %v", err)
}
rmRootDir = true
}
// Start syncbased. Run with --dev to enable development mode methods such as
// DevModeUpdateVClock.
invocation := syncbased.WithStartOpts(syncbased.StartOpts().WithCustomCredentials(creds).WithSessions(t, 5*time.Second)).Start(
//"--v=5",
//"--vpath=vsync*=5",
//"--alsologtostderr=true",
"--v23.tcp.address=127.0.0.1:0",
"--v23.permissions.literal", permsLiteral,
"--name="+name,
"--root-dir="+rootDir,
"--dev")
cleanup = func(signal syscall.Signal) {
go invocation.Kill(signal)
stdout, stderr := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
if err := invocation.Shutdown(stdout, stderr); err != nil {
log.Printf("syncbased terminated with an error: %v\nstdout: %v\nstderr: %v\n", err, stdout, stderr)
} else {
// To debug sync (for example), uncomment this line as well as the logging
// flags in the invocation above.
//log.Printf("syncbased terminated cleanly\nstdout: %v\nstderr: %v\n", stdout, stderr)
}
if rmRootDir {
if err := os.RemoveAll(rootDir); err != nil {
V23Fatalf(t, "failed to remove dir %v: %v", rootDir, err)
}
}
}
// Wait for syncbased to start. If syncbased fails to start, this will time
// out after 5 seconds and return "".
endpoint := invocation.ExpectVar("ENDPOINT")
if endpoint == "" {
cleanup(syscall.SIGKILL)
t.Fatalf("syncbased failed to start")
}
return cleanup
}
// RunClient runs the given program and waits for it to terminate.
// TODO(sadovsky): This function will soon go away. Do not depend on it.
func RunClient(t *v23tests.T, creds *modules.CustomCredentials, program modules.Program, args ...string) {
client, err := t.Shell().StartWithOpts(
t.Shell().DefaultStartOpts().WithCustomCredentials(creds),
nil,
program, args...)
if err != nil {
V23Fatalf(t, "unable to start the client: %v", err)
}
stdout, stderr := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
if err := client.Shutdown(stdout, stderr); err != nil {
V23Fatalf(t, "client failed: %v\nstdout: %v\nstderr: %v\n", err, stdout, stderr)
}
}
func V23Fatalf(t *v23tests.T, format string, args ...interface{}) {
debug.PrintStack()
t.Fatalf(format, args...)
}