Files
Курнат Андрей 2315f25754 Initial QSfera import
2026-06-07 10:20:04 +03:00

100 lines
2.9 KiB
Go

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/qsfera/server/services/search/pkg/config"
"github.com/qsfera/server/services/search/pkg/config/defaults"
"github.com/qsfera/server/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("qsfera/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
}