mirror of
https://github.com/juanfont/headscale.git
synced 2025-08-14 13:51:01 +02:00
cmd/hi: prevent concurrent runs and add force flag
Add mechanism to check for active test runs and prevent concurrent execution with helpful error message. Add --force flag to kill existing containers and force new run. Fixes duplicate run conflicts in integration testing.
This commit is contained in:
parent
044193bf34
commit
9603c36616
@ -1,14 +1,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/creachadair/command"
|
"github.com/creachadair/command"
|
||||||
|
"github.com/docker/docker/api/types/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrTestPatternRequired = errors.New("test pattern is required as first argument or use --test flag")
|
var ErrTestPatternRequired = errors.New("test pattern is required as first argument or use --test flag")
|
||||||
@ -24,6 +27,7 @@ type RunConfig struct {
|
|||||||
KeepOnFailure bool `flag:"keep-on-failure,default=false,Keep containers on test failure"`
|
KeepOnFailure bool `flag:"keep-on-failure,default=false,Keep containers on test failure"`
|
||||||
LogsDir string `flag:"logs-dir,default=control_logs,Control logs directory"`
|
LogsDir string `flag:"logs-dir,default=control_logs,Control logs directory"`
|
||||||
Verbose bool `flag:"verbose,default=false,Verbose output"`
|
Verbose bool `flag:"verbose,default=false,Verbose output"`
|
||||||
|
Force bool `flag:"force,default=false,Kill all containers and force run"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// runIntegrationTest executes the integration test workflow.
|
// runIntegrationTest executes the integration test workflow.
|
||||||
@ -41,6 +45,22 @@ func runIntegrationTest(env *command.Env) error {
|
|||||||
runConfig.GoVersion = detectGoVersion()
|
runConfig.GoVersion = detectGoVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for existing runs unless --force is used
|
||||||
|
if !runConfig.Force {
|
||||||
|
if activeRun, err := checkForActiveRun(env.Context()); err != nil {
|
||||||
|
return fmt.Errorf("failed to check for active runs: %w", err)
|
||||||
|
} else if activeRun != "" {
|
||||||
|
return fmt.Errorf("Another run is already running %s, wait for it to finish or use --force to kill all containers", activeRun)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if runConfig.Verbose {
|
||||||
|
log.Printf("Force flag enabled, killing all test containers...")
|
||||||
|
}
|
||||||
|
if err := killTestContainers(env.Context()); err != nil {
|
||||||
|
return fmt.Errorf("failed to force kill containers: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run pre-flight checks
|
// Run pre-flight checks
|
||||||
if runConfig.Verbose {
|
if runConfig.Verbose {
|
||||||
log.Printf("Running pre-flight system checks...")
|
log.Printf("Running pre-flight system checks...")
|
||||||
@ -120,3 +140,30 @@ func indexOf(s, substr string) int {
|
|||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkForActiveRun checks if there are any active test containers running.
|
||||||
|
func checkForActiveRun(ctx context.Context) (string, error) {
|
||||||
|
cli, err := createDockerClient()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to create Docker client: %w", err)
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
|
||||||
|
containers, err := cli.ContainerList(ctx, container.ListOptions{
|
||||||
|
All: false, // Only running containers
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to list containers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cont := range containers {
|
||||||
|
for _, name := range cont.Names {
|
||||||
|
containerName := strings.TrimPrefix(name, "/")
|
||||||
|
if strings.HasPrefix(containerName, "headscale-test-suite-") {
|
||||||
|
return containerName, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user