- Change from 'go run ./cmd/{service}/main.go' to 'go run ./cmd/{service}/*.go'
- go run with single file doesn't include other files in the package
- Service implementations are in separate _fx.go files
- Using wildcard includes all .go files in the package
- Update README.md and SUMMARY.md with correct commands
- Fixes 'undefined: provideXService' errors when running services
157 lines
4.3 KiB
Go
157 lines
4.3 KiB
Go
// Package main provides tests for the API Gateway service entry point.
|
|
// Note: Full integration tests for the API Gateway should be in integration test suite
|
|
// with testcontainers for service discovery and backend services.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.dcentral.systems/toolz/goplt/internal/di"
|
|
"git.dcentral.systems/toolz/goplt/pkg/registry"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/fx"
|
|
)
|
|
|
|
// TestAPIGatewaySetup verifies that the API Gateway setup structure is correct.
|
|
// Note: Full DI setup requires config files, so this test verifies the structure
|
|
// without actually starting the container.
|
|
func TestAPIGatewaySetup(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Verify that container can be created
|
|
// Full setup requires config files which are not available in unit tests
|
|
container := di.NewContainer()
|
|
require.NotNil(t, container)
|
|
|
|
// Test that container can be stopped (without starting)
|
|
// This verifies the container structure is correct
|
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
|
defer cancel()
|
|
|
|
// Stop should work even if container wasn't started
|
|
err := container.Stop(ctx)
|
|
// It's okay if it errors - we're just testing structure
|
|
_ = err
|
|
}
|
|
|
|
// TestServiceInstanceCreation verifies that service instance is created correctly.
|
|
func TestServiceInstanceCreation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
host string
|
|
port int
|
|
expected string
|
|
}{
|
|
{
|
|
name: "default host and port",
|
|
host: "",
|
|
port: 0,
|
|
expected: "localhost:8080",
|
|
},
|
|
{
|
|
name: "custom host and port",
|
|
host: "gateway.example.com",
|
|
port: 9090,
|
|
expected: "gateway.example.com:9090",
|
|
},
|
|
{
|
|
name: "custom host default port",
|
|
host: "gateway.example.com",
|
|
port: 0,
|
|
expected: "gateway.example.com:8080",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Simulate service instance creation logic from main.go
|
|
gatewayPort := tt.port
|
|
if gatewayPort == 0 {
|
|
gatewayPort = 8080
|
|
}
|
|
gatewayHost := tt.host
|
|
if gatewayHost == "" {
|
|
gatewayHost = "localhost"
|
|
}
|
|
|
|
serviceInstance := ®istry.ServiceInstance{
|
|
ID: "api-gateway-test",
|
|
Name: "api-gateway",
|
|
Address: gatewayHost,
|
|
Port: gatewayPort,
|
|
Tags: []string{"gateway", "http"},
|
|
Metadata: map[string]string{
|
|
"version": "1.0.0",
|
|
},
|
|
}
|
|
|
|
assert.Equal(t, "api-gateway", serviceInstance.Name)
|
|
assert.Equal(t, gatewayHost, serviceInstance.Address)
|
|
assert.Equal(t, gatewayPort, serviceInstance.Port)
|
|
assert.Contains(t, serviceInstance.Tags, "gateway")
|
|
assert.Contains(t, serviceInstance.Tags, "http")
|
|
assert.Equal(t, "1.0.0", serviceInstance.Metadata["version"])
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestLifecycleHooksStructure verifies that lifecycle hooks can be registered.
|
|
// Note: Full lifecycle testing requires config files and should be done in integration tests.
|
|
func TestLifecycleHooksStructure(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var onStartCalled bool
|
|
var onStopCalled bool
|
|
|
|
// Create a test container with custom lifecycle hooks (without core module)
|
|
// This tests the hook registration mechanism
|
|
container := di.NewContainer(
|
|
fx.Invoke(func(lc fx.Lifecycle) {
|
|
lc.Append(fx.Hook{
|
|
OnStart: func(ctx context.Context) error {
|
|
onStartCalled = true
|
|
return nil
|
|
},
|
|
OnStop: func(ctx context.Context) error {
|
|
onStopCalled = true
|
|
return nil
|
|
},
|
|
})
|
|
}),
|
|
)
|
|
|
|
require.NotNil(t, container)
|
|
|
|
// Start the container to trigger OnStart
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
defer cancel()
|
|
|
|
// Start in goroutine since it blocks on signal
|
|
go func() {
|
|
_ = container.Start(ctx)
|
|
}()
|
|
|
|
// Give it a moment to start
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
// Stop to trigger OnStop
|
|
stopCtx, stopCancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
defer stopCancel()
|
|
|
|
err := container.Stop(stopCtx)
|
|
// Stop may error if container wasn't fully started, which is okay
|
|
_ = err
|
|
|
|
// Verify hooks were called
|
|
// Note: OnStart may not be called if container fails to start due to missing config
|
|
// This is expected in unit tests - full testing should be in integration tests
|
|
if onStartCalled {
|
|
assert.True(t, onStopCalled, "OnStop should be called if OnStart was called")
|
|
}
|
|
}
|