Added more tests. Also added return of 404 if the session id to renew is not found

This commit is contained in:
Atin Malaviya 2014-12-10 10:02:23 -05:00
parent b623af776b
commit c992c18ef0
6 changed files with 180 additions and 22 deletions

View File

@ -156,7 +156,12 @@ func (s *HTTPServer) SessionRenew(resp http.ResponseWriter, req *http.Request) (
defer setMeta(resp, &out.QueryMeta)
if err := s.agent.RPC("Session.Renew", &args, &out); err != nil {
return nil, err
} else if out.Sessions == nil {
resp.WriteHeader(404)
resp.Write([]byte(fmt.Sprintf("Session id '%s' not found", args.Session)))
return nil, nil
}
return out.Sessions, nil
}

View File

@ -250,11 +250,8 @@ func TestSessionTTL(t *testing.T) {
t.Fatalf("err: %v", err)
}
respObj, ok = obj.(structs.Sessions)
if ok {
t.Fatalf("session '%s' should have been destroyed")
}
if len(respObj) != 0 {
t.Fatalf("bad: %v", respObj)
t.Fatalf("session '%s' should have been destroyed", id)
}
})
}
@ -315,10 +312,10 @@ func TestSessionTTLRenew(t *testing.T) {
}
respObj, ok = obj.(structs.Sessions)
if !ok {
t.Fatalf("session '%s' should have renewed")
t.Fatalf("session '%s' should have renewed", id)
}
if len(respObj) != 1 {
t.Fatalf("bad: %v", respObj)
t.Fatalf("session '%s' should have renewed", id)
}
// now wait for timeout and expect session to get destroyed
@ -332,11 +329,11 @@ func TestSessionTTLRenew(t *testing.T) {
t.Fatalf("err: %v", err)
}
respObj, ok = obj.(structs.Sessions)
if ok {
t.Fatalf("session '%s' should have been destroyed")
if !ok {
t.Fatalf("session '%s' should have destroyed", id)
}
if len(respObj) != 0 {
t.Fatalf("bad: %v", respObj)
t.Fatalf("session '%s' should have destroyed", id)
}
})
}

View File

@ -370,6 +370,9 @@ func TestLeader_LeftLeader(t *testing.T) {
break
}
}
if leader == nil {
t.Fatalf("Should have a leader")
}
leader.Leave()
leader.Shutdown()
time.Sleep(100 * time.Millisecond)

View File

@ -5,6 +5,7 @@ import (
"github.com/hashicorp/consul/testutil"
"os"
"testing"
"time"
)
func TestSessionEndpoint_Apply(t *testing.T) {
@ -223,6 +224,132 @@ func TestSessionEndpoint_List(t *testing.T) {
}
}
func TestSessionEndpoint_Renew(t *testing.T) {
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
client := rpcClient(t, s1)
defer client.Close()
testutil.WaitForLeader(t, client.Call, "dc1")
s1.fsm.State().EnsureNode(1, structs.Node{"foo", "127.0.0.1"})
ids := []string{}
for i := 0; i < 5; i++ {
arg := structs.SessionRequest{
Datacenter: "dc1",
Op: structs.SessionCreate,
Session: structs.Session{
Node: "foo",
TTL: "10s",
},
}
var out string
if err := client.Call("Session.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
ids = append(ids, out)
}
getR := structs.DCSpecificRequest{
Datacenter: "dc1",
}
var sessions structs.IndexedSessions
if err := client.Call("Session.List", &getR, &sessions); err != nil {
t.Fatalf("err: %v", err)
}
if sessions.Index == 0 {
t.Fatalf("Bad: %v", sessions)
}
if len(sessions.Sessions) != 5 {
t.Fatalf("Bad: %v", sessions.Sessions)
}
for i := 0; i < len(sessions.Sessions); i++ {
s := sessions.Sessions[i]
if !strContains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
t.Fatalf("bad: %v", s)
}
if s.TTL != "30s" {
t.Fatalf("bad: %v", s)
}
}
// now sleep for ttl - since internally we use ttl*2 to destroy, this is ok
time.Sleep(10 * time.Second)
// renew 3 out of 5 sessions
for i := 0; i < 3; i++ {
renewR := structs.SessionSpecificRequest{
Datacenter: "dc1",
Session: ids[i],
}
var session structs.IndexedSessions
if err := client.Call("Session.Renew", &renewR, &session); err != nil {
t.Fatalf("err: %v", err)
}
if session.Index == 0 {
t.Fatalf("Bad: %v", session)
}
if len(session.Sessions) != 1 {
t.Fatalf("Bad: %v", session.Sessions)
}
s := session.Sessions[0]
if !strContains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
t.Fatalf("bad: %v", s)
}
}
// now sleep for ttl*2 - 3 sessions should still be alive
time.Sleep(20 * time.Second)
if err := client.Call("Session.List", &getR, &sessions); err != nil {
t.Fatalf("err: %v", err)
}
if sessions.Index == 0 {
t.Fatalf("Bad: %v", sessions)
}
if len(sessions.Sessions) != 3 {
t.Fatalf("Bad: %v", sessions.Sessions)
}
for i := 0; i < len(sessions.Sessions); i++ {
s := sessions.Sessions[i]
if !strContains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
t.Fatalf("bad: %v", s)
}
if s.TTL != "30s" {
t.Fatalf("bad: %v", s)
}
}
// now sleep again for ttl*2 - no sessions should still be alive
time.Sleep(20 * time.Second)
if err := client.Call("Session.List", &getR, &sessions); err != nil {
t.Fatalf("err: %v", err)
}
if sessions.Index != 0 {
t.Fatalf("Bad: %v", sessions)
}
if len(sessions.Sessions) != 0 {
t.Fatalf("Bad: %v", sessions.Sessions)
}
}
func TestSessionEndpoint_NodeSessions(t *testing.T) {
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)

