mirror of
https://github.com/kemko/nomad.git
synced 2026-01-05 09:55:44 +03:00
scheduler: adding regexp constraints
This commit is contained in:
@@ -3,6 +3,7 @@ package scheduler
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
@@ -251,11 +252,10 @@ func checkConstraint(operand string, lVal, rVal interface{}) bool {
|
||||
case "<", "<=", ">", ">=":
|
||||
// TODO: Implement
|
||||
return false
|
||||
case "contains":
|
||||
// TODO: Implement
|
||||
return false
|
||||
case "version":
|
||||
return checkVersionConstraint(lVal, rVal)
|
||||
case "regexp":
|
||||
return checkRegexpConstraint(lVal, rVal)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -296,3 +296,28 @@ func checkVersionConstraint(lVal, rVal interface{}) bool {
|
||||
// Check the constraints against the version
|
||||
return constraints.Check(vers)
|
||||
}
|
||||
|
||||
// checkRegexpConstraint is used to compare a value on the
|
||||
// left hand side with a regexp on the right hand side
|
||||
func checkRegexpConstraint(lVal, rVal interface{}) bool {
|
||||
// Ensure left-hand is string
|
||||
lStr, ok := lVal.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// Regexp must be a string
|
||||
regexpStr, ok := rVal.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// Parse the regexp
|
||||
re, err := regexp.Compile(regexpStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Look for a match
|
||||
return re.MatchString(lStr)
|
||||
}
|
||||
|
||||
@@ -249,6 +249,11 @@ func TestCheckConstraint(t *testing.T) {
|
||||
lVal: "1.2.3", rVal: "~> 1.0",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
op: "regexp",
|
||||
lVal: "foobarbaz", rVal: "[\\w]+",
|
||||
result: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -292,6 +297,40 @@ func TestCheckVersionConstraint(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckRegexpConstraint(t *testing.T) {
|
||||
type tcase struct {
|
||||
lVal, rVal interface{}
|
||||
result bool
|
||||
}
|
||||
cases := []tcase{
|
||||
{
|
||||
lVal: "foobar", rVal: "bar",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
lVal: "foobar", rVal: "^foo",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
lVal: "foobar", rVal: "^bar",
|
||||
result: false,
|
||||
},
|
||||
{
|
||||
lVal: "zipzap", rVal: "foo",
|
||||
result: false,
|
||||
},
|
||||
{
|
||||
lVal: 1, rVal: "foo",
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
if res := checkRegexpConstraint(tc.lVal, tc.rVal); res != tc.result {
|
||||
t.Fatalf("TC: %#v, Result: %v", tc, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func collectFeasible(iter FeasibleIterator) (out []*structs.Node) {
|
||||
for {
|
||||
next := iter.Next()
|
||||
|
||||
Reference in New Issue
Block a user