fix(docs): Fix service run commands to include all package files
- 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
This commit is contained in:
@@ -117,10 +117,10 @@ docker-compose -f docker-compose.dev.yml up -d
|
|||||||
docker-compose -f docker-compose.dev.yml ps
|
docker-compose -f docker-compose.dev.yml ps
|
||||||
|
|
||||||
# Start services locally (in separate terminals)
|
# Start services locally (in separate terminals)
|
||||||
go run ./cmd/auth-service/main.go # Port 8081
|
go run ./cmd/auth-service/*.go # Port 8081
|
||||||
go run ./cmd/identity-service/main.go # Port 8082
|
go run ./cmd/identity-service/*.go # Port 8082
|
||||||
go run ./cmd/authz-service/main.go # Port 8083
|
go run ./cmd/authz-service/*.go # Port 8083
|
||||||
go run ./cmd/audit-service/main.go # Port 8084
|
go run ./cmd/audit-service/*.go # Port 8084
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Option 2: Full Docker Deployment
|
#### Option 2: Full Docker Deployment
|
||||||
|
|||||||
156
cmd/api-gateway/main_test.go
Normal file
156
cmd/api-gateway/main_test.go
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -196,16 +196,16 @@ Then start services locally:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Terminal 1: Auth Service
|
# Terminal 1: Auth Service
|
||||||
go run ./cmd/auth-service/main.go
|
go run ./cmd/auth-service/*.go
|
||||||
|
|
||||||
# Terminal 2: Identity Service
|
# Terminal 2: Identity Service
|
||||||
go run ./cmd/identity-service/main.go
|
go run ./cmd/identity-service/*.go
|
||||||
|
|
||||||
# Terminal 3: Authz Service
|
# Terminal 3: Authz Service
|
||||||
go run ./cmd/authz-service/main.go
|
go run ./cmd/authz-service/*.go
|
||||||
|
|
||||||
# Terminal 4: Audit Service
|
# Terminal 4: Audit Service
|
||||||
go run ./cmd/audit-service/main.go
|
go run ./cmd/audit-service/*.go
|
||||||
```
|
```
|
||||||
|
|
||||||
### Option 2: Full Docker Compose (All Services in Docker)
|
### Option 2: Full Docker Compose (All Services in Docker)
|
||||||
|
|||||||
Reference in New Issue
Block a user