-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow specification of multiple expanders
Multiple expanders can now be specified, expanders now "filter to the tied for best" instead of "selecting the best" so the output of one expander is now fed to the input of the next. Each expander may only be used once to disallow bad configuration. This should not be a change in functionality as in the event of a tie the random expander is still used.
- Loading branch information
1 parent
45f518e
commit 9214395
Showing
16 changed files
with
322 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package factory | ||
|
||
import ( | ||
"k8s.io/autoscaler/cluster-autoscaler/expander" | ||
|
||
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" | ||
) | ||
|
||
type chainStrategy struct { | ||
filters []expander.Filter | ||
fallback expander.Strategy | ||
} | ||
|
||
func newChainStrategy(filters []expander.Filter, fallback expander.Strategy) expander.Strategy { | ||
return &chainStrategy{ | ||
filters: filters, | ||
fallback: fallback, | ||
} | ||
} | ||
|
||
func (c *chainStrategy) BestOption(options []expander.Option, nodeInfo map[string]*schedulerframework.NodeInfo) *expander.Option { | ||
filteredOptions := options | ||
for _, filter := range c.filters { | ||
filteredOptions = filter.BestOptions(filteredOptions, nodeInfo) | ||
if len(filteredOptions) == 1 { | ||
return &filteredOptions[0] | ||
} | ||
} | ||
return c.fallback.BestOption(filteredOptions, nodeInfo) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package factory | ||
|
||
import ( | ||
"k8s.io/autoscaler/cluster-autoscaler/expander" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" | ||
) | ||
|
||
type substringTestFilterStrategy struct { | ||
substring string | ||
} | ||
|
||
func newSubstringTestFilterStrategy(substring string) *substringTestFilterStrategy { | ||
return &substringTestFilterStrategy{ | ||
substring: substring, | ||
} | ||
} | ||
|
||
func (s *substringTestFilterStrategy) BestOptions(expansionOptions []expander.Option, nodeInfo map[string]*schedulerframework.NodeInfo) []expander.Option { | ||
var ret []expander.Option | ||
for _, option := range expansionOptions { | ||
if strings.Contains(option.Debug, s.substring) { | ||
ret = append(ret, option) | ||
} | ||
} | ||
return ret | ||
|
||
} | ||
|
||
func (s *substringTestFilterStrategy) BestOption(expansionOptions []expander.Option, nodeInfo map[string]*schedulerframework.NodeInfo) *expander.Option { | ||
ret := s.BestOptions(expansionOptions, nodeInfo) | ||
if len(ret) == 0 { | ||
return nil | ||
} | ||
return &ret[0] | ||
} | ||
|
||
func TestChainStrategy_BestOption(t *testing.T) { | ||
for name, tc := range map[string]struct { | ||
filters []expander.Filter | ||
fallback expander.Strategy | ||
options []expander.Option | ||
expected *expander.Option | ||
}{ | ||
"selects with no filters": { | ||
filters: []expander.Filter{}, | ||
fallback: newSubstringTestFilterStrategy("a"), | ||
options: []expander.Option{ | ||
*newOption("b"), | ||
*newOption("a"), | ||
}, | ||
expected: newOption("a"), | ||
}, | ||
"filters with one filter": { | ||
filters: []expander.Filter{ | ||
newSubstringTestFilterStrategy("a"), | ||
}, | ||
fallback: newSubstringTestFilterStrategy("b"), | ||
options: []expander.Option{ | ||
*newOption("ab"), | ||
*newOption("b"), | ||
}, | ||
expected: newOption("ab"), | ||
}, | ||
"filters with multiple filters": { | ||
filters: []expander.Filter{ | ||
newSubstringTestFilterStrategy("a"), | ||
newSubstringTestFilterStrategy("b"), | ||
}, | ||
fallback: newSubstringTestFilterStrategy("x"), | ||
options: []expander.Option{ | ||
*newOption("xab"), | ||
*newOption("xa"), | ||
*newOption("x"), | ||
}, | ||
expected: newOption("xab"), | ||
}, | ||
"selects from multiple after filters": { | ||
filters: []expander.Filter{ | ||
newSubstringTestFilterStrategy("x"), | ||
}, | ||
fallback: newSubstringTestFilterStrategy("a"), | ||
options: []expander.Option{ | ||
*newOption("xc"), | ||
*newOption("xaa"), | ||
*newOption("xab"), | ||
}, | ||
expected: newOption("xaa"), | ||
}, | ||
"short circuits": { | ||
filters: []expander.Filter{ | ||
newSubstringTestFilterStrategy("a"), | ||
newSubstringTestFilterStrategy("b"), | ||
}, | ||
fallback: newSubstringTestFilterStrategy("x"), | ||
options: []expander.Option{ | ||
*newOption("a"), | ||
}, | ||
expected: newOption("a"), | ||
}, | ||
} { | ||
t.Run(name, func(t *testing.T) { | ||
subject := newChainStrategy(tc.filters, tc.fallback) | ||
actual := subject.BestOption(tc.options, nil) | ||
assert.Equal(t, tc.expected, actual) | ||
}) | ||
} | ||
} | ||
|
||
func newOption(debug string) *expander.Option { | ||
return &expander.Option{ | ||
Debug: debug, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.