Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e75e7d7

Browse files
[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月07日T15: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+
}

‎pkg/util/tests/cache/remote_cache.go‎

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)

AltStyle によって変換されたページ (->オリジナル) /