forked from kubernetes/kubernetes
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request kubernetes#130 from lavalamp/test_fix
Move labels and tests to new package
- Loading branch information
Showing
22 changed files
with
428 additions
and
171 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
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,19 @@ | ||
/* | ||
Copyright 2014 Google Inc. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
// Package labels implements a simple label system, parsing and matching queries | ||
// with sets of labels. | ||
package labels |
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,47 @@ | ||
/* | ||
Copyright 2014 Google Inc. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package labels | ||
|
||
import ( | ||
"sort" | ||
"strings" | ||
) | ||
|
||
// Labels allows you to present labels independently from their storage. | ||
type Labels interface { | ||
Get(label string) (value string) | ||
} | ||
|
||
// A map of label:value. Implements Labels. | ||
type Set map[string]string | ||
|
||
// All labels listed as a human readable string. Conveniently, exactly the format | ||
// that ParseQuery takes. | ||
func (ls Set) String() string { | ||
query := make([]string, 0, len(ls)) | ||
for key, value := range ls { | ||
query = append(query, key+"="+value) | ||
} | ||
// Sort for determinism. | ||
sort.StringSlice(query).Sort() | ||
return strings.Join(query, ",") | ||
} | ||
|
||
// Implement Labels interface. | ||
func (ls Set) Get(label string) string { | ||
return ls[label] | ||
} |
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,43 @@ | ||
/* | ||
Copyright 2014 Google Inc. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package labels | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func matches(t *testing.T, ls Set, want string) { | ||
if ls.String() != want { | ||
t.Errorf("Expected '%s', but got '%s'", want, ls.String()) | ||
} | ||
} | ||
|
||
func TestSetString(t *testing.T) { | ||
matches(t, Set{"x": "y"}, "x=y") | ||
matches(t, Set{"foo": "bar"}, "foo=bar") | ||
matches(t, Set{"foo": "bar", "baz": "qup"}, "baz=qup,foo=bar") | ||
|
||
// TODO: Make our label representation robust enough to handle labels | ||
// with ",=!" characters in their names. | ||
} | ||
|
||
func TestLabelGet(t *testing.T) { | ||
ls := Set{"x": "y"} | ||
if ls.Get("x") != "y" { | ||
t.Errorf("Set.Get is broken") | ||
} | ||
} |
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,123 @@ | ||
/* | ||
Copyright 2014 Google Inc. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package labels | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
// Represents a label query. | ||
type Query interface { | ||
// Returns true if this query matches the given set of labels. | ||
Matches(Labels) bool | ||
|
||
// Prints a human readable version of this label query. | ||
String() string | ||
} | ||
|
||
// Everything returns a query that matches all labels. | ||
func Everything() Query { | ||
return andTerm{} | ||
} | ||
|
||
type hasTerm struct { | ||
label, value string | ||
} | ||
|
||
func (t *hasTerm) Matches(ls Labels) bool { | ||
return ls.Get(t.label) == t.value | ||
} | ||
|
||
func (t *hasTerm) String() string { | ||
return fmt.Sprintf("%v=%v", t.label, t.value) | ||
} | ||
|
||
type notHasTerm struct { | ||
label, value string | ||
} | ||
|
||
func (t *notHasTerm) Matches(ls Labels) bool { | ||
return ls.Get(t.label) != t.value | ||
} | ||
|
||
func (t *notHasTerm) String() string { | ||
return fmt.Sprintf("%v!=%v", t.label, t.value) | ||
} | ||
|
||
type andTerm []Query | ||
|
||
func (t andTerm) Matches(ls Labels) bool { | ||
for _, q := range t { | ||
if !q.Matches(ls) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
func (t andTerm) String() string { | ||
var terms []string | ||
for _, q := range t { | ||
terms = append(terms, q.String()) | ||
} | ||
return strings.Join(terms, ",") | ||
} | ||
|
||
func try(queryPiece, op string) (lhs, rhs string, ok bool) { | ||
pieces := strings.Split(queryPiece, op) | ||
if len(pieces) == 2 { | ||
return pieces[0], pieces[1], true | ||
} | ||
return "", "", false | ||
} | ||
|
||
// Given a Set, return a Query which will match exactly that Set. | ||
func QueryFromSet(ls Set) Query { | ||
var items []Query | ||
for label, value := range ls { | ||
items = append(items, &hasTerm{label: label, value: value}) | ||
} | ||
if len(items) == 1 { | ||
return items[0] | ||
} | ||
return andTerm(items) | ||
} | ||
|
||
// Takes a string repsenting a label query and returns an object suitable for matching, or an error. | ||
func ParseQuery(query string) (Query, error) { | ||
parts := strings.Split(query, ",") | ||
var items []Query | ||
for _, part := range parts { | ||
if part == "" { | ||
continue | ||
} | ||
if lhs, rhs, ok := try(part, "!="); ok { | ||
items = append(items, ¬HasTerm{label: lhs, value: rhs}) | ||
} else if lhs, rhs, ok := try(part, "=="); ok { | ||
items = append(items, &hasTerm{label: lhs, value: rhs}) | ||
} else if lhs, rhs, ok := try(part, "="); ok { | ||
items = append(items, &hasTerm{label: lhs, value: rhs}) | ||
} else { | ||
return nil, fmt.Errorf("invalid label query: '%s'; can't understand '%s'", query, part) | ||
} | ||
} | ||
if len(items) == 1 { | ||
return items[0], nil | ||
} | ||
return andTerm(items), nil | ||
} |
Oops, something went wrong.