From 82f1bb0584b2855d5ab3bd1a07f8674d19325647 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Mon, 8 Aug 2022 10:14:58 -0400 Subject: [PATCH] [storagetest] Build out package for more flexible test cases The storagetest package exists to enable testing the usage of storage extensions. This PR extends and cleans up the package so that it can be used for a far larger set of test cases. --- extension/storage/go.mod | 1 - extension/storage/go.sum | 1 - extension/storage/storagetest/client.go | 170 ++++++++++++++++++ extension/storage/storagetest/extension.go | 103 +++++++++++ .../storage/storagetest/extension_test.go | 95 ++++++++++ .../storagetest/{storage.go => host.go} | 44 ++--- extension/storage/storagetest/host_test.go | 104 +++++++++++ extension/storage/storagetest/storage_test.go | 29 --- pkg/stanza/adapter/mocks_test.go | 69 +------ pkg/stanza/adapter/storage_test.go | 9 +- pkg/stanza/go.mod | 1 - pkg/stanza/go.sum | 3 - processor/logstransformprocessor/go.sum | 1 - receiver/filelogreceiver/go.mod | 2 - receiver/filelogreceiver/go.sum | 4 - receiver/filelogreceiver/storage_test.go | 6 +- receiver/journaldreceiver/go.sum | 1 - receiver/otlpjsonfilereceiver/go.sum | 1 - receiver/syslogreceiver/go.sum | 1 - receiver/tcplogreceiver/go.sum | 1 - receiver/udplogreceiver/go.sum | 1 - receiver/windowseventlogreceiver/go.sum | 1 - unreleased/storagetest-memory-extension.yaml | 16 ++ 23 files changed, 523 insertions(+), 141 deletions(-) create mode 100644 extension/storage/storagetest/client.go create mode 100644 extension/storage/storagetest/extension.go create mode 100644 extension/storage/storagetest/extension_test.go rename extension/storage/storagetest/{storage.go => host.go} (51%) create mode 100644 extension/storage/storagetest/host_test.go delete mode 100644 extension/storage/storagetest/storage_test.go create mode 100755 unreleased/storagetest-memory-extension.yaml diff --git a/extension/storage/go.mod b/extension/storage/go.mod index ae11e564d87f..f1129e7a588f 100644 --- a/extension/storage/go.mod +++ b/extension/storage/go.mod @@ -16,7 +16,6 @@ require ( ) require ( - github.com/benbjohnson/clock v1.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/extension/storage/go.sum b/extension/storage/go.sum index 3a46a401dadf..a1f95ddf594f 100644 --- a/extension/storage/go.sum +++ b/extension/storage/go.sum @@ -18,7 +18,6 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+ github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= diff --git a/extension/storage/storagetest/client.go b/extension/storage/storagetest/client.go new file mode 100644 index 000000000000..32d7cf2c8ebd --- /dev/null +++ b/extension/storage/storagetest/client.go @@ -0,0 +1,170 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package storagetest // import "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/storagetest" + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "sync" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/extension/experimental/storage" +) + +var ( + errClientClosed = errors.New("client closed") +) + +type TestClient struct { + cache map[string][]byte + cacheMux sync.Mutex + + kind component.Kind + id config.ComponentID + name string + + storageFile string + + closed bool +} + +// NewInMemoryClient creates a storage.Client that functions as a map[string][]byte +// This is useful for tests that do not involve collector restart behavior. +func NewInMemoryClient(kind component.Kind, id config.ComponentID, name string) *TestClient { + return &TestClient{ + cache: make(map[string][]byte), + kind: kind, + id: id, + name: name, + } +} + +// NewFileBackedClient creates a storage.Client that will load previous +// storage contents upon creation and save storage contents when closed. +// It also has metadata which may be used to validate test expectations. +func NewFileBackedClient(kind component.Kind, id config.ComponentID, name string, storageDir string) *TestClient { + client := NewInMemoryClient(kind, id, name) + + client.storageFile = filepath.Join(storageDir, fmt.Sprintf("%d_%s_%s_%s", kind, id.Type(), id.Name(), name)) + + // Attempt to load previous storage content + contents, err := os.ReadFile(client.storageFile) + if err != nil { + // Assume no previous storage content + return client + } + + previousCache := make(map[string][]byte) + if err := json.Unmarshal(contents, &previousCache); err != nil { + // Assume no previous storage content + return client + } + + client.cache = previousCache + return client +} + +func (p *TestClient) Get(_ context.Context, key string) ([]byte, error) { + p.cacheMux.Lock() + defer p.cacheMux.Unlock() + if p.closed { + return nil, errClientClosed + } + + return p.cache[key], nil +} + +func (p *TestClient) Set(_ context.Context, key string, value []byte) error { + p.cacheMux.Lock() + defer p.cacheMux.Unlock() + if p.closed { + return errClientClosed + } + + p.cache[key] = value + return nil +} + +func (p *TestClient) Delete(_ context.Context, key string) error { + p.cacheMux.Lock() + defer p.cacheMux.Unlock() + if p.closed { + return errClientClosed + } + + delete(p.cache, key) + return nil +} + +func (p *TestClient) Batch(_ context.Context, ops ...storage.Operation) error { + p.cacheMux.Lock() + defer p.cacheMux.Unlock() + if p.closed { + return errClientClosed + } + + for _, op := range ops { + switch op.Type { + case storage.Get: + op.Value = p.cache[op.Key] + case storage.Set: + p.cache[op.Key] = op.Value + case storage.Delete: + delete(p.cache, op.Key) + default: + return errors.New("wrong operation type") + } + } + + return nil +} + +func (p *TestClient) Close(_ context.Context) error { + p.cacheMux.Lock() + defer p.cacheMux.Unlock() + + p.closed = true + + if p.storageFile == "" { + return nil + } + + contents, err := json.Marshal(p.cache) + if err != nil { + return err + } + + return os.WriteFile(p.storageFile, contents, os.FileMode(0600)) +} + +// Kind of component that is using the storage client +func (p *TestClient) Kind() component.Kind { + return p.kind +} + +// ID of component that is using the storage client +func (p *TestClient) ID() config.ComponentID { + return p.id +} + +// Name assigned to the storage client +func (p *TestClient) Name() string { + return p.name +} diff --git a/extension/storage/storagetest/extension.go b/extension/storage/storagetest/extension.go new file mode 100644 index 000000000000..3c1e4232afef --- /dev/null +++ b/extension/storage/storagetest/extension.go @@ -0,0 +1,103 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package storagetest // import "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/storagetest" + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/extension/experimental/storage" +) + +var testStorageType config.Type = "test_storage" + +// TestStorage is an in memory storage extension designed for testing +type TestStorage struct { + config.ExtensionSettings + storageDir string + clients []*TestClient +} + +// Ensure this storage extension implements the appropriate interface +var _ storage.Extension = (*TestStorage)(nil) + +// NewInMemoryStorageExtension creates a TestStorage extension +func NewInMemoryStorageExtension(name string) *TestStorage { + return &TestStorage{ + ExtensionSettings: config.NewExtensionSettings( + config.NewComponentIDWithName(testStorageType, name), + ), + clients: []*TestClient{}, + } +} + +// NewFileBackedStorageExtension creates a TestStorage extension +func NewFileBackedStorageExtension(name string, storageDir string) *TestStorage { + return &TestStorage{ + ExtensionSettings: config.NewExtensionSettings( + config.NewComponentIDWithName(testStorageType, name), + ), + storageDir: storageDir, + } +} + +// Start does nothing +func (s *TestStorage) Start(context.Context, component.Host) error { + return nil +} + +// Shutdown does nothing +func (s *TestStorage) Shutdown(ctx context.Context) error { + return nil +} + +// GetClient returns a storage client for an individual component +func (s *TestStorage) GetClient(_ context.Context, kind component.Kind, ent config.ComponentID, name string) (storage.Client, error) { + if s.storageDir == "" { + return NewInMemoryClient(kind, ent, name), nil + } + return NewFileBackedClient(kind, ent, name, s.storageDir), nil +} + +var nonStorageType config.Type = "non_storage" + +// NonStorage is useful for testing expected behaviors that involve +// non-storage extensions +type NonStorage struct { + config.ExtensionSettings +} + +// Ensure this extension implements the appropriate interface +var _ component.Extension = (*NonStorage)(nil) + +// NewNonStorageExtension creates a NonStorage extension +func NewNonStorageExtension(name string) *NonStorage { + return &NonStorage{ + ExtensionSettings: config.NewExtensionSettings( + config.NewComponentIDWithName(nonStorageType, name), + ), + } +} + +// Start does nothing +func (ns *NonStorage) Start(context.Context, component.Host) error { + return nil +} + +// Shutdown does nothing +func (ns *NonStorage) Shutdown(context.Context) error { + return nil +} diff --git a/extension/storage/storagetest/extension_test.go b/extension/storage/storagetest/extension_test.go new file mode 100644 index 000000000000..780aa0438658 --- /dev/null +++ b/extension/storage/storagetest/extension_test.go @@ -0,0 +1,95 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package storagetest + +import ( + "context" + "testing" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/extension/experimental/storage" + + "github.com/stretchr/testify/require" +) + +func TestInMemoryLifecycle(t *testing.T) { + ext := NewInMemoryStorageExtension("test") + require.Equal(t, config.NewComponentIDWithName(testStorageType, "test"), ext.ID()) + runExtensionLifecycle(t, ext, false) +} + +func TestFileBackedLifecycle(t *testing.T) { + dir := t.TempDir() + ext := NewFileBackedStorageExtension("test", dir) + require.Equal(t, config.NewComponentIDWithName(testStorageType, "test"), ext.ID()) + runExtensionLifecycle(t, ext, true) +} + +func runExtensionLifecycle(t *testing.T, ext storage.Extension, expectPersistence bool) { + ctx := context.Background() + require.NoError(t, ext.Start(ctx, componenttest.NewNopHost())) + + clientOne, err := ext.GetClient(ctx, component.KindProcessor, config.NewComponentID("foo"), "client_one") + require.NoError(t, err) + + // Write a value, confirm it is saved + require.NoError(t, clientOne.Set(ctx, "foo", []byte("bar"))) + fooVal, err := clientOne.Get(ctx, "foo") + require.NoError(t, err) + require.Equal(t, []byte("bar"), fooVal) + + // Delete the value, confirm it is deleted + require.NoError(t, clientOne.Delete(ctx, "foo")) + fooVal, err = clientOne.Get(ctx, "foo") + require.NoError(t, err) + require.Nil(t, fooVal) + + // Write a new value, confirm it is saved + require.NoError(t, clientOne.Set(ctx, "foo2", []byte("bar2"))) + fooVal, err = clientOne.Get(ctx, "foo2") + require.NoError(t, err) + require.Equal(t, []byte("bar2"), fooVal) + + // Close first client + require.NoError(t, clientOne.Close(ctx)) + + // Create new client to test persistence + clientTwo, err := ext.GetClient(ctx, component.KindProcessor, config.NewComponentID("foo"), "client_one") + require.NoError(t, err) + + // Check if the value is accessible from another client + fooVal, err = clientTwo.Get(ctx, "foo2") + require.NoError(t, err) + if expectPersistence { + require.Equal(t, []byte("bar2"), fooVal) + } else { + require.Nil(t, fooVal) + } + + // Perform some additional operations + set := storage.SetOperation("foo3", []byte("bar3")) + get := storage.GetOperation("foo3") + delete := storage.DeleteOperation("foo3") + getNil := storage.GetOperation("foo3") + require.NoError(t, clientTwo.Batch(ctx, set, get, delete, getNil)) + require.Equal(t, get.Value, []byte("bar3")) + require.Nil(t, getNil.Value) + + // Cleanup + require.NoError(t, clientTwo.Close(ctx)) + require.NoError(t, ext.Shutdown(ctx)) +} diff --git a/extension/storage/storagetest/storage.go b/extension/storage/storagetest/host.go similarity index 51% rename from extension/storage/storagetest/storage.go rename to extension/storage/storagetest/host.go index b6f622ac826f..297c8fc4b4fc 100644 --- a/extension/storage/storagetest/storage.go +++ b/extension/storage/storagetest/host.go @@ -15,16 +15,9 @@ package storagetest // import "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/storagetest" import ( - "context" - "testing" - "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/extension/experimental/storage" - "go.uber.org/zap/zaptest" - - "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/filestorage" ) type StorageHost struct { @@ -32,32 +25,31 @@ type StorageHost struct { extensions map[config.ComponentID]component.Extension } -func (h StorageHost) GetExtensions() map[config.ComponentID]component.Extension { - return h.extensions -} - -func NewStorageHost(t *testing.T, directory string, extensionNames ...string) StorageHost { - h := StorageHost{ +func NewStorageHost() *StorageHost { + return &StorageHost{ Host: componenttest.NewNopHost(), extensions: make(map[config.ComponentID]component.Extension), } +} - for _, name := range extensionNames { - h.extensions[newTestEntity(name)] = NewTestExtension(t, directory) - } +func (h *StorageHost) WithInMemoryStorageExtension(name string) *StorageHost { + ext := NewInMemoryStorageExtension(name) + h.extensions[ext.ID()] = ext + return h +} + +func (h *StorageHost) WithFileBackedStorageExtension(name, storageDir string) *StorageHost { + ext := NewFileBackedStorageExtension(name, storageDir) + h.extensions[ext.ID()] = ext return h } -func NewTestExtension(t *testing.T, directory string) storage.Extension { - f := filestorage.NewFactory() - cfg := f.CreateDefaultConfig().(*filestorage.Config) - cfg.Directory = directory - params := component.ExtensionCreateSettings{TelemetrySettings: component.TelemetrySettings{Logger: zaptest.NewLogger(t)}} - extension, _ := f.CreateExtension(context.Background(), params, cfg) - se, _ := extension.(storage.Extension) - return se +func (h *StorageHost) WithNonStorageExtension(name string) *StorageHost { + ext := NewNonStorageExtension(name) + h.extensions[ext.ID()] = ext + return h } -func newTestEntity(name string) config.ComponentID { - return config.NewComponentIDWithName("nop", name) +func (h *StorageHost) GetExtensions() map[config.ComponentID]component.Extension { + return h.extensions } diff --git a/extension/storage/storagetest/host_test.go b/extension/storage/storagetest/host_test.go new file mode 100644 index 000000000000..ce244a138826 --- /dev/null +++ b/extension/storage/storagetest/host_test.go @@ -0,0 +1,104 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package storagetest + +import ( + "testing" + + "go.opentelemetry.io/collector/config" + + "github.com/stretchr/testify/require" +) + +func TestStorageHostWithNone(t *testing.T) { + require.Equal(t, 0, len(NewStorageHost().GetExtensions())) +} + +func TestStorageHostWithOne(t *testing.T) { + storageID := config.NewComponentIDWithName(testStorageType, "one") + + host := NewStorageHost().WithInMemoryStorageExtension("one") + + exts := host.GetExtensions() + require.Equal(t, 1, len(exts)) + + extOne, exists := exts[storageID] + require.True(t, exists) + + storageOne, ok := extOne.(*TestStorage) + require.True(t, ok) + require.Equal(t, storageID, storageOne.ID()) +} + +func TestStorageHostWithTwo(t *testing.T) { + storageOneID := config.NewComponentIDWithName(testStorageType, "one") + storageTwoID := config.NewComponentIDWithName(testStorageType, "two") + + host := NewStorageHost(). + WithInMemoryStorageExtension("one"). + WithFileBackedStorageExtension("two", t.TempDir()) + + exts := host.GetExtensions() + require.Equal(t, 2, len(exts)) + + extOne, exists := exts[storageOneID] + require.True(t, exists) + + storageOne, ok := extOne.(*TestStorage) + require.True(t, ok) + require.Equal(t, storageOneID, storageOne.ID()) + + extTwo, exists := exts[storageTwoID] + require.True(t, exists) + + storageTwo, ok := extTwo.(*TestStorage) + require.True(t, ok) + require.Equal(t, storageTwoID, storageTwo.ID()) +} + +func TestStorageHostWithMixed(t *testing.T) { + storageOneID := config.NewComponentIDWithName(testStorageType, "one") + storageTwoID := config.NewComponentIDWithName(testStorageType, "two") + nonStorageID := config.NewComponentIDWithName(nonStorageType, "non-storage") + + host := NewStorageHost(). + WithInMemoryStorageExtension("one"). + WithFileBackedStorageExtension("two", t.TempDir()). + WithNonStorageExtension("non-storage") + + exts := host.GetExtensions() + require.Equal(t, 3, len(exts)) + + extOne, exists := exts[storageOneID] + require.True(t, exists) + + storageOne, ok := extOne.(*TestStorage) + require.True(t, ok) + require.Equal(t, storageOneID, storageOne.ID()) + + extTwo, exists := exts[storageTwoID] + require.True(t, exists) + + storageTwo, ok := extTwo.(*TestStorage) + require.True(t, ok) + require.Equal(t, storageTwoID, storageTwo.ID()) + + extNon, exists := exts[nonStorageID] + require.True(t, exists) + + nonStorage, ok := extNon.(*NonStorage) + require.True(t, ok) + require.Equal(t, nonStorageID, nonStorage.ID()) +} diff --git a/extension/storage/storagetest/storage_test.go b/extension/storage/storagetest/storage_test.go deleted file mode 100644 index fd699a8bcf1b..000000000000 --- a/extension/storage/storagetest/storage_test.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package storagetest - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewStorageHost(t *testing.T) { - host := NewStorageHost(t, t.TempDir(), "test") - require.Equal(t, 1, len(host.GetExtensions())) - - hostWithTwo := NewStorageHost(t, t.TempDir(), "one", "two") - require.Equal(t, 2, len(hostWithTwo.GetExtensions())) -} diff --git a/pkg/stanza/adapter/mocks_test.go b/pkg/stanza/adapter/mocks_test.go index 5d17f76334e9..88f047b1d44e 100644 --- a/pkg/stanza/adapter/mocks_test.go +++ b/pkg/stanza/adapter/mocks_test.go @@ -17,15 +17,16 @@ package adapter import ( "context" "errors" - "sync" "time" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/consumer/consumertest" - "go.opentelemetry.io/collector/extension/experimental/storage" "go.opentelemetry.io/collector/pdata/plog" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/storagetest" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" @@ -132,64 +133,10 @@ func (f TestReceiverType) DecodeInputConfig(cfg config.Receiver) (*operator.Conf func newMockPersister() *persister { return &persister{ - client: newMockClient(), - } -} - -type mockClient struct { - cache map[string][]byte - cacheMux sync.Mutex -} - -func newMockClient() *mockClient { - return &mockClient{ - cache: make(map[string][]byte), - } -} - -func (p *mockClient) Get(_ context.Context, key string) ([]byte, error) { - p.cacheMux.Lock() - defer p.cacheMux.Unlock() - return p.cache[key], nil -} - -func (p *mockClient) Set(_ context.Context, key string, value []byte) error { - p.cacheMux.Lock() - defer p.cacheMux.Unlock() - p.cache[key] = value - return nil -} - -func (p *mockClient) Delete(_ context.Context, key string) error { - p.cacheMux.Lock() - defer p.cacheMux.Unlock() - delete(p.cache, key) - return nil -} - -func (p *mockClient) Batch(_ context.Context, ops ...storage.Operation) error { - p.cacheMux.Lock() - defer p.cacheMux.Unlock() - - for _, op := range ops { - switch op.Type { - case storage.Get: - op.Value = p.cache[op.Key] - case storage.Set: - p.cache[op.Key] = op.Value - case storage.Delete: - delete(p.cache, op.Key) - default: - return errors.New("wrong operation type") - } + client: storagetest.NewInMemoryClient( + component.KindReceiver, + config.NewComponentID("foolog"), + "test", + ), } - - return nil -} - -func (p *mockClient) Close(_ context.Context) error { - p.cacheMux.Lock() - defer p.cacheMux.Unlock() - p.cache = nil - return nil } diff --git a/pkg/stanza/adapter/storage_test.go b/pkg/stanza/adapter/storage_test.go index 814a4564a743..e1d320f601a9 100644 --- a/pkg/stanza/adapter/storage_test.go +++ b/pkg/stanza/adapter/storage_test.go @@ -29,7 +29,8 @@ import ( func TestStorage(t *testing.T) { ctx := context.Background() r := createReceiver(t) - host := storagetest.NewStorageHost(t, t.TempDir(), "test") + host := storagetest.NewStorageHost(). + WithFileBackedStorageExtension("test", t.TempDir()) require.NoError(t, r.Start(ctx, host)) myBytes := []byte("my_value") @@ -66,12 +67,14 @@ func TestStorage(t *testing.T) { _, err = r.storageClient.Get(ctx, "key") require.Error(t, err) - require.Equal(t, "database not open", err.Error()) + require.Equal(t, "client closed", err.Error()) } func TestFailOnMultipleStorageExtensions(t *testing.T) { r := createReceiver(t) - host := storagetest.NewStorageHost(t, t.TempDir(), "one", "two") + host := storagetest.NewStorageHost(). + WithInMemoryStorageExtension("one"). + WithInMemoryStorageExtension("two") err := r.Start(context.Background(), host) require.Error(t, err) require.Equal(t, "storage client: multiple storage extensions found", err.Error()) diff --git a/pkg/stanza/go.mod b/pkg/stanza/go.mod index 6c519ff1ab87..bd134fbd1d61 100644 --- a/pkg/stanza/go.mod +++ b/pkg/stanza/go.mod @@ -60,7 +60,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.6.1 // indirect github.com/stretchr/objx v0.4.0 // indirect - go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.23.0 // indirect go.opentelemetry.io/otel v1.9.0 // indirect go.opentelemetry.io/otel/metric v0.31.0 // indirect diff --git a/pkg/stanza/go.sum b/pkg/stanza/go.sum index e158d0e66051..8c82b7d6fa17 100644 --- a/pkg/stanza/go.sum +++ b/pkg/stanza/go.sum @@ -375,8 +375,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -549,7 +547,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/processor/logstransformprocessor/go.sum b/processor/logstransformprocessor/go.sum index 76b13e5722cd..409f90b53556 100644 --- a/processor/logstransformprocessor/go.sum +++ b/processor/logstransformprocessor/go.sum @@ -197,7 +197,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/receiver/filelogreceiver/go.mod b/receiver/filelogreceiver/go.mod index f37ca30b5b04..004dc78ec7cd 100644 --- a/receiver/filelogreceiver/go.mod +++ b/receiver/filelogreceiver/go.mod @@ -14,7 +14,6 @@ require ( require ( github.com/antonmedv/expr v1.9.0 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect github.com/bmatcuk/doublestar/v3 v3.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -30,7 +29,6 @@ require ( github.com/observiq/ctimefmt v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect - go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.23.0 // indirect go.opentelemetry.io/otel v1.9.0 // indirect go.opentelemetry.io/otel/metric v0.31.0 // indirect diff --git a/receiver/filelogreceiver/go.sum b/receiver/filelogreceiver/go.sum index e7ca8d5fb80c..da4f67aafbf0 100644 --- a/receiver/filelogreceiver/go.sum +++ b/receiver/filelogreceiver/go.sum @@ -20,7 +20,6 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+ github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmatcuk/doublestar/v3 v3.0.0 h1:TQtVPlDnAYwcrVNB2JiGuMc++H5qzWZd9PhkNo5WyHI= github.com/bmatcuk/doublestar/v3 v3.0.0/go.mod h1:6PcTVMw80pCY1RVuoqu3V++99uQB3vsSYKPTd8AWA0k= @@ -198,8 +197,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= @@ -266,7 +263,6 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/receiver/filelogreceiver/storage_test.go b/receiver/filelogreceiver/storage_test.go index 24b6c87657c8..a79d12bbbd3a 100644 --- a/receiver/filelogreceiver/storage_test.go +++ b/receiver/filelogreceiver/storage_test.go @@ -49,7 +49,7 @@ func TestStorage(t *testing.T) { logger := newRecallLogger(t, logsDir) - host := storagetest.NewStorageHost(t, storageDir, "test") + host := storagetest.NewStorageHost().WithFileBackedStorageExtension("test", storageDir) sink := new(consumertest.LogsSink) rcvr, err := f.CreateLogsReceiver(ctx, componenttest.NewNopReceiverCreateSettings(), cfg, sink) require.NoError(t, err, "failed to create receiver") @@ -80,7 +80,7 @@ func TestStorage(t *testing.T) { logger.log(fmt.Sprintf(baseLog, 4)) // Start the components again - host = storagetest.NewStorageHost(t, storageDir, "test") + host = storagetest.NewStorageHost().WithFileBackedStorageExtension("test", storageDir) rcvr, err = f.CreateLogsReceiver(ctx, componenttest.NewNopReceiverCreateSettings(), cfg, sink) require.NoError(t, err, "failed to create receiver") require.NoError(t, rcvr.Start(ctx, host)) @@ -124,7 +124,7 @@ func TestStorage(t *testing.T) { logger.log(fmt.Sprintf(baseLog, 9)) // Start the components again - host = storagetest.NewStorageHost(t, storageDir, "test") + host = storagetest.NewStorageHost().WithFileBackedStorageExtension("test", storageDir) rcvr, err = f.CreateLogsReceiver(ctx, componenttest.NewNopReceiverCreateSettings(), cfg, sink) require.NoError(t, err, "failed to create receiver") require.NoError(t, rcvr.Start(ctx, host)) diff --git a/receiver/journaldreceiver/go.sum b/receiver/journaldreceiver/go.sum index 9aa5fe5d0d6a..55e98bd38e2e 100644 --- a/receiver/journaldreceiver/go.sum +++ b/receiver/journaldreceiver/go.sum @@ -200,7 +200,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/receiver/otlpjsonfilereceiver/go.sum b/receiver/otlpjsonfilereceiver/go.sum index 26ac78100b92..6a22fcef6229 100644 --- a/receiver/otlpjsonfilereceiver/go.sum +++ b/receiver/otlpjsonfilereceiver/go.sum @@ -198,7 +198,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/receiver/syslogreceiver/go.sum b/receiver/syslogreceiver/go.sum index d8dcb732719e..2767b436d8b3 100644 --- a/receiver/syslogreceiver/go.sum +++ b/receiver/syslogreceiver/go.sum @@ -205,7 +205,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/receiver/tcplogreceiver/go.sum b/receiver/tcplogreceiver/go.sum index 54d8b371b00e..a5fb1233b445 100644 --- a/receiver/tcplogreceiver/go.sum +++ b/receiver/tcplogreceiver/go.sum @@ -202,7 +202,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/receiver/udplogreceiver/go.sum b/receiver/udplogreceiver/go.sum index 9aa5fe5d0d6a..55e98bd38e2e 100644 --- a/receiver/udplogreceiver/go.sum +++ b/receiver/udplogreceiver/go.sum @@ -200,7 +200,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/receiver/windowseventlogreceiver/go.sum b/receiver/windowseventlogreceiver/go.sum index 0e11ebdc04db..4f2481ce1060 100644 --- a/receiver/windowseventlogreceiver/go.sum +++ b/receiver/windowseventlogreceiver/go.sum @@ -197,7 +197,6 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector v0.57.2 h1:/J7twI5BlIK3I4GfDfLhqPgfgSjnhiDesXf24bmrXYM= diff --git a/unreleased/storagetest-memory-extension.yaml b/unreleased/storagetest-memory-extension.yaml new file mode 100755 index 000000000000..a93dc85b32cb --- /dev/null +++ b/unreleased/storagetest-memory-extension.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: extension/storage/storagetest + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add in-memory and file-backed test extensions and clients + +# One or more tracking issues related to the change +issues: [13086] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: