github.com/bigcommerce/nomad@v0.9.3-bc/nomad/plan_normalization_test.go (about) 1 package nomad 2 3 import ( 4 "bytes" 5 "testing" 6 "time" 7 8 "github.com/hashicorp/nomad/nomad/mock" 9 "github.com/hashicorp/nomad/nomad/structs" 10 "github.com/stretchr/testify/assert" 11 "github.com/ugorji/go/codec" 12 ) 13 14 // This test compares the size of the normalized + OmitEmpty raft plan log entry 15 // with the earlier denormalized log. 16 // 17 // Whenever this test is changed, care should be taken to ensure the older msgpack size 18 // is recalculated when new fields are introduced in ApplyPlanResultsRequest 19 func TestPlanNormalize(t *testing.T) { 20 // This size was calculated using the older ApplyPlanResultsRequest format, in which allocations 21 // didn't use OmitEmpty and only the job was normalized in the stopped and preempted allocs. 22 // The newer format uses OmitEmpty and uses a minimal set of fields for the diff of the 23 // stopped and preempted allocs. The file for the older format hasn't been checked in, because 24 // it's not a good idea to check-in a 20mb file to the git repo. 25 unoptimizedLogSize := 19460168 26 27 numUpdatedAllocs := 10000 28 numStoppedAllocs := 8000 29 numPreemptedAllocs := 2000 30 mockAlloc := mock.Alloc() 31 mockAlloc.Job = nil 32 33 mockUpdatedAllocSlice := make([]*structs.Allocation, numUpdatedAllocs) 34 for i := 0; i < numUpdatedAllocs; i++ { 35 mockUpdatedAllocSlice = append(mockUpdatedAllocSlice, mockAlloc) 36 } 37 38 now := time.Now().UTC().UnixNano() 39 mockStoppedAllocSlice := make([]*structs.AllocationDiff, numStoppedAllocs) 40 for i := 0; i < numStoppedAllocs; i++ { 41 mockStoppedAllocSlice = append(mockStoppedAllocSlice, normalizeStoppedAlloc(mockAlloc, now)) 42 } 43 44 mockPreemptionAllocSlice := make([]*structs.AllocationDiff, numPreemptedAllocs) 45 for i := 0; i < numPreemptedAllocs; i++ { 46 mockPreemptionAllocSlice = append(mockPreemptionAllocSlice, normalizePreemptedAlloc(mockAlloc, now)) 47 } 48 49 // Create a plan result 50 applyPlanLogEntry := structs.ApplyPlanResultsRequest{ 51 AllocUpdateRequest: structs.AllocUpdateRequest{ 52 AllocsUpdated: mockUpdatedAllocSlice, 53 AllocsStopped: mockStoppedAllocSlice, 54 }, 55 AllocsPreempted: mockPreemptionAllocSlice, 56 } 57 58 handle := structs.MsgpackHandle 59 var buf bytes.Buffer 60 if err := codec.NewEncoder(&buf, handle).Encode(applyPlanLogEntry); err != nil { 61 t.Fatalf("Encoding failed: %v", err) 62 } 63 64 optimizedLogSize := buf.Len() 65 assert.True(t, float64(optimizedLogSize)/float64(unoptimizedLogSize) < 0.62) 66 }