View File

@ -1825,6 +1825,16 @@ func (s *StateSnapshot) SessionList() ([]*structs.Session, error) {
return out, err
}
// SessionListTTL is used to list all the open sessions
func (s *StateSnapshot) SessionListTTL() ([]*structs.Session, error) {
res, err := s.store.sessionTable.GetTxn(s.tx, "ttl")
out := make([]*structs.Session, len(res))
for i, raw := range res {
out[i] = raw.(*structs.Session)
}
return out, err
}
// ACLList is used to list all of the ACLs
func (s *StateSnapshot) ACLList() ([]*structs.ACL, error) {
res, err := s.store.aclTable.GetTxn(s.tx, "id")

View File

@ -703,13 +703,17 @@ func TestStoreSnapshot(t *testing.T) {
if ok, err := store.KVSLock(18, d); err != nil || !ok {
t.Fatalf("err: %v", err)
}
session = &structs.Session{ID: generateUUID(), Node: "baz", TTL: "60s"}
if err := store.SessionCreate(19, session); err != nil {
t.Fatalf("err: %v", err)
}
a1 := &structs.ACL{
ID: generateUUID(),
Name: "User token",
Type: structs.ACLTypeClient,
}
if err := store.ACLSet(19, a1); err != nil {
if err := store.ACLSet(20, a1); err != nil {
t.Fatalf("err: %v", err)
}
@ -718,7 +722,7 @@ func TestStoreSnapshot(t *testing.T) {
Name: "User token",
Type: structs.ACLTypeClient,
}
if err := store.ACLSet(20, a2); err != nil {
if err := store.ACLSet(21, a2); err != nil {
t.Fatalf("err: %v", err)
}
@ -730,7 +734,7 @@ func TestStoreSnapshot(t *testing.T) {
defer snap.Close()
// Check the last nodes
if idx := snap.LastIndex(); idx != 20 {
if idx := snap.LastIndex(); idx != 21 {
t.Fatalf("bad: %v", idx)
}
@ -785,15 +789,27 @@ func TestStoreSnapshot(t *testing.T) {
t.Fatalf("missing KVS entries!")
}
// Check there are 2 sessions
// Check there are 3 sessions
sessions, err := snap.SessionList()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(sessions) != 2 {
if len(sessions) != 3 {
t.Fatalf("missing sessions")
}
// Check there is 1 session with TTL
sessions, err = snap.SessionListTTL()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(sessions) < 1 {
t.Fatalf("missing TTL session")
} else if len(sessions) > 1 {
t.Fatalf("too many TTL sessions")
}
// Check for an acl
acls, err := snap.ACLList()
if err != nil {
@ -804,13 +820,13 @@ func TestStoreSnapshot(t *testing.T) {
}
// Make some changes!
if err := store.EnsureService(21, "foo", &structs.NodeService{"db", "db", []string{"slave"}, 8000}); err != nil {
if err := store.EnsureService(22, "foo", &structs.NodeService{"db", "db", []string{"slave"}, 8000}); err != nil {
t.Fatalf("err: %v", err)
}
if err := store.EnsureService(22, "bar", &structs.NodeService{"db", "db", []string{"master"}, 8000}); err != nil {
if err := store.EnsureService(23, "bar", &structs.NodeService{"db", "db", []string{"master"}, 8000}); err != nil {
t.Fatalf("err: %v", err)
}
if err := store.EnsureNode(23, structs.Node{"baz", "127.0.0.3"}); err != nil {
if err := store.EnsureNode(24, structs.Node{"baz", "127.0.0.3"}); err != nil {
t.Fatalf("err: %v", err)
}
checkAfter := &structs.HealthCheck{
@ -820,16 +836,16 @@ func TestStoreSnapshot(t *testing.T) {
Status: structs.HealthCritical,
ServiceID: "db",
}
if err := store.EnsureCheck(24, checkAfter); err != nil {
if err := store.EnsureCheck(26, checkAfter); err != nil {
t.Fatalf("err: %v", err)
}
if err := store.KVSDelete(25, "/web/b"); err != nil {
if err := store.KVSDelete(26, "/web/b"); err != nil {
t.Fatalf("err: %v", err)
}
// Nuke an ACL
if err := store.ACLDelete(26, a1.ID); err != nil {
if err := store.ACLDelete(27, a1.ID); err != nil {
t.Fatalf("err: %v", err)
}
@ -883,12 +899,12 @@ func TestStoreSnapshot(t *testing.T) {
t.Fatalf("missing KVS entries!")
}
// Check there are 2 sessions
// Check there are 3 sessions
sessions, err = snap.SessionList()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(sessions) != 2 {
if len(sessions) != 3 {
t.Fatalf("missing sessions")
}