From 79cc8a2b12a8f0f57ac35412145988521211f0c6 Mon Sep 17 00:00:00 2001 From: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> Date: Sat, 27 Apr 2024 01:21:00 +0530 Subject: [PATCH] [jaeger-v2] Add badger e2e integration test (#5355) ## Which problem is this PR solving? - part of #5254 ## Description of the changes - added badger e2e integration test ## How was this change tested? - tested locally ## Checklist - [x] I have read https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md - [x] I have signed all commits - [x] I have added unit tests for the new functionality - [x] I have run lint and test steps successfully - for `jaeger`: `make lint test` - for `jaeger-ui`: `yarn lint` and `yarn test` --------- Signed-off-by: Harshvir Potpose Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> Signed-off-by: Yuri Shkuro Co-authored-by: Yuri Shkuro Co-authored-by: Yuri Shkuro --- .github/workflows/ci-badger.yaml | 14 +- cmd/jaeger/badger_config.yaml | 2 + cmd/jaeger/internal/components.go | 2 + .../internal/integration/badger_test.go | 51 ++++++ cmd/jaeger/internal/integration/grpc_test.go | 2 +- .../internal/integration/integration.go | 32 +++- .../storagereceiver/testdata/config.yaml | 2 +- .../integration/storagecleaner/README.md | 47 ++++++ .../integration/storagecleaner/config.go | 18 +++ .../integration/storagecleaner/config_test.go | 23 +++ .../integration/storagecleaner/extension.go | 98 ++++++++++++ .../storagecleaner/extension_test.go | 146 ++++++++++++++++++ .../integration/storagecleaner/factory.go | 40 +++++ .../storagecleaner/factory_test.go | 28 ++++ .../storagecleaner/package_test.go | 14 ++ go.mod | 2 +- plugin/storage/badger/factory.go | 1 + storage/factory.go | 7 + 18 files changed, 524 insertions(+), 5 deletions(-) create mode 100644 cmd/jaeger/internal/integration/badger_test.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/README.md create mode 100644 cmd/jaeger/internal/integration/storagecleaner/config.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/config_test.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/extension.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/extension_test.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/factory.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/factory_test.go create mode 100644 cmd/jaeger/internal/integration/storagecleaner/package_test.go diff --git a/.github/workflows/ci-badger.yaml b/.github/workflows/ci-badger.yaml index 4f43057ce6d..b6b7cd22f32 100644 --- a/.github/workflows/ci-badger.yaml +++ b/.github/workflows/ci-badger.yaml @@ -18,6 +18,9 @@ permissions: # added using https://github.com/step-security/secure-workflows jobs: badger: runs-on: ubuntu-latest + strategy: + matrix: + version: [v1, v2] steps: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 @@ -31,7 +34,16 @@ jobs: go-version: 1.22.x - name: Run Badger storage integration tests - run: make badger-storage-integration-test + run: | + case ${{ matrix.version }} in + v1) + make badger-storage-integration-test + ;; + v2) + STORAGE=badger \ + make jaeger-v2-storage-integration-test + ;; + esac - name: Setup CODECOV_TOKEN uses: ./.github/actions/setup-codecov diff --git a/cmd/jaeger/badger_config.yaml b/cmd/jaeger/badger_config.yaml index 950be451250..4643c9cc75a 100644 --- a/cmd/jaeger/badger_config.yaml +++ b/cmd/jaeger/badger_config.yaml @@ -20,12 +20,14 @@ extensions: ephemeral: false maintenance_interval: 5 metrics_update_interval: 10 + span_store_ttl: 72h badger_archive: directory_key: "/tmp/jaeger_archive/" directory_value: "/tmp/jaeger_archive/" ephemeral: false maintenance_interval: 5 metrics_update_interval: 10 + span_store_ttl: 720h receivers: otlp: diff --git a/cmd/jaeger/internal/components.go b/cmd/jaeger/internal/components.go index cf9b10a9e71..c7b9957dbd8 100644 --- a/cmd/jaeger/internal/components.go +++ b/cmd/jaeger/internal/components.go @@ -29,6 +29,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/jaeger/internal/exporters/storageexporter" "github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerquery" "github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerstorage" + "github.com/jaegertracing/jaeger/cmd/jaeger/internal/integration/storagecleaner" ) type builders struct { @@ -60,6 +61,7 @@ func (b builders) build() (otelcol.Factories, error) { // add-ons jaegerquery.NewFactory(), jaegerstorage.NewFactory(), + storagecleaner.NewFactory(), // TODO add adaptive sampling ) if err != nil { diff --git a/cmd/jaeger/internal/integration/badger_test.go b/cmd/jaeger/internal/integration/badger_test.go new file mode 100644 index 00000000000..4f3526197c4 --- /dev/null +++ b/cmd/jaeger/internal/integration/badger_test.go @@ -0,0 +1,51 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package integration + +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/jaegertracing/jaeger/cmd/jaeger/internal/integration/storagecleaner" + "github.com/jaegertracing/jaeger/plugin/storage/integration" +) + +func cleanUp(t *testing.T) { + Addr := fmt.Sprintf("http://0.0.0.0:%s%s", storagecleaner.Port, storagecleaner.URL) + r, err := http.NewRequest(http.MethodPost, Addr, nil) + require.NoError(t, err) + + client := &http.Client{} + + resp, err := client.Do(r) + require.NoError(t, err) + defer resp.Body.Close() + + require.Equal(t, http.StatusOK, resp.StatusCode) +} + +func TestBadgerStorage(t *testing.T) { + integration.SkipUnlessEnv(t, "badger") + + s := &E2EStorageIntegration{ + ConfigFile: "../../badger_config.yaml", + StorageIntegration: integration.StorageIntegration{ + SkipBinaryAttrs: true, + SkipArchiveTest: true, + CleanUp: cleanUp, + + // TODO: remove this once badger supports returning spanKind from GetOperations + // Cf https://github.com/jaegertracing/jaeger/issues/1922 + GetOperationsMissingSpanKind: true, + }, + } + s.e2eInitialize(t) + t.Cleanup(func() { + s.e2eCleanUp(t) + }) + s.RunAll(t) +} diff --git a/cmd/jaeger/internal/integration/grpc_test.go b/cmd/jaeger/internal/integration/grpc_test.go index f990e8aec46..22f4bbbd067 100644 --- a/cmd/jaeger/internal/integration/grpc_test.go +++ b/cmd/jaeger/internal/integration/grpc_test.go @@ -33,7 +33,7 @@ func TestGRPCStorage(t *testing.T) { integration.SkipUnlessEnv(t, "grpc") s := &GRPCStorageIntegration{} - s.ConfigFile = "cmd/jaeger/grpc_config.yaml" + s.ConfigFile = "../../grpc_config.yaml" s.SkipBinaryAttrs = true s.initialize(t) diff --git a/cmd/jaeger/internal/integration/integration.go b/cmd/jaeger/internal/integration/integration.go index 67ecd609508..e6404c3b9ed 100644 --- a/cmd/jaeger/internal/integration/integration.go +++ b/cmd/jaeger/internal/integration/integration.go @@ -7,9 +7,11 @@ import ( "io" "os" "os/exec" + "path/filepath" "testing" "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" "github.com/jaegertracing/jaeger/pkg/testutils" "github.com/jaegertracing/jaeger/plugin/storage/integration" @@ -38,10 +40,11 @@ type E2EStorageIntegration struct { // This function should be called before any of the tests start. func (s *E2EStorageIntegration) e2eInitialize(t *testing.T) { logger, _ := testutils.NewLogger() + configFile := createStorageCleanerConfig(t, s.ConfigFile) cmd := exec.Cmd{ Path: "./cmd/jaeger/jaeger", - Args: []string{"jaeger", "--config", s.ConfigFile}, + Args: []string{"jaeger", "--config", configFile}, // Change the working directory to the root of this project // since the binary config file jaeger_query's ui_config points to // "./cmd/jaeger/config-ui.json" @@ -67,3 +70,30 @@ func (s *E2EStorageIntegration) e2eCleanUp(t *testing.T) { require.NoError(t, s.SpanReader.(io.Closer).Close()) require.NoError(t, s.SpanWriter.(io.Closer).Close()) } + +func createStorageCleanerConfig(t *testing.T, configFile string) string { + data, err := os.ReadFile(configFile) + require.NoError(t, err) + var config map[string]interface{} + err = yaml.Unmarshal(data, &config) + require.NoError(t, err) + + service, ok := config["service"].(map[string]interface{}) + require.True(t, ok) + service["extensions"] = append(service["extensions"].([]interface{}), "storage_cleaner") + + extensions, ok := config["extensions"].(map[string]interface{}) + require.True(t, ok) + query, ok := extensions["jaeger_query"].(map[string]interface{}) + require.True(t, ok) + trace_storage := query["trace_storage"].(string) + extensions["storage_cleaner"] = map[string]string{"trace_storage": trace_storage} + + newData, err := yaml.Marshal(config) + require.NoError(t, err) + tempFile := filepath.Join(t.TempDir(), "storageCleaner_config.yaml") + err = os.WriteFile(tempFile, newData, 0o600) + require.NoError(t, err) + + return tempFile +} diff --git a/cmd/jaeger/internal/integration/receivers/storagereceiver/testdata/config.yaml b/cmd/jaeger/internal/integration/receivers/storagereceiver/testdata/config.yaml index a7c0da9218d..e590e8f1694 100644 --- a/cmd/jaeger/internal/integration/receivers/storagereceiver/testdata/config.yaml +++ b/cmd/jaeger/internal/integration/receivers/storagereceiver/testdata/config.yaml @@ -3,4 +3,4 @@ jaeger_storage_receiver/defaults: trace_storage: storage jaeger_storage_receiver/filled: trace_storage: storage - pull_interval: 2s \ No newline at end of file + pull_interval: 2s diff --git a/cmd/jaeger/internal/integration/storagecleaner/README.md b/cmd/jaeger/internal/integration/storagecleaner/README.md new file mode 100644 index 00000000000..a2011cddb06 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/README.md @@ -0,0 +1,47 @@ +# storage_cleaner + +This module implements an extension that allows purging the backend storage by making an HTTP POST request to it. + +The storage_cleaner extension is intended to be used only in tests, providing a way to clear the storage between test runs. Making a POST request to the exposed endpoint will delete all data in storage. + + +```mermaid +flowchart LR + Receiver --> Processor + Processor --> Exporter + JaegerStorageExension -->|"(1) get storage"| Exporter + Exporter -->|"(2) write trace"| Storage + + E2E_test -->|"(1) POST /purge"| HTTP_endpoint + JaegerStorageExension -->|"(2) getStorage()"| HTTP_endpoint + HTTP_endpoint -.->|"(3) storage.(*storage.Purger).Purge()"| Storage + + subgraph Jaeger Collector + Receiver + Processor + Exporter + + Storage + StorageCleanerExtension + HTTP_endpoint + subgraph JaegerStorageExension + Storage + end + subgraph StorageCleanerExtension + HTTP_endpoint + end + end +``` + +# Getting Started + +The following settings are required: + +- `trace_storage` : name of a storage backend defined in `jaegerstorage` extension + +```yaml +extensions: + storage_cleaner: + trace_storage: storage_name +``` + diff --git a/cmd/jaeger/internal/integration/storagecleaner/config.go b/cmd/jaeger/internal/integration/storagecleaner/config.go new file mode 100644 index 00000000000..5b4c9d30812 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/config.go @@ -0,0 +1,18 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "github.com/asaskevich/govalidator" +) + +type Config struct { + TraceStorage string `valid:"required" mapstructure:"trace_storage"` + Port string `mapstructure:"port"` +} + +func (cfg *Config) Validate() error { + _, err := govalidator.ValidateStruct(cfg) + return err +} diff --git a/cmd/jaeger/internal/integration/storagecleaner/config_test.go b/cmd/jaeger/internal/integration/storagecleaner/config_test.go new file mode 100644 index 00000000000..48b49c66e88 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/config_test.go @@ -0,0 +1,23 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestStorageExtensionConfig(t *testing.T) { + config := createDefaultConfig().(*Config) + config.TraceStorage = "storage" + err := config.Validate() + require.NoError(t, err) +} + +func TestStorageExtensionConfigError(t *testing.T) { + config := createDefaultConfig().(*Config) + err := config.Validate() + require.ErrorContains(t, err, "non zero value required") +} diff --git a/cmd/jaeger/internal/integration/storagecleaner/extension.go b/cmd/jaeger/internal/integration/storagecleaner/extension.go new file mode 100644 index 00000000000..5ef26eb1867 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/extension.go @@ -0,0 +1,98 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/gorilla/mux" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/extension" + + "github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerstorage" + "github.com/jaegertracing/jaeger/storage" +) + +var ( + _ extension.Extension = (*storageCleaner)(nil) + _ extension.Dependent = (*storageCleaner)(nil) +) + +const ( + Port = "9231" + URL = "/purge" +) + +type storageCleaner struct { + config *Config + server *http.Server + settings component.TelemetrySettings +} + +func newStorageCleaner(config *Config, telemetrySettings component.TelemetrySettings) *storageCleaner { + return &storageCleaner{ + config: config, + settings: telemetrySettings, + } +} + +func (c *storageCleaner) Start(ctx context.Context, host component.Host) error { + storageFactory, err := jaegerstorage.GetStorageFactory(c.config.TraceStorage, host) + if err != nil { + return fmt.Errorf("cannot find storage factory '%s': %w", c.config.TraceStorage, err) + } + + purgeStorage := func() error { + purger, ok := storageFactory.(storage.Purger) + if !ok { + return fmt.Errorf("storage %s does not implement Purger interface", c.config.TraceStorage) + } + if err := purger.Purge(); err != nil { + return fmt.Errorf("error purging storage: %w", err) + } + return nil + } + + purgeHandler := func(w http.ResponseWriter, r *http.Request) { + if err := purgeStorage(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + w.Write([]byte("Purge request processed successfully")) + } + + r := mux.NewRouter() + r.HandleFunc(URL, purgeHandler).Methods(http.MethodPost) + c.server = &http.Server{ + Addr: ":" + c.config.Port, + Handler: r, + ReadHeaderTimeout: 3 * time.Second, + } + go func() { + if err := c.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + err = fmt.Errorf("error starting cleaner server: %w", err) + c.settings.ReportStatus(component.NewFatalErrorEvent(err)) + } + }() + + return nil +} + +func (c *storageCleaner) Shutdown(ctx context.Context) error { + if c.server != nil { + if err := c.server.Shutdown(ctx); err != nil { + return fmt.Errorf("error shutting down cleaner server: %w", err) + } + } + return nil +} + +func (c *storageCleaner) Dependencies() []component.ID { + return []component.ID{jaegerstorage.ID} +} diff --git a/cmd/jaeger/internal/integration/storagecleaner/extension_test.go b/cmd/jaeger/internal/integration/storagecleaner/extension_test.go new file mode 100644 index 00000000000..26fb08a47e2 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/extension_test.go @@ -0,0 +1,146 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "context" + "fmt" + "net/http" + "sync/atomic" + "testing" + "time" + + "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/storagetest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component" + + "github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerstorage" + "github.com/jaegertracing/jaeger/storage" + factoryMocks "github.com/jaegertracing/jaeger/storage/mocks" +) + +var ( + _ jaegerstorage.Extension = (*mockStorageExt)(nil) + _ storage.Factory = (*PurgerFactory)(nil) +) + +type PurgerFactory struct { + factoryMocks.Factory + err error +} + +func (f *PurgerFactory) Purge() error { + return f.err +} + +type mockStorageExt struct { + name string + factory storage.Factory +} + +func (m *mockStorageExt) Start(ctx context.Context, host component.Host) error { + panic("not implemented") +} + +func (m *mockStorageExt) Shutdown(ctx context.Context) error { + panic("not implemented") +} + +func (m *mockStorageExt) Factory(name string) (storage.Factory, bool) { + if m.name == name { + return m.factory, true + } + return nil, false +} + +func TestStorageCleanerExtension(t *testing.T) { + tests := []struct { + name string + factory storage.Factory + status int + }{ + { + name: "good storage", + factory: &PurgerFactory{}, + status: http.StatusOK, + }, + { + name: "good storage with error", + factory: &PurgerFactory{err: fmt.Errorf("error")}, + status: http.StatusInternalServerError, + }, + { + name: "bad storage", + factory: &factoryMocks.Factory{}, + status: http.StatusInternalServerError, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + config := &Config{ + TraceStorage: "storage", + Port: Port, + } + s := newStorageCleaner(config, component.TelemetrySettings{}) + require.NotEmpty(t, s.Dependencies()) + host := storagetest.NewStorageHost() + host.WithExtension(jaegerstorage.ID, &mockStorageExt{ + name: "storage", + factory: test.factory, + }) + require.NoError(t, s.Start(context.Background(), host)) + defer s.Shutdown(context.Background()) + + addr := fmt.Sprintf("http://0.0.0.0:%s%s", Port, URL) + client := &http.Client{} + require.Eventually(t, func() bool { + r, err := http.NewRequest(http.MethodPost, addr, nil) + require.NoError(t, err) + resp, err := client.Do(r) + require.NoError(t, err) + defer resp.Body.Close() + return test.status == resp.StatusCode + }, 5*time.Second, 100*time.Millisecond) + }) + } +} + +func TestGetStorageFactoryError(t *testing.T) { + config := &Config{} + s := newStorageCleaner(config, component.TelemetrySettings{}) + host := storagetest.NewStorageHost() + host.WithExtension(jaegerstorage.ID, &mockStorageExt{ + name: "storage", + factory: nil, + }) + err := s.Start(context.Background(), host) + require.Error(t, err) + require.Contains(t, err.Error(), "cannot find storage factory") +} + +func TestStorageExtensionStartError(t *testing.T) { + config := &Config{ + TraceStorage: "storage", + Port: "invalid-port", + } + var startStatus atomic.Pointer[component.StatusEvent] + s := newStorageCleaner(config, component.TelemetrySettings{ + ReportStatus: func(status *component.StatusEvent) { + startStatus.Store(status) + }, + }) + host := storagetest.NewStorageHost().WithExtension( + jaegerstorage.ID, + &mockStorageExt{ + name: "storage", + factory: &PurgerFactory{}, + }) + require.NoError(t, s.Start(context.Background(), host)) + assert.Eventually(t, func() bool { + return startStatus.Load() != nil + }, 5*time.Second, 100*time.Millisecond) + require.Contains(t, startStatus.Load().Err().Error(), "error starting cleaner server") +} diff --git a/cmd/jaeger/internal/integration/storagecleaner/factory.go b/cmd/jaeger/internal/integration/storagecleaner/factory.go new file mode 100644 index 00000000000..66ab01324ff --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/factory.go @@ -0,0 +1,40 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/extension" +) + +// componentType is the name of this extension in configuration. +var componentType = component.MustNewType("storage_cleaner") + +// ID is the identifier of this extension. +var ID = component.NewID(componentType) + +func NewFactory() extension.Factory { + return extension.NewFactory( + componentType, + createDefaultConfig, + createExtension, + component.StabilityLevelBeta, + ) +} + +func createDefaultConfig() component.Config { + return &Config{ + Port: Port, + } +} + +func createExtension( + _ context.Context, + set extension.CreateSettings, + cfg component.Config, +) (extension.Extension, error) { + return newStorageCleaner(cfg.(*Config), set.TelemetrySettings), nil +} diff --git a/cmd/jaeger/internal/integration/storagecleaner/factory_test.go b/cmd/jaeger/internal/integration/storagecleaner/factory_test.go new file mode 100644 index 00000000000..7b1ec51d8f3 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/factory_test.go @@ -0,0 +1,28 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/extension/extensiontest" +) + +func TestCreateDefaultConfig(t *testing.T) { + cfg := createDefaultConfig().(*Config) + require.NotNil(t, cfg, "failed to create default config") + require.NoError(t, componenttest.CheckConfigStruct(cfg)) +} + +func TestCreateExtension(t *testing.T) { + cfg := createDefaultConfig().(*Config) + f := NewFactory() + r, err := f.CreateExtension(context.Background(), extensiontest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + assert.NotNil(t, r) +} diff --git a/cmd/jaeger/internal/integration/storagecleaner/package_test.go b/cmd/jaeger/internal/integration/storagecleaner/package_test.go new file mode 100644 index 00000000000..cec15912582 --- /dev/null +++ b/cmd/jaeger/internal/integration/storagecleaner/package_test.go @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storagecleaner + +import ( + "testing" + + "github.com/jaegertracing/jaeger/pkg/testutils" +) + +func TestMain(m *testing.M) { + testutils.VerifyGoLeaks(m) +} diff --git a/go.mod b/go.mod index e825c00f8bd..2e95435b8e5 100644 --- a/go.mod +++ b/go.mod @@ -225,7 +225,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.1 ) replace github.com/Shopify/sarama => github.com/Shopify/sarama v1.33.0 diff --git a/plugin/storage/badger/factory.go b/plugin/storage/badger/factory.go index 607ab05bf65..1fc2e1dffac 100644 --- a/plugin/storage/badger/factory.go +++ b/plugin/storage/badger/factory.go @@ -50,6 +50,7 @@ var ( // interface comformance checks _ storage.Factory = (*Factory)(nil) _ io.Closer = (*Factory)(nil) _ plugin.Configurable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) // TODO badger could implement archive storage // _ storage.ArchiveFactory = (*Factory)(nil) diff --git a/storage/factory.go b/storage/factory.go index 933d0dce27d..b56e6fdc07f 100644 --- a/storage/factory.go +++ b/storage/factory.go @@ -49,6 +49,13 @@ type Factory interface { CreateDependencyReader() (dependencystore.Reader, error) } +// Purger defines an interface that is capable of purging the storage. +// Only meant to be used from integration tests. +type Purger interface { + // Purge removes all data from the storage. + Purge() error +} + // SamplingStoreFactory defines an interface that is capable of returning the necessary backends for // adaptive sampling. type SamplingStoreFactory interface {