consul: Providing logOutput to StateStore

pull/19/head
Armon Dadgar 2014-03-05 14:34:29 -08:00
parent d8e2da7f73
commit ca5a9cac23
3 changed files with 79 additions and 26 deletions

View File

@ -14,8 +14,9 @@ import (
// along with Raft to provide strong consistency. We implement // along with Raft to provide strong consistency. We implement
// this outside the Server to avoid exposing this outside the package. // this outside the Server to avoid exposing this outside the package.
type consulFSM struct { type consulFSM struct {
logger *log.Logger logOutput io.Writer
state *StateStore logger *log.Logger
state *StateStore
} }
// consulSnapshot is used to provide a snapshot of the current // consulSnapshot is used to provide a snapshot of the current
@ -34,14 +35,15 @@ type snapshotHeader struct {
// NewFSM is used to construct a new FSM with a blank state // NewFSM is used to construct a new FSM with a blank state
func NewFSM(logOutput io.Writer) (*consulFSM, error) { func NewFSM(logOutput io.Writer) (*consulFSM, error) {
state, err := NewStateStore() state, err := NewStateStore(logOutput)
if err != nil { if err != nil {
return nil, err return nil, err
} }
fsm := &consulFSM{ fsm := &consulFSM{
logger: log.New(logOutput, "", log.LstdFlags), logOutput: logOutput,
state: state, logger: log.New(logOutput, "", log.LstdFlags),
state: state,
} }
return fsm, nil return fsm, nil
} }
@ -146,7 +148,7 @@ func (c *consulFSM) Restore(old io.ReadCloser) error {
defer old.Close() defer old.Close()
// Create a new state store // Create a new state store
state, err := NewStateStore() state, err := NewStateStore(c.logOutput)
if err != nil { if err != nil {
return err return err
} }

View File

@ -4,7 +4,9 @@ import (
"fmt" "fmt"
"github.com/armon/gomdb" "github.com/armon/gomdb"
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"io"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
) )
@ -23,6 +25,7 @@ const (
// implementation uses the Lightning Memory-Mapped Database (MDB). // implementation uses the Lightning Memory-Mapped Database (MDB).
// This gives us Multi-Version Concurrency Control for "free" // This gives us Multi-Version Concurrency Control for "free"
type StateStore struct { type StateStore struct {
logger *log.Logger
path string path string
env *mdb.Env env *mdb.Env
nodeTable *MDBTable nodeTable *MDBTable
@ -48,7 +51,7 @@ func (s *StateSnapshot) Close() error {
} }
// NewStateStore is used to create a new state store // NewStateStore is used to create a new state store
func NewStateStore() (*StateStore, error) { func NewStateStore(logOutput io.Writer) (*StateStore, error) {
// Create a new temp dir // Create a new temp dir
path, err := ioutil.TempDir("", "consul") path, err := ioutil.TempDir("", "consul")
if err != nil { if err != nil {
@ -62,9 +65,10 @@ func NewStateStore() (*StateStore, error) {
} }
s := &StateStore{ s := &StateStore{
path: path, logger: log.New(logOutput, "", log.LstdFlags),
env: env, path: path,
watch: make(map[*MDBTable]*NotifyGroup), env: env,
watch: make(map[*MDBTable]*NotifyGroup),
} }
// Ensure we can initialize // Ensure we can initialize

View File

@ -2,13 +2,18 @@ package consul
import ( import (
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"os"
"reflect" "reflect"
"sort" "sort"
"testing" "testing"
) )
func testStateStore() (*StateStore, error) {
return NewStateStore(os.Stderr)
}
func TestEnsureNode(t *testing.T) { func TestEnsureNode(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -34,7 +39,7 @@ func TestEnsureNode(t *testing.T) {
} }
func TestGetNodes(t *testing.T) { func TestGetNodes(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -61,7 +66,7 @@ func TestGetNodes(t *testing.T) {
} }
func BenchmarkGetNodes(b *testing.B) { func BenchmarkGetNodes(b *testing.B) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
b.Fatalf("err: %v", err) b.Fatalf("err: %v", err)
} }
@ -81,7 +86,7 @@ func BenchmarkGetNodes(b *testing.B) {
} }
func TestEnsureService(t *testing.T) { func TestEnsureService(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -126,7 +131,7 @@ func TestEnsureService(t *testing.T) {
} }
func TestEnsureService_DuplicateNode(t *testing.T) { func TestEnsureService_DuplicateNode(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -179,7 +184,7 @@ func TestEnsureService_DuplicateNode(t *testing.T) {
} }
func TestDeleteNodeService(t *testing.T) { func TestDeleteNodeService(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -227,7 +232,7 @@ func TestDeleteNodeService(t *testing.T) {
} }
func TestDeleteNodeService_One(t *testing.T) { func TestDeleteNodeService_One(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -264,7 +269,7 @@ func TestDeleteNodeService_One(t *testing.T) {
} }
func TestDeleteNode(t *testing.T) { func TestDeleteNode(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -320,7 +325,7 @@ func TestDeleteNode(t *testing.T) {
} }
func TestGetServices(t *testing.T) { func TestGetServices(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -370,7 +375,7 @@ func TestGetServices(t *testing.T) {
} }
func TestServiceNodes(t *testing.T) { func TestServiceNodes(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -461,7 +466,7 @@ func TestServiceNodes(t *testing.T) {
} }
func TestServiceTagNodes(t *testing.T) { func TestServiceTagNodes(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -509,7 +514,7 @@ func TestServiceTagNodes(t *testing.T) {
} }
func TestStoreSnapshot(t *testing.T) { func TestStoreSnapshot(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -638,7 +643,7 @@ func TestStoreSnapshot(t *testing.T) {
} }
func TestEnsureCheck(t *testing.T) { func TestEnsureCheck(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -720,7 +725,7 @@ func TestEnsureCheck(t *testing.T) {
} }
func TestDeleteNodeCheck(t *testing.T) { func TestDeleteNodeCheck(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -770,7 +775,7 @@ func TestDeleteNodeCheck(t *testing.T) {
} }
func TestCheckServiceNodes(t *testing.T) { func TestCheckServiceNodes(t *testing.T) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -851,7 +856,7 @@ func TestCheckServiceNodes(t *testing.T) {
} }
} }
func BenchmarkCheckServiceNodes(t *testing.B) { func BenchmarkCheckServiceNodes(t *testing.B) {
store, err := NewStateStore() store, err := testStateStore()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -887,3 +892,45 @@ func BenchmarkCheckServiceNodes(t *testing.B) {
store.CheckServiceNodes("db") store.CheckServiceNodes("db")
} }
} }
func TestSS_Register_Deregister_Query(t *testing.T) {
store, err := testStateStore()
if err != nil {
t.Fatalf("err: %v", err)
}
defer store.Close()
if err := store.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}); err != nil {
t.Fatalf("err: %v", err)
}
srv := &structs.NodeService{
"statsite-box-stats",
"statsite-box-stats",
"",
0}
if err := store.EnsureService(2, "foo", srv); err != nil {
t.Fatalf("err: %v")
}
srv = &structs.NodeService{
"statsite-share-stats",
"statsite-share-stats",
"",
0}
if err := store.EnsureService(3, "foo", srv); err != nil {
t.Fatalf("err: %v")
}
if err := store.DeleteNode(4, "foo"); err != nil {
t.Fatalf("err: %v", err)
}
idx, nodes := store.CheckServiceNodes("statsite-share-stats")
if idx != 4 {
t.Fatalf("bad: %v", idx)
}
if len(nodes) != 0 {
t.Fatalf("Bad: %v", nodes)
}
}