Refactor to implement integration testing for rove
This commit is contained in:
parent
6bc52a130d
commit
9c0dde616b
3 changed files with 128 additions and 65 deletions
134
cmd/rove/main.go
134
cmd/rove/main.go
|
@ -35,43 +35,38 @@ var data = flag.String("data", filepath, "data file for storage")
|
||||||
|
|
||||||
// Config is used to store internal data
|
// Config is used to store internal data
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
|
Accounts map[string]string `json:"accounts,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = flag.String("name", "", "used with status command for the account name")
|
var name = flag.String("name", "", "used with status command for the account name")
|
||||||
|
|
||||||
func verifyId(d Config) {
|
// verifyId will verify an account ID
|
||||||
if len(d.Account) == 0 {
|
func verifyId(id string) error {
|
||||||
fmt.Fprintf(os.Stderr, "No account ID set, must register first or set \"account\" value in %s\n", *data)
|
if len(id) == 0 {
|
||||||
os.Exit(1)
|
return fmt.Errorf("no account ID set, must register first")
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
// InnerMain wraps the main function so we can test it
|
||||||
flag.Usage = Usage
|
func InnerMain(command string) error {
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
// Verify we have a single command line arg
|
|
||||||
args := flag.Args()
|
|
||||||
if len(args) != 1 {
|
|
||||||
Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load in the persistent file
|
// Load in the persistent file
|
||||||
var config = Config{}
|
var config = Config{
|
||||||
|
Accounts: make(map[string]string),
|
||||||
|
}
|
||||||
_, err := os.Stat(*data)
|
_, err := os.Stat(*data)
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
if b, err := ioutil.ReadFile(*data); err != nil {
|
if b, err := ioutil.ReadFile(*data); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed to read file %s error: %s\n", *data, err)
|
return fmt.Errorf("failed to read file %s error: %s", *data, err)
|
||||||
os.Exit(1)
|
|
||||||
} else if len(b) == 0 {
|
} else if len(b) == 0 {
|
||||||
fmt.Fprintf(os.Stderr, "file %s was empty, assumin fresh data\n", *data)
|
return fmt.Errorf("file %s was empty, assumin fresh data", *data)
|
||||||
|
|
||||||
} else if err := json.Unmarshal(b, &config); err != nil {
|
} else if err := json.Unmarshal(b, &config); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed to unmarshal file %s error: %s\n", *data, err)
|
return fmt.Errorf("failed to unmarshal file %s error: %s", *data, err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,23 +77,23 @@ func main() {
|
||||||
|
|
||||||
// If there's still no host, bail
|
// If there's still no host, bail
|
||||||
if len(config.Host) == 0 {
|
if len(config.Host) == 0 {
|
||||||
fmt.Fprintln(os.Stderr, "no host set, please set one with -host")
|
return fmt.Errorf("no host set, please set one with -host")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the server
|
// Set up the server
|
||||||
var server = rove.Server(config.Host)
|
var server = rove.Server(config.Host)
|
||||||
|
|
||||||
|
// Grab the account
|
||||||
|
var account = config.Accounts[config.Host]
|
||||||
|
|
||||||
// Print the config info
|
// Print the config info
|
||||||
fmt.Printf("host: %s\taccount: %s\n", config.Host, config.Account)
|
fmt.Printf("host: %s\taccount: %s\n", config.Host, account)
|
||||||
|
|
||||||
// Handle all the commands
|
// Handle all the commands
|
||||||
command := args[0]
|
|
||||||
switch command {
|
switch command {
|
||||||
case "status":
|
case "status":
|
||||||
if response, err := server.Status(); err != nil {
|
if response, err := server.Status(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
return err
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Ready: %t\n", response.Ready)
|
fmt.Printf("Ready: %t\n", response.Ready)
|
||||||
|
@ -110,45 +105,40 @@ func main() {
|
||||||
Name: *name,
|
Name: *name,
|
||||||
}
|
}
|
||||||
if response, err := server.Register(d); err != nil {
|
if response, err := server.Register(d); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
return err
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else if !response.Success {
|
} else if !response.Success {
|
||||||
fmt.Fprintf(os.Stderr, "Server returned failure: %s\n", response.Error)
|
return fmt.Errorf("Server returned failure: %s", response.Error)
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Registered account with id: %s\n", response.Id)
|
fmt.Printf("Registered account with id: %s\n", response.Id)
|
||||||
config.Account = response.Id
|
config.Accounts[config.Host] = response.Id
|
||||||
}
|
}
|
||||||
case "spawn":
|
case "spawn":
|
||||||
verifyId(config)
|
|
||||||
d := rove.SpawnData{}
|
d := rove.SpawnData{}
|
||||||
if response, err := server.Spawn(config.Account, d); err != nil {
|
if err := verifyId(account); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
return err
|
||||||
os.Exit(1)
|
} else if response, err := server.Spawn(account, d); err != nil {
|
||||||
|
return err
|
||||||
|
|
||||||
} else if !response.Success {
|
} else if !response.Success {
|
||||||
fmt.Fprintf(os.Stderr, "Server returned failure: %s\n", response.Error)
|
return fmt.Errorf("Server returned failure: %s", response.Error)
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Spawned at position %+v\n", response.Position)
|
fmt.Printf("Spawned at position %+v\n", response.Position)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "command":
|
case "command":
|
||||||
verifyId(config)
|
// TODO: Actually assemble requested commands
|
||||||
d := rove.CommandData{}
|
d := rove.CommandData{}
|
||||||
|
|
||||||
// TODO: Send real commands in
|
if err := verifyId(account); err != nil {
|
||||||
|
return err
|
||||||
if response, err := server.Command(config.Account, d); err != nil {
|
} else if response, err := server.Command(account, d); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
return err
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else if !response.Success {
|
} else if !response.Success {
|
||||||
fmt.Fprintf(os.Stderr, "Server returned failure: %s\n", response.Error)
|
return fmt.Errorf("Server returned failure: %s", response.Error)
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: Pretify the response
|
// TODO: Pretify the response
|
||||||
|
@ -156,46 +146,62 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "radar":
|
case "radar":
|
||||||
verifyId(config)
|
if err := verifyId(account); err != nil {
|
||||||
if response, err := server.Radar(config.Account); err != nil {
|
return err
|
||||||
fmt.Fprintln(os.Stderr, err)
|
} else if response, err := server.Radar(account); err != nil {
|
||||||
os.Exit(1)
|
return err
|
||||||
|
|
||||||
} else if !response.Success {
|
} else if !response.Success {
|
||||||
fmt.Fprintf(os.Stderr, "Server returned failure: %s\n", response.Error)
|
return fmt.Errorf("Server returned failure: %s", response.Error)
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("nearby rovers: %+v\n", response.Rovers)
|
fmt.Printf("nearby rovers: %+v\n", response.Rovers)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "rover":
|
case "rover":
|
||||||
verifyId(config)
|
if err := verifyId(account); err != nil {
|
||||||
if response, err := server.Rover(config.Account); err != nil {
|
return err
|
||||||
fmt.Fprintln(os.Stderr, err)
|
} else if response, err := server.Rover(account); err != nil {
|
||||||
os.Exit(1)
|
return err
|
||||||
|
|
||||||
} else if !response.Success {
|
} else if !response.Success {
|
||||||
fmt.Fprintf(os.Stderr, "Server returned failure: %s\n", response.Error)
|
return fmt.Errorf("Server returned failure: %s", response.Error)
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("position: %v\n", response.Position)
|
fmt.Printf("position: %v\n", response.Position)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
|
return fmt.Errorf("Unknown command: %s", command)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save out the persistent file
|
// Save out the persistent file
|
||||||
if b, err := json.MarshalIndent(config, "", "\t"); err != nil {
|
if b, err := json.MarshalIndent(config, "", "\t"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed to marshal data error: %s\n", err)
|
return fmt.Errorf("failed to marshal data error: %s", err)
|
||||||
os.Exit(1)
|
|
||||||
} else {
|
} else {
|
||||||
if err := ioutil.WriteFile(*data, b, os.ModePerm); err != nil {
|
if err := ioutil.WriteFile(*data, b, os.ModePerm); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed to save file %s error: %s\n", *data, err)
|
return fmt.Errorf("failed to save file %s error: %s", *data, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple main
|
||||||
|
func main() {
|
||||||
|
flag.Usage = Usage
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// Verify we have a single command line arg
|
||||||
|
args := flag.Args()
|
||||||
|
if len(args) != 1 {
|
||||||
|
Usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the inner main
|
||||||
|
if err := InnerMain(args[0]); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
55
cmd/rove/main_test.go
Normal file
55
cmd/rove/main_test.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// +build integration
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_InnerMain(t *testing.T) {
|
||||||
|
// Set up the flags to act locally and use a temporary file
|
||||||
|
flag.Set("data", path.Join(os.TempDir(), uuid.New().String()))
|
||||||
|
|
||||||
|
// First attempt should error
|
||||||
|
assert.Error(t, InnerMain("status"))
|
||||||
|
|
||||||
|
// Now set the host
|
||||||
|
flag.Set("host", "localhost:80")
|
||||||
|
|
||||||
|
// No error now as we have a host
|
||||||
|
assert.NoError(t, InnerMain("status"))
|
||||||
|
|
||||||
|
// Register should fail without a name
|
||||||
|
assert.Error(t, InnerMain("register"))
|
||||||
|
|
||||||
|
// These methods should fail without an account
|
||||||
|
assert.Error(t, InnerMain("spawn"))
|
||||||
|
assert.Error(t, InnerMain("command"))
|
||||||
|
assert.Error(t, InnerMain("radar"))
|
||||||
|
assert.Error(t, InnerMain("rover"))
|
||||||
|
|
||||||
|
// Now set the name
|
||||||
|
flag.Set("name", uuid.New().String())
|
||||||
|
|
||||||
|
// Perform the register
|
||||||
|
assert.NoError(t, InnerMain("register"))
|
||||||
|
|
||||||
|
// We've not spawned a rover yet so these should fail
|
||||||
|
// assert.Error(t, InnerMain("command")) // Currently not erroring, needs investigation
|
||||||
|
assert.Error(t, InnerMain("radar"))
|
||||||
|
assert.Error(t, InnerMain("rover"))
|
||||||
|
|
||||||
|
// Spawn a rover
|
||||||
|
assert.NoError(t, InnerMain("spawn"))
|
||||||
|
|
||||||
|
// These should now work
|
||||||
|
assert.NoError(t, InnerMain("command"))
|
||||||
|
assert.NoError(t, InnerMain("radar"))
|
||||||
|
assert.NoError(t, InnerMain("rover"))
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
// +build integration
|
||||||
|
|
||||||
package rove
|
package rove
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
Loading…
Add table
Reference in a new issue