mirror of
https://github.com/status-im/consul.git
synced 2025-01-09 21:35:52 +00:00
81df781e5f
Introduces `storage.Backend`, which will serve as the interface between the Resource Service and the underlying storage system (Raft today, but in the future, who knows!). The primary design goal of this interface is to keep its surface area small, and push as much functionality as possible into the layers above, so that new implementations can be added with little effort, and easily proven to be correct. To that end, we also provide a suite of "conformance" tests that can be run against a backend implementation to check it behaves correctly. In this commit, we introduce an initial in-memory storage backend, which is suitable for tests and when running Consul in development mode. This backend is a thin wrapper around the `Store` type, which implements a resource database using go-memdb and our internal pub/sub system. `Store` will also be used to handle reads in our Raft backend, and in the future, used as a local cache for external storage systems.
93 lines
2.1 KiB
Go
93 lines
2.1 KiB
Go
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,
|
|
) {
|
|
t.Helper()
|
|
|
|
if len(listX) == 0 && len(listY) == 0 {
|
|
return
|
|
}
|
|
|
|
opts = append(opts, protocmp.Transform())
|
|
|
|
// 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(outY) && len(listX) == 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)
|
|
}
|
|
|
|
if diff := cmp.Diff(outX, outY, opts...); diff != "" {
|
|
t.Fatalf("assertion failed: slices do not have matching elements\n--- expected\n+++ actual\n%v", diff)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|