scheduler: adding regexp constraints

This commit is contained in:
Armon Dadgar
2015-10-11 15:35:13 -04:00
parent 2aad0838fa
commit 0a2e874245
2 changed files with 67 additions and 3 deletions

View File

@@ -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)
}

View File

@@ -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()