diff --git a/Makefile b/Makefile index d1d7d902..e01ff21a 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,14 @@ include .env POSTGRES_URL = postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=${POSTGRES_SSL_MODE} +TEST_POSTGRES_USER = test +TEST_POSTGRES_PASSWORD = test +TEST_POSTGRES_HOST = localhost +TEST_POSTGRES_PORT = 5400 +TEST_POSTGRES_DB = test +TEST_POSTGRES_SSL_MODE = disable +DELETE_TEST_DB ?= true + .PHONY: migrate migrate: @migrate -path internal/odin/db/migrations -database ${POSTGRES_URL} up @@ -43,3 +51,25 @@ oapi-gen: .PHONY: start-observability start-observability: @docker compose up valkyrie-otel-collector jaeger prometheus -d + +.PHONY: start-test-db +start-test-db: + @docker run \ + --rm \ + --name odin-test-db \ + -e POSTGRES_USER=${TEST_POSTGRES_USER} \ + -e POSTGRES_PASSWORD=${TEST_POSTGRES_PASSWORD} \ + -e POSTGRES_DB=${TEST_POSTGRES_DB} \ + -p ${TEST_POSTGRES_PORT}:5432 \ + -d postgres + +.PHONY: stop-test-db +stop-test-db: + @docker stop odin-test-db + +.PHONY: test +test: start-test-db + @go test ./internal/odin/server + if [ "${DELETE_TEST_DB}" = "true" ]; then \ + $(MAKE) stop-test-db; \ + fi \ No newline at end of file diff --git a/build/package/nix/odin.nix b/build/package/nix/odin.nix index 4e9cbe1b..6a08f76f 100644 --- a/build/package/nix/odin.nix +++ b/build/package/nix/odin.nix @@ -12,7 +12,7 @@ buildGoModule rec { pname = "odin"; version = "0.0.1"; - vendorHash = "sha256-g+YA2d4tuAtGazjtNiIyyaWbJfnZXMeHk7e8EDr+uUw="; + vendorHash = "sha256-lmhtxBhG6YL71ieUmAjnesliFcW7T/+OU0hyupm4cMg="; src = ../../..; diff --git a/go.mod b/go.mod index 5b92b741..7e5350e0 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ require ( github.com/shirou/gopsutil/v4 v4.24.6 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 + github.com/testcontainers/testcontainers-go v0.33.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 @@ -47,6 +49,7 @@ require ( github.com/containerd/containerd v1.7.18 // indirect github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containers/buildah v1.37.0 // indirect github.com/containers/common v0.60.0 // indirect @@ -56,8 +59,10 @@ require ( github.com/containers/psgo v1.9.0 // indirect github.com/containers/storage v1.55.0 // indirect github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect github.com/cyphar/filepath-securejoin v0.3.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/disiqueira/gotree/v3 v3.0.2 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/dlclark/regexp2 v1.11.0 // indirect @@ -121,7 +126,9 @@ require ( github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/user v0.2.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -139,6 +146,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/sftp v1.13.6 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/proglottis/gpgme v0.1.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect @@ -146,6 +154,7 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect github.com/segmentio/asm v1.2.0 // indirect + github.com/shirou/gopsutil/v3 v3.24.5 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sigstore/fulcio v1.4.5 // indirect github.com/sigstore/rekor v1.3.6 // indirect diff --git a/go.sum b/go.sum index a63f1a4d..6561885f 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -50,6 +52,8 @@ github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5Z github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containers/buildah v1.37.0 h1:jvHwu1vIwIqnHyOSg9eef9Apdpry+5oWLrm43gdf8Rk= @@ -71,6 +75,8 @@ github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbF github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09 h1:OoRAFlvDGCUqDLampLQjk0yeeSGdF9zzst/3G9IkBbc= github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09/go.mod h1:m2r/smMKsKwgMSAoFKHaa68ImdCSNuKE1MxvQ64xuCQ= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= @@ -283,8 +289,12 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/user v0.2.0 h1:OnpapJsRp25vkhw8TFG6OLJODNh/3rEwRWtJ3kakwRM= github.com/moby/sys/user v0.2.0/go.mod h1:RYstrcWOJpVh+6qzUqp2bU3eaRpdiQeKGlKitaH0PM8= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= @@ -366,6 +376,8 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= +github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= github.com/shirou/gopsutil/v4 v4.24.6 h1:9qqCSYF2pgOU+t+NgJtp7Co5+5mHF/HyKBUckySQL64= github.com/shirou/gopsutil/v4 v4.24.6/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -414,6 +426,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtse github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw= +github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= diff --git a/internal/logs/logs.go b/internal/logs/logs.go index 9e8484b5..29f92d54 100644 --- a/internal/logs/logs.go +++ b/internal/logs/logs.go @@ -22,6 +22,8 @@ func GetLogger(level string) *zerolog.Logger { zerolog.SetGlobalLevel(zerolog.FatalLevel) case "panic": zerolog.SetGlobalLevel(zerolog.PanicLevel) + case "disable": + zerolog.SetGlobalLevel(zerolog.Disabled) default: zerolog.SetGlobalLevel(zerolog.InfoLevel) } diff --git a/internal/odin/cmd/root.go b/internal/odin/cmd/root.go index 38877196..e4cede5d 100644 --- a/internal/odin/cmd/root.go +++ b/internal/odin/cmd/root.go @@ -32,6 +32,10 @@ func init() { } RootCmd.PersistentFlags().String("log-level", envConfig.ODIN_LOG_LEVEL, "Log level") + RootCmd.PersistentFlags().String("pg-user", envConfig.POSTGRES_USER, "Postgres user") + RootCmd.PersistentFlags().String("pg-password", envConfig.POSTGRES_PASSWORD, "Postgres password") + RootCmd.PersistentFlags().Uint32("pg-port", envConfig.POSTGRES_PORT, "Postgres port") + RootCmd.PersistentFlags().String("pg-db", envConfig.POSTGRES_DB, "Postgres database") RootCmd.AddCommand(server.ServerCmd) RootCmd.AddCommand(worker.WorkerCmd) diff --git a/internal/odin/cmd/server/start.go b/internal/odin/cmd/server/start.go index 7f731568..b1037290 100644 --- a/internal/odin/cmd/server/start.go +++ b/internal/odin/cmd/server/start.go @@ -1,6 +1,7 @@ package server import ( + "strconv" "sync" "github.com/spf13/cobra" @@ -24,7 +25,22 @@ func serverExec(cmd *cobra.Command, args []string) error { logger := logs.GetLogger(logLevel) logger.Info().Msg("Starting Odin in standalone mode") - envConfig, err := config.GetEnvConfig() + pg_user := cmd.Flag("pg-user").Value.String() + pg_password := cmd.Flag("pg-password").Value.String() + pg_port := cmd.Flag("pg-port").Value.String() + pg_port_int, err := strconv.ParseUint(pg_port, 10, 32) + if err != nil { + logger.Err(err).Msg("Failed to parse pg-port") + return err + } + pg_db := cmd.Flag("pg-db").Value.String() + + envConfig, err := config.GetEnvConfig( + config.WithPostgresDB(pg_db), + config.WithPostgresUser(pg_user), + config.WithPostgresPassword(pg_password), + config.WithPostgresPort(uint32(pg_port_int)), + ) if err != nil { logger.Err(err).Msg("Failed to get environment config") return err diff --git a/internal/odin/cmd/standalone.go b/internal/odin/cmd/standalone.go index 4e23a6be..dd8ef003 100644 --- a/internal/odin/cmd/standalone.go +++ b/internal/odin/cmd/standalone.go @@ -4,6 +4,7 @@ import ( "context" "os" "os/signal" + "strconv" "sync" "syscall" @@ -36,7 +37,22 @@ func standaloneExec(cmd *cobra.Command, args []string) error { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) - envConfig, err := config.GetEnvConfig() + pg_user := cmd.Flag("pg-user").Value.String() + pg_password := cmd.Flag("pg-password").Value.String() + pg_port := cmd.Flag("pg-port").Value.String() + pg_port_int, err := strconv.ParseUint(pg_port, 10, 32) + if err != nil { + logger.Err(err).Msg("Failed to parse pg-port") + return err + } + pg_db := cmd.Flag("pg-db").Value.String() + + envConfig, err := config.GetEnvConfig( + config.WithPostgresDB(pg_db), + config.WithPostgresUser(pg_user), + config.WithPostgresPassword(pg_password), + config.WithPostgresPort(uint32(pg_port_int)), + ) if err != nil { logger.Err(err).Msg("Failed to get environment config") return err diff --git a/internal/odin/cmd/worker/start.go b/internal/odin/cmd/worker/start.go index 7903abc3..22128c91 100644 --- a/internal/odin/cmd/worker/start.go +++ b/internal/odin/cmd/worker/start.go @@ -4,6 +4,7 @@ import ( "context" "os" "os/signal" + "strconv" "sync" "syscall" @@ -25,11 +26,28 @@ var WorkerStartCmd = &cobra.Command{ logLevel := cmd.Flag("log-level").Value.String() logger := logs.GetLogger(logLevel) logger.Info().Msg("Starting worker") - envConfig, err := config.GetEnvConfig() + + pg_user := cmd.Flag("pg-user").Value.String() + pg_password := cmd.Flag("pg-password").Value.String() + pg_port := cmd.Flag("pg-port").Value.String() + pg_port_int, err := strconv.ParseUint(pg_port, 10, 32) + if err != nil { + logger.Err(err).Msg("Failed to parse pg-port") + return err + } + pg_db := cmd.Flag("pg-db").Value.String() + + envConfig, err := config.GetEnvConfig( + config.WithPostgresDB(pg_db), + config.WithPostgresUser(pg_user), + config.WithPostgresPassword(pg_password), + config.WithPostgresPort(uint32(pg_port_int)), + ) if err != nil { logger.Err(err).Msg("Failed to get environment config") return err } + ctx, cancel := context.WithCancel(cmd.Context()) sigChan := make(chan os.Signal, 1) diff --git a/internal/odin/config/environment.go b/internal/odin/config/environment.go index b8b3fcb2..97515528 100644 --- a/internal/odin/config/environment.go +++ b/internal/odin/config/environment.go @@ -2,12 +2,45 @@ package config import ( "fmt" + "log" "os" "path/filepath" "github.com/spf13/viper" ) +type EnvOptsFunc func(*EnvConfig) + +func WithPostgresHost(host string) EnvOptsFunc { + return func(envConfig *EnvConfig) { + envConfig.POSTGRES_HOST = host + } +} + +func WithPostgresPort(port uint32) EnvOptsFunc { + return func(envConfig *EnvConfig) { + envConfig.POSTGRES_PORT = port + } +} + +func WithPostgresUser(user string) EnvOptsFunc { + return func(envConfig *EnvConfig) { + envConfig.POSTGRES_USER = user + } +} + +func WithPostgresPassword(password string) EnvOptsFunc { + return func(envConfig *EnvConfig) { + envConfig.POSTGRES_PASSWORD = password + } +} + +func WithPostgresDB(db string) EnvOptsFunc { + return func(envConfig *EnvConfig) { + envConfig.POSTGRES_DB = db + } +} + // Environment struct represents the configuration settings for the application. type EnvConfig struct { POSTGRES_HOST string `mapstructure:"POSTGRES_HOST"` // represents the PostgreSQL server host. @@ -47,7 +80,7 @@ type EnvConfig struct { // EnvConfig holds the configuration settings for the application. -func GetEnvConfig() (*EnvConfig, error) { +func GetEnvConfig(opts ...EnvOptsFunc) (*EnvConfig, error) { viper.SetConfigType("env") viper.AddConfigPath(".") viper.SetConfigName(".env") @@ -85,7 +118,7 @@ func GetEnvConfig() (*EnvConfig, error) { // Read configuration from file err := viper.ReadInConfig() if err != nil { - return nil, err + log.Println(".env file not found. Using default values.") } // Unmarshal configuration into EnvConfig struct @@ -103,5 +136,9 @@ func GetEnvConfig() (*EnvConfig, error) { EnvConfig.ODIN_INFO_DIR = fmt.Sprintf("%s/%s", EnvConfig.USER_HOME_DIR, ".odin") EnvConfig.ODIN_WORKER_DIR = fmt.Sprintf("%s/%s", EnvConfig.ODIN_INFO_DIR, "worker") EnvConfig.ODIN_WORKER_INFO_FILE = fmt.Sprintf("%s/%s", EnvConfig.ODIN_WORKER_DIR, "worker-info.json") + + for _, opt := range opts { + opt(&EnvConfig) + } return &EnvConfig, nil } diff --git a/internal/odin/server/execution_test.go b/internal/odin/server/execution_test.go index 58687202..d6dd6592 100644 --- a/internal/odin/server/execution_test.go +++ b/internal/odin/server/execution_test.go @@ -1 +1,91 @@ -package server_test +package server + +import ( + "context" + "net/http/httptest" + "testing" + + "github.com/deepakdinesh1123/valkyrie/internal/logs" + "github.com/deepakdinesh1123/valkyrie/internal/odin/config" + "github.com/deepakdinesh1123/valkyrie/pkg/odin/api" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + "github.com/testcontainers/testcontainers-go" +) + +type ExecutionSuite struct { + suite.Suite + envConfig *config.EnvConfig + logger *zerolog.Logger + odinServer *OdinServer + server *httptest.Server + workers []*testcontainers.Container +} + +func (s *ExecutionSuite) SetupSuite() { + envConfig, err := config.GetEnvConfig( + config.WithPostgresDB("test"), + config.WithPostgresUser("test"), + config.WithPostgresPassword("test"), + config.WithPostgresPort(5400), + ) + if err != nil { + s.T().Errorf("failed to get environment config -> %s", err) + } + + s.envConfig = envConfig + s.logger = logs.GetLogger("debug") + srv, err := NewServer(context.Background(), s.envConfig, false, true, s.logger) + if err != nil { + s.T().Errorf("failed to create server -> %s", err) + } + s.odinServer = srv + s.server = httptest.NewServer(srv.server) + + workerContainer, err := testcontainers.GenericContainer(context.TODO(), testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ + FromDockerfile: testcontainers.FromDockerfile{ + Context: "../../../.", + Dockerfile: "build/package/dockerfiles/odin.worker.dockerfile", + }, + }, + }) + if err != nil { + s.T().Errorf("failed to create worker container -> %s", err) + } + + s.workers = append(s.workers, &workerContainer) + err = workerContainer.Start(context.TODO()) + if err != nil { + s.T().Errorf("failed to start worker container -> %s", err) + } +} + +func (s *ExecutionSuite) TearDownSuite() { + s.server.Close() +} + +func (s *ExecutionSuite) TestExecute() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + client, err := api.NewClient(s.server.URL) + if err != nil { + s.T().Errorf("failed to create client -> %s", err) + } + res, err := client.Execute(ctx, &api.ExecutionRequest{ + Code: "print('hello')", + Language: "python", + }) + switch res := res.(type) { + case *api.ExecuteBadRequest: + s.T().Errorf("bad request -> %s", res.Message) + case *api.ExecuteInternalServerError: + s.T().Errorf("internal server error -> %s", res.Message) + } + assert.Nil(s.T(), err) +} +func TestExecutionSuite(t *testing.T) { + suite.Run(t, new(ExecutionSuite)) +}