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