client: test watching allocations

This commit is contained in:
Armon Dadgar 2015-08-29 14:33:30 -07:00
parent 4d6238ebb8
commit e57ee3fbfe
2 changed files with 72 additions and 3 deletions

View File

@ -473,7 +473,7 @@ func (c *Client) watchAllocations(allocUpdates chan []*structs.Allocation) {
func (c *Client) runAllocs(updated []*structs.Allocation) {
// Get the existing allocs
c.allocLock.RLock()
exist := make([]*structs.Allocation, len(c.allocs))
exist := make([]*structs.Allocation, 0, len(c.allocs))
for _, ctx := range c.allocs {
exist = append(exist, ctx.Alloc())
}
@ -515,14 +515,15 @@ func (c *Client) runAllocs(updated []*structs.Allocation) {
// removeAlloc is invoked when we should remove an allocation
func (c *Client) removeAlloc(alloc *structs.Allocation) error {
c.allocLock.RLock()
defer c.allocLock.RUnlock()
c.allocLock.Lock()
defer c.allocLock.Unlock()
ctx, ok := c.allocs[alloc.ID]
if !ok {
c.logger.Printf("[WARN] client: missing context for alloc '%s'", alloc.ID)
return nil
}
ctx.Destroy()
delete(c.allocs, alloc.ID)
return nil
}

View File

@ -238,3 +238,71 @@ func TestClient_UpdateAllocStatus(t *testing.T) {
t.Fatalf("bad: %#v", out)
}
}
func TestClient_WatchAllocs(t *testing.T) {
s1, _ := testServer(t, nil)
defer s1.Shutdown()
testutil.WaitForLeader(t, s1.RPC)
c1 := testClient(t, func(c *config.Config) {
c.RPCHandler = s1
})
defer c1.Shutdown()
// Create mock allocations
alloc1 := mock.Alloc()
alloc1.NodeID = c1.Node().ID
alloc2 := mock.Alloc()
alloc2.NodeID = c1.Node().ID
state := s1.State()
err := state.UpdateAllocations(100,
[]*structs.Allocation{alloc1, alloc2})
if err != nil {
t.Fatalf("err: %v", err)
}
// Both allocations should get registered
testutil.WaitForResult(func() (bool, error) {
c1.allocLock.RLock()
num := len(c1.allocs)
c1.allocLock.RUnlock()
return num == 2, nil
}, func(err error) {
t.Fatalf("err: %v", err)
})
// Delete one allocation
err = state.DeleteEval(101, nil, []string{alloc1.ID})
if err != nil {
t.Fatalf("err: %v", err)
}
// Update the other allocation
alloc2.DesiredStatus = structs.AllocDesiredStatusStop
err = state.UpdateAllocations(102,
[]*structs.Allocation{alloc2})
if err != nil {
t.Fatalf("err: %v", err)
}
// One allocations should get de-registered
testutil.WaitForResult(func() (bool, error) {
c1.allocLock.RLock()
num := len(c1.allocs)
c1.allocLock.RUnlock()
return num == 1, nil
}, func(err error) {
t.Fatalf("err: %v", err)
})
// One allocations should get updated
testutil.WaitForResult(func() (bool, error) {
c1.allocLock.RLock()
ar := c1.allocs[alloc2.ID]
c1.allocLock.RUnlock()
return ar.Alloc().DesiredStatus == structs.AllocDesiredStatusStop, nil
}, func(err error) {
t.Fatalf("err: %v", err)
})
}