client: alloc diffing
This commit is contained in:
parent
811d6d85e1
commit
1dfa7296c1
|
@ -4,10 +4,74 @@ import (
|
|||
crand "crypto/rand"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
import "math/rand"
|
||||
|
||||
type allocTuple struct {
|
||||
exist, updated *structs.Allocation
|
||||
}
|
||||
|
||||
// diffResult is used to return the sets that result from a diff
|
||||
type diffResult struct {
|
||||
added []*structs.Allocation
|
||||
removed []*structs.Allocation
|
||||
updated []allocTuple
|
||||
ignore []*structs.Allocation
|
||||
}
|
||||
|
||||
func (d *diffResult) GoString() string {
|
||||
return fmt.Sprintf("allocs: (added %d) (removed %d) (updated %d) (ignore %d)",
|
||||
len(d.added), len(d.removed), len(d.updated), len(d.ignore))
|
||||
}
|
||||
|
||||
// diffAllocs is used to diff the existing and updated allocations
|
||||
// to see what has happened.
|
||||
func diffAllocs(existing, updated []*structs.Allocation) *diffResult {
|
||||
result := &diffResult{}
|
||||
|
||||
// Index the updated allocations by id
|
||||
idx := make(map[string]*structs.Allocation)
|
||||
for _, update := range updated {
|
||||
idx[update.ID] = update
|
||||
}
|
||||
|
||||
// Scan the existing allocations
|
||||
existIdx := make(map[string]struct{})
|
||||
for _, exist := range existing {
|
||||
// Mark this as existing
|
||||
existIdx[exist.ID] = struct{}{}
|
||||
|
||||
// Check for presence in the new set
|
||||
update, ok := idx[exist.ID]
|
||||
|
||||
// If not present, removed
|
||||
if !ok {
|
||||
result.removed = append(result.removed, exist)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check for an update
|
||||
if update.ModifyIndex > exist.ModifyIndex {
|
||||
result.updated = append(result.updated, allocTuple{exist, update})
|
||||
continue
|
||||
}
|
||||
|
||||
// Ignore this
|
||||
result.ignore = append(result.ignore, exist)
|
||||
}
|
||||
|
||||
// Scan the updated allocations for any that are new
|
||||
for _, update := range updated {
|
||||
if _, ok := existIdx[update.ID]; !ok {
|
||||
result.added = append(result.added, update)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// generateUUID is used to generate a random UUID
|
||||
func generateUUID() string {
|
||||
buf := make([]byte, 16)
|
||||
|
|
|
@ -5,8 +5,50 @@ import (
|
|||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
func TestDiffAllocs(t *testing.T) {
|
||||
alloc1 := mock.Alloc() // Ignore
|
||||
alloc2 := mock.Alloc() // Update
|
||||
alloc2u := new(structs.Allocation)
|
||||
*alloc2u = *alloc2
|
||||
alloc2u.ModifyIndex += 1
|
||||
alloc3 := mock.Alloc() // Remove
|
||||
alloc4 := mock.Alloc() // Add
|
||||
|
||||
exist := []*structs.Allocation{
|
||||
alloc1,
|
||||
alloc2,
|
||||
alloc3,
|
||||
}
|
||||
updated := []*structs.Allocation{
|
||||
alloc1,
|
||||
alloc2u,
|
||||
alloc4,
|
||||
}
|
||||
|
||||
result := diffAllocs(exist, updated)
|
||||
|
||||
if len(result.ignore) != 1 || result.ignore[0] != alloc1 {
|
||||
t.Fatalf("Bad: %#v", result.ignore)
|
||||
}
|
||||
if len(result.added) != 1 || result.added[0] != alloc4 {
|
||||
t.Fatalf("Bad: %#v", result.added)
|
||||
}
|
||||
if len(result.removed) != 1 || result.removed[0] != alloc3 {
|
||||
t.Fatalf("Bad: %#v", result.removed)
|
||||
}
|
||||
if len(result.updated) != 1 {
|
||||
t.Fatalf("Bad: %#v", result.updated)
|
||||
}
|
||||
if result.updated[0].exist != alloc2 || result.updated[0].updated != alloc2u {
|
||||
t.Fatalf("Bad: %#v", result.updated)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateUUID(t *testing.T) {
|
||||
prev := generateUUID()
|
||||
for i := 0; i < 100; i++ {
|
||||
|
|
Loading…
Reference in New Issue