Prevent side effect modification of select options when preferred nodes are set

This commit is contained in:
Preetha Appan
2018-01-19 10:09:30 -06:00
parent c6c0741bd8
commit 4cbef07d37
2 changed files with 13 additions and 5 deletions

View File

@@ -172,13 +172,14 @@ func (s *GenericStack) Select(tg *structs.TaskGroup, options *SelectOptions) (*R
if options != nil && len(options.PreferredNodes) > 0 {
originalNodes := s.source.nodes
s.source.SetNodes(options.PreferredNodes)
options.PreferredNodes = nil
if option, resources := s.Select(tg, options); option != nil {
optionsNew := *options
optionsNew.PreferredNodes = nil
if option, resources := s.Select(tg, &optionsNew); option != nil {
s.source.SetNodes(originalNodes)
return option, resources
}
s.source.SetNodes(originalNodes)
return s.Select(tg, options)
return s.Select(tg, &optionsNew)
}
// Reset the max selector and context

View File

@@ -8,6 +8,7 @@ import (
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/stretchr/testify/require"
)
func BenchmarkServiceStack_With_ComputedClass(b *testing.B) {
@@ -140,7 +141,8 @@ func TestServiceStack_Select_PreferringNodes(t *testing.T) {
// Create a preferred node
preferredNode := mock.Node()
selectOptions := &SelectOptions{PreferredNodes: []*structs.Node{preferredNode}}
prefNodes := []*structs.Node{preferredNode}
selectOptions := &SelectOptions{PreferredNodes: prefNodes}
option, _ := stack.Select(job.TaskGroups[0], selectOptions)
if option == nil {
t.Fatalf("missing node %#v", ctx.Metrics())
@@ -149,12 +151,16 @@ func TestServiceStack_Select_PreferringNodes(t *testing.T) {
t.Fatalf("expected: %v, actual: %v", option.Node.ID, preferredNode.ID)
}
// Make sure select doesn't have a side effect on preferred nodes
require.Equal(t, prefNodes, selectOptions.PreferredNodes)
// Change the preferred node's kernel to windows and ensure the allocations
// are placed elsewhere
preferredNode1 := preferredNode.Copy()
preferredNode1.Attributes["kernel.name"] = "windows"
preferredNode1.ComputeClass()
selectOptions = &SelectOptions{PreferredNodes: []*structs.Node{preferredNode1}}
prefNodes1 := []*structs.Node{preferredNode1}
selectOptions = &SelectOptions{PreferredNodes: prefNodes1}
option, _ = stack.Select(job.TaskGroups[0], selectOptions)
if option == nil {
t.Fatalf("missing node %#v", ctx.Metrics())
@@ -163,6 +169,7 @@ func TestServiceStack_Select_PreferringNodes(t *testing.T) {
if option.Node.ID != nodes[0].ID {
t.Fatalf("expected: %#v, actual: %#v", nodes[0], option.Node)
}
require.Equal(t, prefNodes1, selectOptions.PreferredNodes)
}
func TestServiceStack_Select_MetricsReset(t *testing.T) {