open-nomad/nomad/plan_normalization_test.go
James Rasell 0e926ef3fd
allow configuration of Docker hostnames in bridge mode (#11173)
Add a new hostname string parameter to the network block which
allows operators to specify the hostname of the network namespace.
Changing this causes a destructive update to the allocation and it
is omitted if empty from API responses. This parameter also supports
interpolation.

In order to have a hostname passed as a configuration param when
creating an allocation network, the CreateNetwork func of the
DriverNetworkManager interface needs to be updated. In order to
minimize the disruption of future changes, rather than add another
string func arg, the function now accepts a request struct along with
the allocID param. The struct has the hostname as a field.

The in-tree implementations of DriverNetworkManager.CreateNetwork
have been modified to account for the function signature change.
In updating for the change, the enhancement of adding hostnames to
network namespaces has also been added to the Docker driver, whilst
the default Linux manager does not current implement it.
2021-09-16 08:13:09 +02:00

67 lines
2.3 KiB
Go

package nomad
import (
"bytes"
"testing"
"time"
"github.com/hashicorp/go-msgpack/codec"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/stretchr/testify/assert"
)
// This test compares the size of the normalized + OmitEmpty raft plan log entry
// with the earlier denormalized log.
//
// 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()
mockStoppedAllocSlice := make([]*structs.AllocationDiff, numStoppedAllocs)
for i := 0; i < numStoppedAllocs; i++ {
mockStoppedAllocSlice = append(mockStoppedAllocSlice, normalizeStoppedAlloc(mockAlloc, now))
}
mockPreemptionAllocSlice := make([]*structs.AllocationDiff, numPreemptedAllocs)
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,
},
AllocsPreempted: mockPreemptionAllocSlice,
}
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()
assert.Less(t, float64(optimizedLogSize)/float64(unoptimizedLogSize), 0.67)
}