Synchronize on ready with a pipe.
parent
49455cd59c
commit
6729af8524
|
@ -17,6 +17,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
@ -30,6 +31,7 @@ import (
|
||||||
|
|
||||||
var fType = flag.String("type", "", "The name of the samples/ sub-dir.")
|
var fType = flag.String("type", "", "The name of the samples/ sub-dir.")
|
||||||
var fMountPoint = flag.String("mount_point", "", "Path to mount point.")
|
var fMountPoint = flag.String("mount_point", "", "Path to mount point.")
|
||||||
|
var fReadyFile = flag.Uint64("ready_file", 0, "FD to signal when ready.")
|
||||||
|
|
||||||
var fFlushesFile = flag.Uint64("flushfs.flushes_file", 0, "")
|
var fFlushesFile = flag.Uint64("flushfs.flushes_file", 0, "")
|
||||||
var fFsyncsFile = flag.Uint64("flushfs.fsyncs_file", 0, "")
|
var fFsyncsFile = flag.Uint64("flushfs.fsyncs_file", 0, "")
|
||||||
|
@ -97,9 +99,25 @@ func makeFS() (fs fuse.FileSystem, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getReadyFile() (f *os.File, err error) {
|
||||||
|
if *fReadyFile == 0 {
|
||||||
|
err = errors.New("You must set --ready_file.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f = os.NewFile(uintptr(*fReadyFile), "(ready file)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
// Grab the file to signal when ready.
|
||||||
|
readyFile, err := getReadyFile()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("getReadyFile:", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Create an appropriate file system.
|
// Create an appropriate file system.
|
||||||
fs, err := makeFS()
|
fs, err := makeFS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -121,6 +139,12 @@ func main() {
|
||||||
log.Fatalf("WaitForReady: %v", err)
|
log.Fatalf("WaitForReady: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signal that it is ready.
|
||||||
|
_, err = readyFile.Write([]byte("x"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("readyFile.Write: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for it to be unmounted.
|
// Wait for it to be unmounted.
|
||||||
if err = mfs.Join(context.Background()); err != nil {
|
if err = mfs.Join(context.Background()); err != nil {
|
||||||
log.Fatalf("Join: %v", err)
|
log.Fatalf("Join: %v", err)
|
||||||
|
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/jacobsa/ogletest"
|
"github.com/jacobsa/ogletest"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
@ -145,6 +144,16 @@ func waitForMountSample(
|
||||||
err = fmt.Errorf("Waiting for mount_sample: %v", err)
|
err = fmt.Errorf("Waiting for mount_sample: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func waitForReady(readyReader *os.File, c chan<- struct{}) {
|
||||||
|
_, err := readyReader.Read(make([]byte, 1))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Readying from ready pipe: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c <- struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
// Like SetUp, but doens't panic.
|
// Like SetUp, but doens't panic.
|
||||||
func (t *SubprocessTest) initialize() (err error) {
|
func (t *SubprocessTest) initialize() (err error) {
|
||||||
// Initialize the context.
|
// Initialize the context.
|
||||||
|
@ -174,6 +183,18 @@ func (t *SubprocessTest) initialize() (err error) {
|
||||||
|
|
||||||
args = append(args, t.MountFlags...)
|
args = append(args, t.MountFlags...)
|
||||||
|
|
||||||
|
// Set up a pipe for the "ready" status.
|
||||||
|
readyReader, readyWriter, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("Pipe: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer readyReader.Close()
|
||||||
|
defer readyWriter.Close()
|
||||||
|
|
||||||
|
t.MountFiles["ready_file"] = readyWriter
|
||||||
|
|
||||||
// Set up inherited files and appropriate flags.
|
// Set up inherited files and appropriate flags.
|
||||||
var extraFiles []*os.File
|
var extraFiles []*os.File
|
||||||
for flag, file := range t.MountFiles {
|
for flag, file := range t.MountFiles {
|
||||||
|
@ -199,12 +220,21 @@ func (t *SubprocessTest) initialize() (err error) {
|
||||||
|
|
||||||
// Launch a goroutine that waits for it and returns its status.
|
// Launch a goroutine that waits for it and returns its status.
|
||||||
mountSampleErr := make(chan error, 1)
|
mountSampleErr := make(chan error, 1)
|
||||||
t.mountSampleErr = mountSampleErr
|
|
||||||
go waitForMountSample(mountCmd, mountSampleErr, &stderr)
|
go waitForMountSample(mountCmd, mountSampleErr, &stderr)
|
||||||
|
|
||||||
// TODO(jacobsa): Probably need some sort of signalling (on stderr? write to
|
// Wait for the tool to say the file system is ready. In parallel, watch for
|
||||||
// a flag-controlled file?) when WaitForReady has returned.
|
// the tool to fail.
|
||||||
time.Sleep(time.Second)
|
readyChan := make(chan struct{}, 1)
|
||||||
|
go waitForReady(readyReader, readyChan)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-readyChan:
|
||||||
|
case err = <-mountSampleErr:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TearDown is no responsible for joining.
|
||||||
|
t.mountSampleErr = mountSampleErr
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue