Matt Keeler 653a886689
Implement a Catalog Controllers Lifecycle Integration Test (#17435)
* Implement a Catalog Controllers Lifecycle Integration Test

* Prevent triggering the race detector.

This allows defining some variables for protobuf constants and using those in comparisons. Without that, something internal in the fmt package ended up looking at the protobuf message size cache and triggering the race detector.
2023-06-16 12:58:53 -04:00

105 lines
2.4 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package prototest
import (
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/testing/protocmp"
)
type TestingT interface {
Helper()
Fatalf(string, ...any)
}
func AssertDeepEqual(t TestingT, x, y interface{}, opts ...cmp.Option) {
t.Helper()
opts = append(opts, protocmp.Transform())
if diff := cmp.Diff(x, y, opts...); diff != "" {
t.Fatalf("assertion failed: values are not equal\n--- expected\n+++ actual\n%v", diff)
}
}
// AssertElementsMatch asserts that the specified listX(array, slice...) is
// equal to specified listY(array, slice...) ignoring the order of the
// elements. If there are duplicate elements, the number of appearances of each
// of them in both lists should match.
//
// prototest.AssertElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
func AssertElementsMatch[V any](
t TestingT, listX, listY []V, opts ...cmp.Option,
) {
diff := diffElements(listX, listY, opts...)
if diff != "" {
t.Fatalf("assertion failed: slices do not have matching elements\n--- expected\n+++ actual\n%v", diff)
}
}
func diffElements[V any](
listX, listY []V, opts ...cmp.Option,
) string {
if len(listX) == 0 && len(listY) == 0 {
return ""
}
opts = append(opts, protocmp.Transform())
if len(listX) != len(listY) {
return cmp.Diff(listX, listY, opts...)
}
// dump into a map keyed by sliceID
mapX := make(map[int]V)
for i, val := range listX {
mapX[i] = val
}
mapY := make(map[int]V)
for i, val := range listY {
mapY[i] = val
}
var outX, outY []V
for i, itemX := range mapX {
for j, itemY := range mapY {
if diff := cmp.Diff(itemX, itemY, opts...); diff == "" {
outX = append(outX, itemX)
outY = append(outY, itemY)
delete(mapX, i)
delete(mapY, j)
}
}
}
if len(outX) == len(listX) && len(outY) == len(listY) {
return "" // matches
}
// dump remainder into the slice so we can generate a useful error
for _, itemX := range mapX {
outX = append(outX, itemX)
}
for _, itemY := range mapY {
outY = append(outY, itemY)
}
return cmp.Diff(outX, outY, opts...)
}
func AssertContainsElement[V any](t TestingT, list []V, element V, opts ...cmp.Option) {
t.Helper()
opts = append(opts, protocmp.Transform())
for _, e := range list {
if cmp.Equal(e, element, opts...) {
return
}
}
t.Fatalf("assertion failed: list does not contain element\n--- list\n%+v\n--- element: %+v", list, element)
}