Skip to content

Commit e75e7d7

Browse files
authored
[Feature] [Platform] Meta Integration Tests (#1966)
1 parent 9a477a3 commit e75e7d7

File tree

10 files changed

+221
-4
lines changed

10 files changed

+221
-4
lines changed

.golangci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ linters-settings:
187187
pkg: github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/constants
188188
- alias: utilConstants
189189
pkg: github.com/arangodb/kube-arangodb/pkg/util/constants
190+
- alias: tcache
191+
pkg: github.com/arangodb/kube-arangodb/pkg/util/tests/cache
190192
- alias: apps
191193
pkg: k8s.io/api/apps/v1
192194
- alias: batch

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- (Bugfix) Enable Platform Operator on EE Chart
1414
- (Feature) Improve GRPC JSON Handling
1515
- (Bugfix) Fix Operator Pod Resources
16+
- (Feature) (Platform) MetaV1 Integration Tests
1617

1718
## [1.3.0](https://github.com/arangodb/kube-arangodb/tree/1.3.0) (2025-08-01)
1819
- (Feature) (Platform) Storage Debug

integrations/meta/v1/impl.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,18 @@ func New(ctx context.Context, cfg Configuration) (svc.Handler, error) {
4747
}
4848

4949
func newInternal(ctx context.Context, cfg Configuration) (*implementation, error) {
50+
return newInternalWithRemoteCache(ctx, cfg, cache.NewRemoteCacheWithTTL[*Object](cfg.KVCollection(cfg.Endpoint, "_system", "_meta_store"), cfg.TTL))
51+
}
52+
53+
func newInternalWithRemoteCache(ctx context.Context, cfg Configuration, c cache.RemoteCache[*Object]) (*implementation, error) {
5054
if err := cfg.Validate(); err != nil {
5155
return nil, err
5256
}
5357

5458
obj := &implementation{
5559
cfg: cfg,
5660
ctx: ctx,
57-
cache: cache.NewRemoteCacheWithTTL[*Object](cfg.KVCollection(cfg.Endpoint, "_system", "_meta_store"), cfg.TTL),
61+
cache: c,
5862
}
5963

6064
return obj, nil

integrations/meta/v1/impl_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package v1
22+
23+
import (
24+
"encoding/json"
25+
"testing"
26+
27+
"github.com/stretchr/testify/require"
28+
)
29+
30+
var existing_json_data = `{"_key":"genai.all_project_names","_id":"_meta_store/genai.all_project_names","_rev":"_j8TwrTm--_","meta":{"updatedAt":"2025-07-07T15:13:09Z"},"object":{"Object":{"type_url":"type.googleapis.com/arangodb_platform_internal.metadata_store.GenAiProjectNames","value":"ChV0ZXN0X3Byb2plY3RfNmVhYWM3MjM="}}}`
31+
32+
func Test(t *testing.T) {
33+
var o Object
34+
err := json.Unmarshal([]byte(existing_json_data), &o)
35+
require.NoError(t, err)
36+
37+
data, err := json.Marshal(&o)
38+
require.NoError(t, err)
39+
40+
require.Equal(t, existing_json_data, string(data))
41+
}

integrations/meta/v1/object.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
type Object struct {
3434
Key string `json:"_key,omitempty"`
35+
ID string `json:"_id,omitempty"`
3536
Rev *string `json:"_rev,omitempty"`
3637

3738
Meta *ObjectMeta `json:"meta,omitempty"`

integrations/meta/v1/service_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
pbMetaV1 "github.com/arangodb/kube-arangodb/integrations/meta/v1/definition"
3131
"github.com/arangodb/kube-arangodb/pkg/util"
3232
"github.com/arangodb/kube-arangodb/pkg/util/svc"
33+
tcache "github.com/arangodb/kube-arangodb/pkg/util/tests/cache"
3334
"github.com/arangodb/kube-arangodb/pkg/util/tests/tgrpc"
3435
)
3536

@@ -57,7 +58,7 @@ func Test_Types(t *testing.T) {
5758
}
5859

5960
func Handler(t *testing.T, ctx context.Context, mods ...util.ModR[Configuration]) svc.Handler {
60-
handler, err := New(ctx, NewConfiguration().With(mods...))
61+
handler, err := newInternalWithRemoteCache(ctx, NewConfiguration().With(mods...), tcache.NewRemoteCache[*Object]())
6162
require.NoError(t, err)
6263

6364
return handler

pkg/util/list.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,21 @@ func UniqueList[A comparable](in []A) []A {
161161
return r
162162
}
163163

164+
func BatchList[A any](size int, in []A) [][]A {
165+
ret := make([][]A, 0, len(in)/size+1)
166+
167+
for id := 0; id < len(in); id += size {
168+
end := id + size
169+
if limit := len(in); end > limit {
170+
end = limit
171+
}
172+
173+
ret = append(ret, in[id:end])
174+
}
175+
176+
return ret
177+
}
178+
164179
func FormatListErr[A, B any](in []A, format func(A) (B, error)) ([]B, error) {
165180
var r = make([]B, len(in))
166181

pkg/util/list_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,19 @@ func Test_AppendAfter(t *testing.T) {
9191
}, 4)
9292
require.Equal(t, []int{1, 3, 2, 4}, elements)
9393
}
94+
95+
func Test_Batcher(t *testing.T) {
96+
v := make([]int, 17)
97+
for id := range v {
98+
v[id] = id
99+
}
100+
101+
res := BatchList(16, v)
102+
require.Len(t, res, 2)
103+
104+
require.Len(t, res[0], 16)
105+
require.Len(t, res[1], 1)
106+
107+
require.Equal(t, v[0:16], res[0])
108+
require.Equal(t, v[16:], res[1])
109+
}

pkg/util/next.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -20,8 +20,39 @@
2020

2121
package util
2222

23-
import "context"
23+
import (
24+
"context"
25+
"io"
26+
"sync"
27+
)
2428

2529
type NextIterator[T any] interface {
2630
Next(ctx context.Context) (T, error)
2731
}
32+
33+
func NewStaticNextIterator[T any](objs ...T) NextIterator[T] {
34+
return &staticNextIterator[T]{
35+
objects: objs,
36+
}
37+
}
38+
39+
type staticNextIterator[T any] struct {
40+
lock sync.Mutex
41+
42+
id int
43+
44+
objects []T
45+
}
46+
47+
func (s *staticNextIterator[T]) Next(ctx context.Context) (T, error) {
48+
s.lock.Lock()
49+
defer s.lock.Unlock()
50+
51+
if s.id >= len(s.objects) {
52+
return Default[T](), io.EOF
53+
}
54+
55+
obj := s.objects[s.id]
56+
s.id++
57+
return obj, nil
58+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package cache
22+
23+
import (
24+
"context"
25+
"encoding/json"
26+
goStrings "strings"
27+
"sync"
28+
29+
"github.com/arangodb/kube-arangodb/pkg/util"
30+
"github.com/arangodb/kube-arangodb/pkg/util/cache"
31+
)
32+
33+
func NewRemoteCache[T cache.RemoteCacheObject]() cache.RemoteCache[T] {
34+
return &localRemoteCache[T]{
35+
objects: map[string]json.RawMessage{},
36+
}
37+
}
38+
39+
type localRemoteCache[T cache.RemoteCacheObject] struct {
40+
lock sync.Mutex
41+
42+
objects map[string]json.RawMessage
43+
}
44+
45+
func (l *localRemoteCache[T]) Put(ctx context.Context, key string, obj T) error {
46+
l.lock.Lock()
47+
defer l.lock.Unlock()
48+
49+
data, err := json.Marshal(obj)
50+
if err != nil {
51+
return err
52+
}
53+
54+
l.objects[key] = data
55+
return nil
56+
}
57+
58+
func (l *localRemoteCache[T]) Get(ctx context.Context, key string) (T, bool, error) {
59+
l.lock.Lock()
60+
defer l.lock.Unlock()
61+
62+
data, ok := l.objects[key]
63+
if !ok {
64+
return util.Default[T](), false, nil
65+
}
66+
67+
var obj T
68+
69+
if err := json.Unmarshal(data, &obj); err != nil {
70+
return obj, false, err
71+
}
72+
73+
return obj, true, nil
74+
}
75+
76+
func (l *localRemoteCache[T]) Remove(ctx context.Context, key string) (bool, error) {
77+
l.lock.Lock()
78+
defer l.lock.Unlock()
79+
80+
if _, ok := l.objects[key]; ok {
81+
delete(l.objects, key)
82+
return true, nil
83+
}
84+
85+
return false, nil
86+
}
87+
88+
func (l *localRemoteCache[T]) Invalidate(ctx context.Context, key string) {
89+
l.lock.Lock()
90+
defer l.lock.Unlock()
91+
92+
// Nothing to do with reload
93+
}
94+
95+
func (l *localRemoteCache[T]) List(ctx context.Context, size int, prefix string) (util.NextIterator[[]string], error) {
96+
l.lock.Lock()
97+
defer l.lock.Unlock()
98+
99+
keys := util.MapKeys(l.objects)
100+
keys = util.FilterList(keys, func(key string) bool {
101+
return goStrings.HasPrefix(key, prefix)
102+
})
103+
104+
return util.NewStaticNextIterator(util.BatchList(size, keys)...), nil
105+
}

0 commit comments

Comments
 (0)