-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
scheduler: annotate tasksUpdated with reason and purge DeepEquals
- Loading branch information
Showing
11 changed files
with
1,054 additions
and
243 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package lang | ||
|
||
import ( | ||
"github.com/google/go-cmp/cmp" | ||
"github.com/google/go-cmp/cmp/cmpopts" | ||
"golang.org/x/exp/maps" | ||
) | ||
|
||
var ( | ||
cmpOptIgnoreUnexported = ignoreUnexportedAlways() | ||
cmpOptNilIsEmpty = cmpopts.EquateEmpty() | ||
cmpOptIgnore = cmp.Ignore() | ||
) | ||
|
||
// ignoreUnexportedAlways creates a cmp.Option filter that will ignore unexported | ||
// fields of on any/all types. It is a derivative of go-cmp.IgnoreUnexported, | ||
// here we do not require specifying individual types. | ||
// | ||
// reference: https://github.com/google/go-cmp/blob/master/cmp/cmpopts/ignore.go#L110 | ||
func ignoreUnexportedAlways() cmp.Option { | ||
return cmp.FilterPath( | ||
func(p cmp.Path) bool { | ||
sf, ok := p.Index(-1).(cmp.StructField) | ||
if !ok { | ||
return false | ||
} | ||
c := sf.Name()[0] | ||
return c < 'A' || c > 'Z' | ||
}, | ||
cmpOptIgnore, | ||
) | ||
} | ||
|
||
// OpaqueMapsEqual compare maps[<comparable>]<any> for equality, but safely by | ||
// using the cmp package and ignoring un-exported types, and by treating nil/empty | ||
// slices and maps as equal. | ||
// | ||
// This is intended as a substitute for reflect.DeepEqual in the case of "opaque maps", | ||
// e.g. `map[comparable]any` - such as the case for Task Driver config or Envoy proxy | ||
// pass-through configuration. | ||
func OpaqueMapsEqual[M ~map[K]V, K comparable, V any](m1, m2 M) bool { | ||
return maps.EqualFunc(m1, m2, func(a, b V) bool { | ||
return cmp.Equal(a, b, | ||
cmpOptIgnoreUnexported, // ignore all unexported fields | ||
cmpOptNilIsEmpty, // treat nil/empty slices as equal | ||
) | ||
}) | ||
} |
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,88 @@ | ||
package lang | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/nomad/ci" | ||
"github.com/shoenig/test/must" | ||
) | ||
|
||
func Test_OpaqueMapsEqual(t *testing.T) { | ||
ci.Parallel(t) | ||
|
||
type public struct { | ||
F int | ||
} | ||
|
||
type private struct { | ||
g int | ||
} | ||
|
||
type mix struct { | ||
F int | ||
g int | ||
} | ||
|
||
cases := []struct { | ||
name string | ||
a, b map[string]any | ||
exp bool | ||
}{{ | ||
name: "both nil", | ||
a: nil, | ||
b: nil, | ||
exp: true, | ||
}, { | ||
name: "empty and nil", | ||
a: nil, | ||
b: make(map[string]any), | ||
exp: true, | ||
}, { | ||
name: "same strings", | ||
a: map[string]any{"a": "A"}, | ||
b: map[string]any{"a": "A"}, | ||
exp: true, | ||
}, { | ||
name: "same public struct", | ||
a: map[string]any{"a": &public{F: 42}}, | ||
b: map[string]any{"a": &public{F: 42}}, | ||
exp: true, | ||
}, { | ||
name: "different public struct", | ||
a: map[string]any{"a": &public{F: 42}}, | ||
b: map[string]any{"a": &public{F: 10}}, | ||
exp: false, | ||
}, { | ||
name: "different private struct", | ||
a: map[string]any{"a": &private{g: 42}}, | ||
b: map[string]any{"a": &private{g: 10}}, | ||
exp: true, // private fields not compared | ||
}, { | ||
name: "mix same public different private", | ||
a: map[string]any{"a": &mix{F: 42, g: 1}}, | ||
b: map[string]any{"a": &mix{F: 42, g: 2}}, | ||
exp: true, // private fields not compared | ||
}, { | ||
name: "mix different public same private", | ||
a: map[string]any{"a": &mix{F: 42, g: 1}}, | ||
b: map[string]any{"a": &mix{F: 10, g: 1}}, | ||
exp: false, | ||
}, { | ||
name: "nil vs empty slice values", | ||
a: map[string]any{"key": []string(nil)}, | ||
b: map[string]any{"key": make([]string, 0)}, | ||
exp: true, | ||
}, { | ||
name: "nil vs empty map values", | ||
a: map[string]any{"key": map[int]int(nil)}, | ||
b: map[string]any{"key": make(map[int]int, 0)}, | ||
exp: true, | ||
}} | ||
|
||
for _, tc := range cases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
result := OpaqueMapsEqual(tc.a, tc.b) | ||
must.Eq(t, tc.exp, result) | ||
}) | ||
} | ||
} |
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.