mirror of
https://github.com/mudler/LocalAI.git
synced 2026-04-02 06:04:09 -04:00
* feat: add distributed mode (experimental) Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix data races, mutexes, transactions Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactorings Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fixups Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix events and tool stream in agent chat Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * use ginkgo Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(cron): compute correctly time boundaries avoiding re-triggering Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * enhancements, refactorings Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * do not flood of healthy checks Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * do not list obvious backends as text backends Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * tests fixups Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * refactoring and consolidation Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * Drop redundant healthcheck Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * enhancements, refactorings Signed-off-by: Ettore Di Giacinto <mudler@localai.io> --------- Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
114 lines
3.1 KiB
Go
114 lines
3.1 KiB
Go
package distributed_test
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/mudler/LocalAI/core/services/messaging"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
|
|
"github.com/testcontainers/testcontainers-go"
|
|
tcnats "github.com/testcontainers/testcontainers-go/modules/nats"
|
|
tcpostgres "github.com/testcontainers/testcontainers-go/modules/postgres"
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
)
|
|
|
|
// TestInfra holds shared test containers and connection strings.
|
|
type TestInfra struct {
|
|
Ctx context.Context
|
|
PGContainer *tcpostgres.PostgresContainer
|
|
NATSContainer *tcnats.NATSContainer
|
|
PGURL string
|
|
NatsURL string
|
|
NC *messaging.Client
|
|
}
|
|
|
|
// SetupInfra starts PostgreSQL and NATS containers and connects a messaging client.
|
|
// Call in BeforeEach. Use DeferCleanup or call Teardown in AfterEach.
|
|
func SetupInfra(dbName string) *TestInfra {
|
|
GinkgoHelper()
|
|
|
|
infra := &TestInfra{Ctx: context.Background()}
|
|
var err error
|
|
|
|
// Start PostgreSQL container
|
|
infra.PGContainer, err = tcpostgres.Run(infra.Ctx, "postgres:16-alpine",
|
|
tcpostgres.WithDatabase(dbName),
|
|
tcpostgres.WithUsername("test"),
|
|
tcpostgres.WithPassword("test"),
|
|
testcontainers.WithWaitStrategy(
|
|
wait.ForLog("database system is ready to accept connections").
|
|
WithOccurrence(2).
|
|
WithStartupTimeout(30*time.Second),
|
|
),
|
|
)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
infra.PGURL, err = infra.PGContainer.ConnectionString(infra.Ctx, "sslmode=disable")
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
// Start NATS container
|
|
infra.NATSContainer, err = tcnats.Run(infra.Ctx, "nats:2-alpine")
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
infra.NatsURL, err = infra.NATSContainer.ConnectionString(infra.Ctx)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
// Connect messaging client
|
|
infra.NC, err = messaging.New(infra.NatsURL)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
// Register cleanup in LIFO order
|
|
DeferCleanup(func() {
|
|
if infra.NC != nil {
|
|
infra.NC.Close()
|
|
}
|
|
if infra.PGContainer != nil {
|
|
infra.PGContainer.Terminate(context.Background())
|
|
}
|
|
if infra.NATSContainer != nil {
|
|
infra.NATSContainer.Terminate(context.Background())
|
|
}
|
|
})
|
|
|
|
return infra
|
|
}
|
|
|
|
// SetupNATSOnly starts only a NATS container and connects a messaging client.
|
|
// Useful for tests that don't need PostgreSQL.
|
|
func SetupNATSOnly() *TestInfra {
|
|
GinkgoHelper()
|
|
|
|
infra := &TestInfra{Ctx: context.Background()}
|
|
var err error
|
|
|
|
infra.NATSContainer, err = tcnats.Run(infra.Ctx, "nats:2-alpine")
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
infra.NatsURL, err = infra.NATSContainer.ConnectionString(infra.Ctx)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
infra.NC, err = messaging.New(infra.NatsURL)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
DeferCleanup(func() {
|
|
if infra.NC != nil {
|
|
infra.NC.Close()
|
|
}
|
|
if infra.NATSContainer != nil {
|
|
infra.NATSContainer.Terminate(context.Background())
|
|
}
|
|
})
|
|
|
|
return infra
|
|
}
|
|
|
|
// FlushNATS ensures all subscriptions are registered server-side before publishing.
|
|
// Replaces time.Sleep(100ms) after Subscribe calls.
|
|
func FlushNATS(nc *messaging.Client) {
|
|
GinkgoHelper()
|
|
Expect(nc.Conn().Flush()).To(Succeed())
|
|
}
|