2019-03-08 12:48:12 +00:00
|
|
|
package nomad
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2020-03-18 11:27:32 +00:00
|
|
|
"github.com/hashicorp/go-msgpack/codec"
|
2019-03-08 12:48:12 +00:00
|
|
|
"github.com/hashicorp/nomad/nomad/mock"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
2019-04-11 00:15:04 +00:00
|
|
|
// This test compares the size of the normalized + OmitEmpty raft plan log entry
|
|
|
|
// with the earlier denormalized log.
|
|
|
|
//
|
2019-03-08 12:48:12 +00:00
|
|
|
// Whenever this test is changed, care should be taken to ensure the older msgpack size
|
|
|
|
// is recalculated when new fields are introduced in ApplyPlanResultsRequest
|
|
|
|
func TestPlanNormalize(t *testing.T) {
|
|
|
|
// This size was calculated using the older ApplyPlanResultsRequest format, in which allocations
|
|
|
|
// didn't use OmitEmpty and only the job was normalized in the stopped and preempted allocs.
|
|
|
|
// The newer format uses OmitEmpty and uses a minimal set of fields for the diff of the
|
|
|
|
// stopped and preempted allocs. The file for the older format hasn't been checked in, because
|
|
|
|
// it's not a good idea to check-in a 20mb file to the git repo.
|
|
|
|
unoptimizedLogSize := 19460168
|
|
|
|
|
|
|
|
numUpdatedAllocs := 10000
|
|
|
|
numStoppedAllocs := 8000
|
|
|
|
numPreemptedAllocs := 2000
|
|
|
|
mockAlloc := mock.Alloc()
|
|
|
|
mockAlloc.Job = nil
|
|
|
|
|
|
|
|
mockUpdatedAllocSlice := make([]*structs.Allocation, numUpdatedAllocs)
|
|
|
|
for i := 0; i < numUpdatedAllocs; i++ {
|
|
|
|
mockUpdatedAllocSlice = append(mockUpdatedAllocSlice, mockAlloc)
|
|
|
|
}
|
|
|
|
|
|
|
|
now := time.Now().UTC().UnixNano()
|
2019-04-11 00:15:04 +00:00
|
|
|
mockStoppedAllocSlice := make([]*structs.AllocationDiff, numStoppedAllocs)
|
2019-03-08 12:48:12 +00:00
|
|
|
for i := 0; i < numStoppedAllocs; i++ {
|
|
|
|
mockStoppedAllocSlice = append(mockStoppedAllocSlice, normalizeStoppedAlloc(mockAlloc, now))
|
|
|
|
}
|
|
|
|
|
2019-04-11 00:15:04 +00:00
|
|
|
mockPreemptionAllocSlice := make([]*structs.AllocationDiff, numPreemptedAllocs)
|
2019-03-08 12:48:12 +00:00
|
|
|
for i := 0; i < numPreemptedAllocs; i++ {
|
|
|
|
mockPreemptionAllocSlice = append(mockPreemptionAllocSlice, normalizePreemptedAlloc(mockAlloc, now))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a plan result
|
|
|
|
applyPlanLogEntry := structs.ApplyPlanResultsRequest{
|
|
|
|
AllocUpdateRequest: structs.AllocUpdateRequest{
|
|
|
|
AllocsUpdated: mockUpdatedAllocSlice,
|
|
|
|
AllocsStopped: mockStoppedAllocSlice,
|
|
|
|
},
|
2019-04-11 00:15:04 +00:00
|
|
|
AllocsPreempted: mockPreemptionAllocSlice,
|
2019-03-08 12:48:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handle := structs.MsgpackHandle
|
|
|
|
var buf bytes.Buffer
|
|
|
|
if err := codec.NewEncoder(&buf, handle).Encode(applyPlanLogEntry); err != nil {
|
|
|
|
t.Fatalf("Encoding failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
optimizedLogSize := buf.Len()
|
2021-03-31 13:26:26 +00:00
|
|
|
assert.Less(t, float64(optimizedLogSize)/float64(unoptimizedLogSize), 0.65)
|
2019-03-08 12:48:12 +00:00
|
|
|
}
|