Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions dbos/dbos.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ type Config struct {
AdminServer bool
}

// ProcessConfig merges configuration from two sources in order of precedence:
// processConfig merges configuration from two sources in order of precedence:
// 1. programmatic configuration
// 2. environment variables
// Finally, it applies default values if needed.
func ProcessConfig(inputConfig *Config) (*Config, error) {
func processConfig(inputConfig *Config) (*Config, error) {
// First check required fields
if len(inputConfig.DatabaseURL) == 0 {
return nil, fmt.Errorf("missing required config field: databaseURL")
Expand Down Expand Up @@ -133,7 +133,7 @@ func Initialize(inputConfig Config) error {
}

// Load & process the configuration
config, err := ProcessConfig(&inputConfig)
config, err := processConfig(&inputConfig)
if err != nil {
return newInitializationError(err.Error())
}
Expand Down
87 changes: 87 additions & 0 deletions dbos/dbos_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package dbos

import (
"context"
"encoding/hex"
"maps"
"testing"
)

func TestConfigValidationErrorTypes(t *testing.T) {
databaseURL := getDatabaseURL(t)

t.Run("FailsWithoutAppName", func(t *testing.T) {
config := Config{
DatabaseURL: databaseURL,
}

err := Initialize(config)
if err == nil {
t.Fatal("expected error when app name is missing, but got none")
}

dbosErr, ok := err.(*DBOSError)
if !ok {
t.Fatalf("expected DBOSError, got %T", err)
}

if dbosErr.Code != InitializationError {
t.Fatalf("expected InitializationError code, got %v", dbosErr.Code)
}

expectedMsg := "Error initializing DBOS Transact: missing required config field: appName"
if dbosErr.Message != expectedMsg {
t.Fatalf("expected error message '%s', got '%s'", expectedMsg, dbosErr.Message)
}
})

t.Run("FailsWithoutDatabaseURL", func(t *testing.T) {
config := Config{
AppName: "test-app",
}

err := Initialize(config)
if err == nil {
t.Fatal("expected error when database URL is missing, but got none")
}

dbosErr, ok := err.(*DBOSError)
if !ok {
t.Fatalf("expected DBOSError, got %T", err)
}

if dbosErr.Code != InitializationError {
t.Fatalf("expected InitializationError code, got %v", dbosErr.Code)
}

expectedMsg := "Error initializing DBOS Transact: missing required config field: databaseURL"
if dbosErr.Message != expectedMsg {
t.Fatalf("expected error message '%s', got '%s'", expectedMsg, dbosErr.Message)
}
})
}
func TestAppVersion(t *testing.T) {
if _, err := hex.DecodeString(_APP_VERSION); err != nil {
t.Fatalf("APP_VERSION is not a valid hex string: %v", err)
}

// Save the original registry content
originalRegistry := make(map[string]workflowRegistryEntry)
maps.Copy(originalRegistry, registry)

// Restore the registry after the test
defer func() {
registry = originalRegistry
}()

// Replace the registry and verify the hash is different
registry = make(map[string]workflowRegistryEntry)

WithWorkflow(func(ctx context.Context, input string) (string, error) {
return "new-registry-workflow-" + input, nil
})
hash2 := computeApplicationVersion()
if _APP_VERSION == hash2 {
t.Fatalf("APP_VERSION hash did not change after replacing registry")
}
}
Loading