tools/functional-tester/etcd-agent: add status rpc

This commit is contained in:
Xiang Li 2015-03-12 15:18:11 -07:00
parent f9ee8ecb3a
commit e46beb75c8
4 changed files with 118 additions and 7 deletions

View File

@ -21,9 +21,20 @@ import (
"os/exec"
"path"
"time"
"github.com/coreos/etcd/tools/functional-tester/etcd-agent/client"
)
const (
stateUninitialized = "uninitialized"
stateStarted = "started"
stateStopped = "stopped"
stateTerminated = "terminated"
)
type Agent struct {
state string // the state of etcd process
cmd *exec.Cmd
logfile *os.File
l net.Listener
@ -43,7 +54,7 @@ func newAgent(etcd string) (*Agent, error) {
return nil, err
}
return &Agent{cmd: c, logfile: f}, nil
return &Agent{state: stateUninitialized, cmd: c, logfile: f}, nil
}
// start starts a new etcd process with the given args.
@ -51,7 +62,13 @@ func (a *Agent) start(args ...string) error {
a.cmd = exec.Command(a.cmd.Path, args...)
a.cmd.Stdout = a.logfile
a.cmd.Stderr = a.logfile
return a.cmd.Start()
err := a.cmd.Start()
if err != nil {
return err
}
a.state = stateStarted
return nil
}
// stop stops the existing etcd process the agent started.
@ -61,7 +78,13 @@ func (a *Agent) stop() error {
return err
}
_, err = a.cmd.Process.Wait()
return err
if err != nil {
return err
}
a.state = stateStopped
return nil
}
// restart restarts the stopped etcd process.
@ -69,11 +92,22 @@ func (a *Agent) restart() error {
a.cmd = exec.Command(a.cmd.Path, a.cmd.Args[1:]...)
a.cmd.Stdout = a.logfile
a.cmd.Stderr = a.logfile
return a.cmd.Start()
err := a.cmd.Start()
if err != nil {
return err
}
a.state = stateStarted
return nil
}
func (a *Agent) cleanup() error {
a.stop()
err := a.stop()
if err != nil {
return err
}
a.state = stateUninitialized
a.logfile.Close()
if err := archiveLogAndDataDir("etcd.log", a.dataDir()); err != nil {
return err
@ -86,8 +120,20 @@ func (a *Agent) cleanup() error {
// terminate stops the exiting etcd process the agent started
// and removes the data dir.
func (a *Agent) terminate() error {
a.stop()
return os.RemoveAll(a.dataDir())
err := a.stop()
if err != nil {
return err
}
err = os.RemoveAll(a.dataDir())
if err != nil {
return err
}
a.state = stateTerminated
return nil
}
func (a *Agent) status() client.Status {
return client.Status{State: a.state}
}
func (a *Agent) dataDir() string {

View File

@ -16,6 +16,12 @@ package client
import "net/rpc"
type Status struct {
// TODO: gather more informations
// TODO: memory usage, raft information, etc..
State string
}
type Agent interface {
ID() uint64
// Start starts a new etcd with the given args on the agent machine.
@ -30,6 +36,8 @@ type Agent interface {
Terminate() error
// Isoloate isolates the network of etcd
Isolate() error
// Status returns the status of etcd on the agent
Status() (Status, error)
}
type agent struct {
@ -79,6 +87,15 @@ func (a *agent) Isolate() error {
panic("not implemented")
}
func (a *agent) Status() (Status, error) {
var s Status
err := a.rpcClient.Call("Agent.RPCStatus", struct{}{}, &s)
if err != nil {
return s, err
}
return s, nil
}
func (a *agent) ID() uint64 {
panic("not implemented")
}

View File

@ -19,6 +19,8 @@ import (
"net"
"net/http"
"net/rpc"
"github.com/coreos/etcd/tools/functional-tester/etcd-agent/client"
)
func (a *Agent) serveRPC() {
@ -69,3 +71,8 @@ func (a *Agent) RPCTerminate(args struct{}, reply *struct{}) error {
func (a *Agent) RPCIsolate(args struct{}, reply *struct{}) error {
panic("not implemented")
}
func (a *Agent) RPCStatus(args struct{}, status *client.Status) error {
*status = a.status()
return nil
}

View File

@ -20,6 +20,8 @@ import (
"net/rpc"
"os"
"testing"
"github.com/coreos/etcd/tools/functional-tester/etcd-agent/client"
)
func init() {
@ -123,3 +125,42 @@ func TestRPCTerminate(t *testing.T) {
t.Fatal(err)
}
}
func TestRPCStatus(t *testing.T) {
c, err := rpc.DialHTTP("tcp", ":9027")
if err != nil {
t.Fatal(err)
}
var s client.Status
err = c.Call("Agent.RPCStatus", struct{}{}, &s)
if err != nil {
t.Fatal(err)
}
if s.State != stateTerminated {
t.Errorf("state = %s, want %s", s.State, stateTerminated)
}
dir, err := ioutil.TempDir(os.TempDir(), "etcd-agent")
if err != nil {
t.Fatal(err)
}
var pid int
err = c.Call("Agent.RPCStart", []string{"-data-dir", dir}, &pid)
if err != nil {
t.Fatal(err)
}
err = c.Call("Agent.RPCStatus", struct{}{}, &s)
if err != nil {
t.Fatal(err)
}
if s.State != stateStarted {
t.Errorf("state = %s, want %s", s.State, stateStarted)
}
err = c.Call("Agent.RPCTerminate", struct{}{}, nil)
if err != nil {
t.Fatal(err)
}
}