|
|
|
@@ -22,6 +22,7 @@ import (
|
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
|
|
|
|
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
|
|
|
|
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
|
|
|
|
"github.com/grafana/grafana/pkg/util/testutil"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -108,34 +109,34 @@ func runTestIntegrationBackendHappyPath(t *testing.T, backend resource.StorageBa
|
|
|
|
|
var rv1, rv2, rv3, rv4, rv5 int64
|
|
|
|
|
|
|
|
|
|
t.Run("Add 3 resources", func(t *testing.T) {
|
|
|
|
|
rv1, err = writeEvent(ctx, backend, "item1", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv1, err = writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv1, int64(0))
|
|
|
|
|
|
|
|
|
|
rv2, err = writeEvent(ctx, backend, "item2", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv2, err = writeEvent(ctx, backend, "item2", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv2, rv1)
|
|
|
|
|
|
|
|
|
|
rv3, err = writeEvent(ctx, backend, "item3", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv3, err = writeEvent(ctx, backend, "item3", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv3, rv2)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Update item2", func(t *testing.T) {
|
|
|
|
|
rv4, err = writeEvent(ctx, backend, "item2", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rv4, err = writeEvent(ctx, backend, "item2", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv4, rv3)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Delete item1", func(t *testing.T) {
|
|
|
|
|
rv5, err = writeEvent(ctx, backend, "item1", resource.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
rv5, err = writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv5, rv4)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Read latest item 2", func(t *testing.T) {
|
|
|
|
|
resp := backend.ReadResource(ctx, &resource.ReadRequest{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
resp := backend.ReadResource(ctx, &resourcepb.ReadRequest{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Name: "item2",
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
@@ -149,8 +150,8 @@ func runTestIntegrationBackendHappyPath(t *testing.T, backend resource.StorageBa
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Read early version of item2", func(t *testing.T) {
|
|
|
|
|
resp := backend.ReadResource(ctx, &resource.ReadRequest{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
resp := backend.ReadResource(ctx, &resourcepb.ReadRequest{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Name: "item2",
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
@@ -164,9 +165,9 @@ func runTestIntegrationBackendHappyPath(t *testing.T, backend resource.StorageBa
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("List latest", func(t *testing.T) {
|
|
|
|
|
resp, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
resp, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
@@ -185,29 +186,29 @@ func runTestIntegrationBackendHappyPath(t *testing.T, backend resource.StorageBa
|
|
|
|
|
event := <-stream
|
|
|
|
|
require.Equal(t, "item1", event.Key.Name)
|
|
|
|
|
require.Equal(t, rv1, event.ResourceVersion)
|
|
|
|
|
require.Equal(t, resource.WatchEvent_ADDED, event.Type)
|
|
|
|
|
require.Equal(t, resourcepb.WatchEvent_ADDED, event.Type)
|
|
|
|
|
require.Equal(t, "folderuid", event.Folder)
|
|
|
|
|
|
|
|
|
|
event = <-stream
|
|
|
|
|
require.Equal(t, "item2", event.Key.Name)
|
|
|
|
|
require.Equal(t, rv2, event.ResourceVersion)
|
|
|
|
|
require.Equal(t, resource.WatchEvent_ADDED, event.Type)
|
|
|
|
|
require.Equal(t, resourcepb.WatchEvent_ADDED, event.Type)
|
|
|
|
|
require.Equal(t, "folderuid", event.Folder)
|
|
|
|
|
|
|
|
|
|
event = <-stream
|
|
|
|
|
require.Equal(t, "item3", event.Key.Name)
|
|
|
|
|
require.Equal(t, rv3, event.ResourceVersion)
|
|
|
|
|
require.Equal(t, resource.WatchEvent_ADDED, event.Type)
|
|
|
|
|
require.Equal(t, resourcepb.WatchEvent_ADDED, event.Type)
|
|
|
|
|
|
|
|
|
|
event = <-stream
|
|
|
|
|
require.Equal(t, "item2", event.Key.Name)
|
|
|
|
|
require.Equal(t, rv4, event.ResourceVersion)
|
|
|
|
|
require.Equal(t, resource.WatchEvent_MODIFIED, event.Type)
|
|
|
|
|
require.Equal(t, resourcepb.WatchEvent_MODIFIED, event.Type)
|
|
|
|
|
|
|
|
|
|
event = <-stream
|
|
|
|
|
require.Equal(t, "item1", event.Key.Name)
|
|
|
|
|
require.Equal(t, rv5, event.ResourceVersion)
|
|
|
|
|
require.Equal(t, resource.WatchEvent_DELETED, event.Type)
|
|
|
|
|
require.Equal(t, resourcepb.WatchEvent_DELETED, event.Type)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -224,31 +225,31 @@ func runTestIntegrationBackendGetResourceStats(t *testing.T, backend resource.St
|
|
|
|
|
return strings.Compare(a.Resource, b.Resource)
|
|
|
|
|
}
|
|
|
|
|
// Create resources across different namespaces/groups
|
|
|
|
|
_, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_ADDED,
|
|
|
|
|
_, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_ADDED,
|
|
|
|
|
WithNamespace(nsPrefix+"-ns1"),
|
|
|
|
|
WithGroup("group"),
|
|
|
|
|
WithResource("resource1"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item2", resource.WatchEvent_ADDED,
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item2", resourcepb.WatchEvent_ADDED,
|
|
|
|
|
WithNamespace(nsPrefix+"-ns1"),
|
|
|
|
|
WithGroup("group"),
|
|
|
|
|
WithResource("resource1"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item3", resource.WatchEvent_ADDED,
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item3", resourcepb.WatchEvent_ADDED,
|
|
|
|
|
WithNamespace(nsPrefix+"-ns1"),
|
|
|
|
|
WithGroup("group"),
|
|
|
|
|
WithResource("resource2"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item4", resource.WatchEvent_ADDED,
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item4", resourcepb.WatchEvent_ADDED,
|
|
|
|
|
WithNamespace(nsPrefix+"-ns2"),
|
|
|
|
|
WithGroup("group"),
|
|
|
|
|
WithResource("resource1"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item5", resource.WatchEvent_ADDED,
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item5", resourcepb.WatchEvent_ADDED,
|
|
|
|
|
WithNamespace(nsPrefix+"-ns2"),
|
|
|
|
|
WithGroup("group"),
|
|
|
|
|
WithResource("resource1"))
|
|
|
|
@@ -311,7 +312,7 @@ func runTestIntegrationBackendWatchWriteEvents(t *testing.T, backend resource.St
|
|
|
|
|
ctx := testutil.NewTestContext(t, time.Now().Add(5*time.Second))
|
|
|
|
|
|
|
|
|
|
// Create a few resources before initing the watch
|
|
|
|
|
_, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_ADDED, WithNamespace(nsPrefix+"-ns1"))
|
|
|
|
|
_, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_ADDED, WithNamespace(nsPrefix+"-ns1"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// Start the watch
|
|
|
|
@@ -319,7 +320,7 @@ func runTestIntegrationBackendWatchWriteEvents(t *testing.T, backend resource.St
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// Create one more event
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item2", resource.WatchEvent_ADDED, WithNamespace(nsPrefix+"-ns1"))
|
|
|
|
|
_, err = writeEvent(ctx, backend, "item2", resourcepb.WatchEvent_ADDED, WithNamespace(nsPrefix+"-ns1"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, "item2", (<-stream).Key.Name)
|
|
|
|
|
|
|
|
|
@@ -335,35 +336,35 @@ func runTestIntegrationBackendList(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
server := newServer(t, backend)
|
|
|
|
|
ns := nsPrefix + "-ns1"
|
|
|
|
|
// Create a few resources before starting the watch
|
|
|
|
|
rv1, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv1, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv1, int64(0))
|
|
|
|
|
rv2, err := writeEvent(ctx, backend, "item2", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv2, err := writeEvent(ctx, backend, "item2", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv2, rv1)
|
|
|
|
|
rv3, err := writeEvent(ctx, backend, "item3", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv3, err := writeEvent(ctx, backend, "item3", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv3, rv2)
|
|
|
|
|
rv4, err := writeEvent(ctx, backend, "item4", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv4, err := writeEvent(ctx, backend, "item4", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv4, rv3)
|
|
|
|
|
rv5, err := writeEvent(ctx, backend, "item5", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv5, err := writeEvent(ctx, backend, "item5", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv5, rv4)
|
|
|
|
|
rv6, err := writeEvent(ctx, backend, "item2", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rv6, err := writeEvent(ctx, backend, "item2", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv6, rv5)
|
|
|
|
|
rv7, err := writeEvent(ctx, backend, "item3", resource.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
rv7, err := writeEvent(ctx, backend, "item3", resourcepb.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv7, rv6)
|
|
|
|
|
rv8, err := writeEvent(ctx, backend, "item6", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv8, err := writeEvent(ctx, backend, "item6", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv8, rv7)
|
|
|
|
|
|
|
|
|
|
t.Run("fetch all latest", func(t *testing.T) {
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
|
},
|
|
|
|
@@ -383,10 +384,10 @@ func runTestIntegrationBackendList(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("list latest first page ", func(t *testing.T) {
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
|
},
|
|
|
|
@@ -404,10 +405,10 @@ func runTestIntegrationBackendList(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("list at revision", func(t *testing.T) {
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
ResourceVersion: rv4,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
|
},
|
|
|
|
@@ -424,11 +425,11 @@ func runTestIntegrationBackendList(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("fetch first page at revision with limit", func(t *testing.T) {
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
ResourceVersion: rv7,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
|
},
|
|
|
|
@@ -454,11 +455,11 @@ func runTestIntegrationBackendList(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
StartOffset: 2,
|
|
|
|
|
SortAscending: false,
|
|
|
|
|
}
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
NextPageToken: continueToken.String(),
|
|
|
|
|
Limit: 2,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
|
},
|
|
|
|
@@ -482,28 +483,28 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
ctx := testutil.NewTestContext(t, time.Now().Add(30*time.Second))
|
|
|
|
|
server := newServer(t, backend)
|
|
|
|
|
ns := nsPrefix + "-ns1"
|
|
|
|
|
rv1, _ := writeEvent(ctx, backend, "item1", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv1, _ := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.Greater(t, rv1, int64(0))
|
|
|
|
|
|
|
|
|
|
// add 5 events for item1 - should be saved to history
|
|
|
|
|
rvHistory1, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rvHistory1, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvHistory1, rv1)
|
|
|
|
|
rvHistory2, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rvHistory2, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvHistory2, rvHistory1)
|
|
|
|
|
rvHistory3, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rvHistory3, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvHistory3, rvHistory2)
|
|
|
|
|
rvHistory4, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rvHistory4, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvHistory4, rvHistory3)
|
|
|
|
|
rvHistory5, err := writeEvent(ctx, backend, "item1", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rvHistory5, err := writeEvent(ctx, backend, "item1", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvHistory5, rvHistory4)
|
|
|
|
|
|
|
|
|
|
t.Run("fetch history with different version matching", func(t *testing.T) {
|
|
|
|
|
baseKey := &resource.ResourceKey{
|
|
|
|
|
baseKey := &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
@@ -512,7 +513,7 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
request *resource.ListRequest
|
|
|
|
|
request *resourcepb.ListRequest
|
|
|
|
|
expectedVersions []int64
|
|
|
|
|
expectedValues []string
|
|
|
|
|
minExpectedHeadRV int64
|
|
|
|
@@ -521,12 +522,12 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "NotOlderThan with rv1 (ASC order)",
|
|
|
|
|
request: &resource.ListRequest{
|
|
|
|
|
request: &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
ResourceVersion: rv1,
|
|
|
|
|
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: baseKey,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@@ -538,12 +539,12 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "NotOlderThan with rv=0 (ASC order)",
|
|
|
|
|
request: &resource.ListRequest{
|
|
|
|
|
request: &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
ResourceVersion: 0,
|
|
|
|
|
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: baseKey,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@@ -555,10 +556,10 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "ResourceVersionMatch_Unset (DESC order)",
|
|
|
|
|
request: &resource.ListRequest{
|
|
|
|
|
request: &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: baseKey,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@@ -597,12 +598,12 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
// Test pagination for NotOlderThan (second page)
|
|
|
|
|
t.Run("second page with NotOlderThan", func(t *testing.T) {
|
|
|
|
|
// Get first page
|
|
|
|
|
firstRequest := &resource.ListRequest{
|
|
|
|
|
firstRequest := &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
ResourceVersion: rv1,
|
|
|
|
|
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resource.ListOptions{Key: baseKey},
|
|
|
|
|
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resourcepb.ListOptions{Key: baseKey},
|
|
|
|
|
}
|
|
|
|
|
firstPageRes, err := server.List(ctx, firstRequest)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
@@ -612,13 +613,13 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// Get second page
|
|
|
|
|
secondPageRes, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
secondPageRes, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Limit: 3,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
ResourceVersion: rv1,
|
|
|
|
|
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
NextPageToken: continueToken.String(),
|
|
|
|
|
Options: &resource.ListOptions{Key: baseKey},
|
|
|
|
|
Options: &resourcepb.ListOptions{Key: baseKey},
|
|
|
|
|
})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Nil(t, secondPageRes.Error)
|
|
|
|
@@ -639,12 +640,12 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
StartOffset: 2,
|
|
|
|
|
SortAscending: false,
|
|
|
|
|
}
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
NextPageToken: continueToken.String(),
|
|
|
|
|
Limit: 2,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
@@ -665,7 +666,7 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
t.Run("paginated history with NotOlderThan returns items in ascending order", func(t *testing.T) {
|
|
|
|
|
// Create 10 versions of a resource to test pagination
|
|
|
|
|
ns2 := nsPrefix + "-ns2"
|
|
|
|
|
resourceKey := &resource.ResourceKey{
|
|
|
|
|
resourceKey := &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns2,
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
@@ -675,13 +676,13 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
var resourceVersions []int64
|
|
|
|
|
|
|
|
|
|
// First create the initial resource
|
|
|
|
|
initialRV, err := writeEvent(ctx, backend, "paged-item", resource.WatchEvent_ADDED, WithNamespace(ns2))
|
|
|
|
|
initialRV, err := writeEvent(ctx, backend, "paged-item", resourcepb.WatchEvent_ADDED, WithNamespace(ns2))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
resourceVersions = append(resourceVersions, initialRV)
|
|
|
|
|
|
|
|
|
|
// Create 9 more versions with modifications
|
|
|
|
|
for i := 0; i < 9; i++ {
|
|
|
|
|
rv, err := writeEvent(ctx, backend, "paged-item", resource.WatchEvent_MODIFIED, WithNamespace(ns2))
|
|
|
|
|
rv, err := writeEvent(ctx, backend, "paged-item", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns2))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
resourceVersions = append(resourceVersions, rv)
|
|
|
|
|
}
|
|
|
|
@@ -701,16 +702,16 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
{pageNumber: 4, pageSize: 1, startToken: ""}, // Will be set in the test - last page with remaining item
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var allItems []*resource.ResourceWrapper
|
|
|
|
|
var allItems []*resourcepb.ResourceWrapper
|
|
|
|
|
|
|
|
|
|
// Request first page with NotOlderThan and ResourceVersion=0 (should start from oldest)
|
|
|
|
|
for i, page := range pages {
|
|
|
|
|
req := &resource.ListRequest{
|
|
|
|
|
req := &resourcepb.ListRequest{
|
|
|
|
|
Limit: int64(page.pageSize),
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
ResourceVersion: 0,
|
|
|
|
|
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: resourceKey,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
@@ -781,17 +782,17 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
|
|
|
|
|
t.Run("fetch history with deleted item", func(t *testing.T) {
|
|
|
|
|
// Create a resource and delete it
|
|
|
|
|
rv, err := writeEvent(ctx, backend, "deleted-item", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv, err := writeEvent(ctx, backend, "deleted-item", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
rvDeleted, err := writeEvent(ctx, backend, "deleted-item", resource.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
rvDeleted, err := writeEvent(ctx, backend, "deleted-item", resourcepb.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvDeleted, rv)
|
|
|
|
|
|
|
|
|
|
// Fetch history for the deleted item
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
@@ -806,25 +807,25 @@ func runTestIntegrationBackendListHistory(t *testing.T, backend resource.Storage
|
|
|
|
|
|
|
|
|
|
t.Run("fetch history with recreated item", func(t *testing.T) {
|
|
|
|
|
// Create a resource and delete it
|
|
|
|
|
rv, err := writeEvent(ctx, backend, "deleted-item", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv, err := writeEvent(ctx, backend, "deleted-item", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
rvDeleted, err := writeEvent(ctx, backend, "deleted-item", resource.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
rvDeleted, err := writeEvent(ctx, backend, "deleted-item", resourcepb.WatchEvent_DELETED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rvDeleted, rv)
|
|
|
|
|
|
|
|
|
|
// Create a few more versions after deletion
|
|
|
|
|
rv1, err := writeEvent(ctx, backend, "deleted-item", resource.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
rv1, err := writeEvent(ctx, backend, "deleted-item", resourcepb.WatchEvent_ADDED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv1, rvDeleted)
|
|
|
|
|
rv2, err := writeEvent(ctx, backend, "deleted-item", resource.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
rv2, err := writeEvent(ctx, backend, "deleted-item", resourcepb.WatchEvent_MODIFIED, WithNamespace(ns))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv2, rv1)
|
|
|
|
|
|
|
|
|
|
// Fetch history for the deleted item
|
|
|
|
|
res, err := server.List(ctx, &resource.ListRequest{
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
res, err := server.List(ctx, &resourcepb.ListRequest{
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "group",
|
|
|
|
|
Resource: "resource",
|
|
|
|
@@ -854,26 +855,26 @@ func runTestIntegrationBackendListHistoryErrorReporting(t *testing.T, backend re
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
start := time.Now()
|
|
|
|
|
origRv, _ := writeEvent(ctx, backend, name, resource.WatchEvent_ADDED, WithNamespace(ns), WithGroup(group), WithResource(resourceName))
|
|
|
|
|
origRv, _ := writeEvent(ctx, backend, name, resourcepb.WatchEvent_ADDED, WithNamespace(ns), WithGroup(group), WithResource(resourceName))
|
|
|
|
|
require.Greater(t, origRv, int64(0))
|
|
|
|
|
|
|
|
|
|
const events = 500
|
|
|
|
|
prevRv := origRv
|
|
|
|
|
for i := 0; i < events; i++ {
|
|
|
|
|
rv, err := writeEvent(ctx, backend, name, resource.WatchEvent_MODIFIED, WithNamespace(ns), WithGroup(group), WithResource(resourceName))
|
|
|
|
|
rv, err := writeEvent(ctx, backend, name, resourcepb.WatchEvent_MODIFIED, WithNamespace(ns), WithGroup(group), WithResource(resourceName))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Greater(t, rv, prevRv)
|
|
|
|
|
prevRv = rv
|
|
|
|
|
}
|
|
|
|
|
t.Log("added events in ", time.Since(start))
|
|
|
|
|
|
|
|
|
|
req := &resource.ListRequest{
|
|
|
|
|
req := &resourcepb.ListRequest{
|
|
|
|
|
Limit: 2 * events,
|
|
|
|
|
Source: resource.ListRequest_HISTORY,
|
|
|
|
|
Source: resourcepb.ListRequest_HISTORY,
|
|
|
|
|
ResourceVersion: origRv,
|
|
|
|
|
VersionMatchV2: resource.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resource.ListOptions{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
VersionMatchV2: resourcepb.ResourceVersionMatchV2_NotOlderThan,
|
|
|
|
|
Options: &resourcepb.ListOptions{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: group,
|
|
|
|
|
Resource: resourceName,
|
|
|
|
@@ -903,16 +904,15 @@ func runTestIntegrationBlobSupport(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
ns := nsPrefix + "-ns1"
|
|
|
|
|
|
|
|
|
|
t.Run("put and fetch blob", func(t *testing.T) {
|
|
|
|
|
key := &resource.ResourceKey{
|
|
|
|
|
key := &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: ns,
|
|
|
|
|
Group: "g",
|
|
|
|
|
Resource: "r",
|
|
|
|
|
Name: "n",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b1, err := server.PutBlob(ctx, &resource.PutBlobRequest{
|
|
|
|
|
b1, err := server.PutBlob(ctx, &resourcepb.PutBlobRequest{
|
|
|
|
|
Resource: key,
|
|
|
|
|
Method: resource.PutBlobRequest_GRPC,
|
|
|
|
|
Method: resourcepb.PutBlobRequest_GRPC,
|
|
|
|
|
ContentType: "plain/text",
|
|
|
|
|
Value: []byte("hello 11111"),
|
|
|
|
|
})
|
|
|
|
@@ -920,9 +920,9 @@ func runTestIntegrationBlobSupport(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
require.Nil(t, b1.Error)
|
|
|
|
|
require.Equal(t, "c894ae57bd227b8f8c63f38a2ddf458b", b1.Hash)
|
|
|
|
|
|
|
|
|
|
b2, err := server.PutBlob(ctx, &resource.PutBlobRequest{
|
|
|
|
|
b2, err := server.PutBlob(ctx, &resourcepb.PutBlobRequest{
|
|
|
|
|
Resource: key,
|
|
|
|
|
Method: resource.PutBlobRequest_GRPC,
|
|
|
|
|
Method: resourcepb.PutBlobRequest_GRPC,
|
|
|
|
|
ContentType: "plain/text",
|
|
|
|
|
Value: []byte("hello 22222"), // the most recent
|
|
|
|
|
})
|
|
|
|
@@ -950,19 +950,19 @@ func runTestIntegrationBlobSupport(t *testing.T, backend resource.StorageBackend
|
|
|
|
|
obj.SetKind("Test")
|
|
|
|
|
val, err := obj.MarshalJSON()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
out, err := server.Create(ctx, &resource.CreateRequest{Key: key, Value: val})
|
|
|
|
|
out, err := server.Create(ctx, &resourcepb.CreateRequest{Key: key, Value: val})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Nil(t, out.Error)
|
|
|
|
|
require.True(t, out.ResourceVersion > 0)
|
|
|
|
|
|
|
|
|
|
// The server (not store!) will lookup the saved annotation and return the correct payload
|
|
|
|
|
res, err := server.GetBlob(ctx, &resource.GetBlobRequest{Resource: key})
|
|
|
|
|
res, err := server.GetBlob(ctx, &resourcepb.GetBlobRequest{Resource: key})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Nil(t, out.Error)
|
|
|
|
|
require.Contains(t, string(res.Value), "hello 22222")
|
|
|
|
|
|
|
|
|
|
// But we can still get an older version with an explicit UID
|
|
|
|
|
res, err = server.GetBlob(ctx, &resource.GetBlobRequest{Resource: key, Uid: b1.Uid})
|
|
|
|
|
res, err = server.GetBlob(ctx, &resourcepb.GetBlobRequest{Resource: key, Uid: b1.Uid})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Nil(t, out.Error)
|
|
|
|
|
require.Contains(t, string(res.Value), "hello 11111")
|
|
|
|
@@ -981,8 +981,8 @@ func runTestIntegrationBackendCreateNewResource(t *testing.T, backend resource.S
|
|
|
|
|
ns := nsPrefix + "-create-resource"
|
|
|
|
|
ctx = request.WithNamespace(ctx, ns)
|
|
|
|
|
|
|
|
|
|
request := &resource.CreateRequest{
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
request := &resourcepb.CreateRequest{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: "default",
|
|
|
|
|
Group: "test.grafana",
|
|
|
|
|
Resource: "Test",
|
|
|
|
@@ -1064,7 +1064,7 @@ type WriteEventOptions struct {
|
|
|
|
|
Value []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeEvent(ctx context.Context, store resource.StorageBackend, name string, action resource.WatchEvent_Type, opts ...WriteEventOption) (int64, error) {
|
|
|
|
|
func writeEvent(ctx context.Context, store resource.StorageBackend, name string, action resourcepb.WatchEvent_Type, opts ...WriteEventOption) (int64, error) {
|
|
|
|
|
// Default options
|
|
|
|
|
options := WriteEventOptions{
|
|
|
|
|
Namespace: "namespace",
|
|
|
|
@@ -1087,7 +1087,7 @@ func writeEvent(ctx context.Context, store resource.StorageBackend, name string,
|
|
|
|
|
"namespace": options.Namespace,
|
|
|
|
|
},
|
|
|
|
|
"spec": map[string]any{
|
|
|
|
|
"value": name + " " + resource.WatchEvent_Type_name[int32(action)],
|
|
|
|
|
"value": name + " " + resourcepb.WatchEvent_Type_name[int32(action)],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
@@ -1106,7 +1106,7 @@ func writeEvent(ctx context.Context, store resource.StorageBackend, name string,
|
|
|
|
|
return store.WriteEvent(ctx, resource.WriteEvent{
|
|
|
|
|
Type: action,
|
|
|
|
|
Value: options.Value,
|
|
|
|
|
Key: &resource.ResourceKey{
|
|
|
|
|
Key: &resourcepb.ResourceKey{
|
|
|
|
|
Namespace: options.Namespace,
|
|
|
|
|
Group: options.Group,
|
|
|
|
|
Resource: options.Resource,
|
|
|
|
|