enhancement(search): add support for testcontainers to run local tests

This commit is contained in:
fschade
2025-08-28 09:32:26 +02:00
parent ad866b8ce3
commit ca0493b286
851 changed files with 111016 additions and 18 deletions
@@ -40,9 +40,6 @@ func DefaultConfig() *config.Config {
Datapath: filepath.Join(defaults.BaseDataPath(), "search"),
},
OpenSearch: config.EngineOpenSearch{
Client: config.EngineOpenSearchClient{
Addresses: []string{"http://localhost:9201"},
},
ResourceIndex: config.EngineOpenSearchResourceIndex{
Name: "opencloud-resource",
},
@@ -32,7 +32,7 @@ func TestNewBackend(t *testing.T) {
func TestEngine_Search(t *testing.T) {
indexName := "opencloud-test-engine-search"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
@@ -75,7 +75,7 @@ func TestEngine_Search(t *testing.T) {
func TestEngine_Upsert(t *testing.T) {
indexName := "opencloud-test-engine-upsert"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
@@ -94,7 +94,7 @@ func TestEngine_Upsert(t *testing.T) {
func TestEngine_Move(t *testing.T) {
indexName := "opencloud-test-engine-move"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
@@ -131,7 +131,7 @@ func TestEngine_Move(t *testing.T) {
func TestEngine_Delete(t *testing.T) {
indexName := "opencloud-test-engine-delete"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
@@ -164,7 +164,7 @@ func TestEngine_Delete(t *testing.T) {
func TestEngine_Restore(t *testing.T) {
indexName := "opencloud-test-engine-restore"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
@@ -198,7 +198,7 @@ func TestEngine_Restore(t *testing.T) {
func TestEngine_Purge(t *testing.T) {
indexName := "opencloud-test-engine-purge"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
@@ -220,7 +220,7 @@ func TestEngine_Purge(t *testing.T) {
func TestEngine_DocCount(t *testing.T) {
indexName := "opencloud-test-engine-doc-count"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCount([]string{indexName}, nil, 0)
+4 -4
View File
@@ -8,7 +8,7 @@ import (
"github.com/tidwall/sjson"
"github.com/opencloud-eu/opencloud/services/search/pkg/opensearch"
opensearchtest "github.com/opencloud-eu/opencloud/services/search/pkg/opensearch/internal/test"
"github.com/opencloud-eu/opencloud/services/search/pkg/opensearch/internal/test"
)
func TestIndexManager(t *testing.T) {
@@ -19,7 +19,7 @@ func TestIndexManager(t *testing.T) {
Got: opensearch.IndexManagerLatest,
},
}
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
@@ -40,7 +40,7 @@ func TestIndexManager(t *testing.T) {
indexManager := opensearch.IndexManagerLatest
indexName := "opencloud-test-resource"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
tc.Require.IndicesCreate(indexName, strings.NewReader(indexManager.String()))
@@ -51,7 +51,7 @@ func TestIndexManager(t *testing.T) {
indexManager := opensearch.IndexManagerLatest
indexName := "opencloud-test-resource"
tc := opensearchtest.NewDefaultTestClient(t)
tc := opensearchtest.NewDefaultTestClient(t, defaultConfig.Engine.OpenSearch.Client)
tc.Require.IndicesReset([]string{indexName})
body, err := sjson.Set(indexManager.String(), "settings.number_of_shards", "2")
@@ -12,7 +12,7 @@ import (
opensearchgoAPI "github.com/opensearch-project/opensearch-go/v4/opensearchapi"
"github.com/stretchr/testify/require"
"github.com/opencloud-eu/opencloud/services/search/pkg/config/defaults"
"github.com/opencloud-eu/opencloud/services/search/pkg/config"
)
type TestClient struct {
@@ -20,10 +20,12 @@ type TestClient struct {
Require *testRequireClient
}
func NewDefaultTestClient(t *testing.T) *TestClient {
func NewDefaultTestClient(t *testing.T, cfg config.EngineOpenSearchClient) *TestClient {
client, err := opensearchgoAPI.NewClient(opensearchgoAPI.Config{
Client: opensearchgo.Config{
Addresses: defaults.DefaultConfig().Engine.OpenSearch.Client.Addresses,
Addresses: cfg.Addresses,
Username: cfg.Username,
Password: cfg.Password,
},
})
require.NoError(t, err, "failed to create OpenSearch client")
@@ -0,0 +1,99 @@
package opensearchtest
import (
"context"
"fmt"
"os"
"slices"
"strings"
"time"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/opensearch"
"github.com/testcontainers/testcontainers-go/wait"
"github.com/opencloud-eu/opencloud/services/search/pkg/config"
"github.com/opencloud-eu/opencloud/services/search/pkg/config/defaults"
"github.com/opencloud-eu/opencloud/services/search/pkg/config/parser"
)
const (
openSearchImage = "opensearchproject/opensearch:2"
)
func SetupTests(ctx context.Context) (*config.Config, func(), error) {
cfg, err := setupDefaultConfig()
if err != nil {
return nil, nil, fmt.Errorf("failed to setup default configuration: %w", err)
}
cleanupOpenSearch, err := setupOpenSearchTestContainer(ctx, cfg)
if err != nil {
return nil, nil, fmt.Errorf("failed to setup OpenSearch test container: %w", err)
}
return cfg, cleanupOpenSearch, nil
}
func setupDefaultConfig() (*config.Config, error) {
cfg := defaults.DefaultConfig()
defaults.EnsureDefaults(cfg)
{ // parser.Validate requires these fields to be set even if they are not used in these tests.
cfg.TokenManager.JWTSecret = "any-jwt"
cfg.ServiceAccount.ServiceAccountID = "any-service-account-id"
cfg.ServiceAccount.ServiceAccountSecret = "any-service-account-secret"
}
if err := parser.ParseConfig(cfg); err != nil {
return nil, fmt.Errorf("failed to parse default configuration: %w", err)
}
return cfg, nil
}
func setupOpenSearchTestContainer(ctx context.Context, cfg *config.Config) (func(), error) {
usesExternalOpensearch := slices.Contains([]bool{
os.Getenv("CI") == "woodpecker",
os.Getenv("CI_SYSTEM_NAME") == "woodpecker",
os.Getenv("USE_TESTCONTAINERS") == "false",
}, true)
if usesExternalOpensearch {
return func() {}, nil
}
containerName := fmt.Sprintf("opencloud/test/%s", openSearchImage)
containerName = strings.Replace(containerName, "/", "__", -1)
containerName = strings.Replace(containerName, ":", "_", -1)
container, err := opensearch.Run(
ctx,
openSearchImage,
opensearch.WithUsername(cfg.Engine.OpenSearch.Client.Username),
opensearch.WithPassword(cfg.Engine.OpenSearch.Client.Password),
testcontainers.WithName(containerName),
testcontainers.WithReuseByName(containerName),
testcontainers.WithWaitStrategy(
wait.ForLog("ML configuration initialized successfully").
WithStartupTimeout(5*time.Second),
),
)
if err != nil {
return nil, fmt.Errorf("failed to start OpenSearch container: %w", err)
}
address, err := container.Address(ctx)
if err != nil {
_ = container.Terminate(ctx) // attempt to clean up the container
return nil, fmt.Errorf("failed to get OpenSearch container address: %w", err)
}
// Ensure the address is set in the default configuration.
cfg.Engine.OpenSearch.Client.Addresses = []string{address}
return func() {
err := container.Terminate(ctx)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "failed to terminate OpenSearch container: %v\n", err)
}
}, nil
}
@@ -0,0 +1,26 @@
package opensearch_test
import (
"context"
"fmt"
"os"
"testing"
"github.com/opencloud-eu/opencloud/services/search/pkg/config"
opensearchtest "github.com/opencloud-eu/opencloud/services/search/pkg/opensearch/internal/test"
)
var defaultConfig *config.Config
func TestMain(m *testing.M) {
cfg, done, err := opensearchtest.SetupTests(context.Background())
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, "Failed to setup tests:", err)
os.Exit(1)
return
}
defaultConfig = cfg
code := m.Run()
done()
os.Exit(code)
}