mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			126 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"log"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/creachadair/command"
 | 
						|
)
 | 
						|
 | 
						|
var ErrTestPatternRequired = errors.New("test pattern is required as first argument or use --test flag")
 | 
						|
 | 
						|
type RunConfig struct {
 | 
						|
	TestPattern   string        `flag:"test,Test pattern to run"`
 | 
						|
	Timeout       time.Duration `flag:"timeout,default=120m,Test timeout"`
 | 
						|
	FailFast      bool          `flag:"failfast,default=true,Stop on first test failure"`
 | 
						|
	UsePostgres   bool          `flag:"postgres,default=false,Use PostgreSQL instead of SQLite"`
 | 
						|
	GoVersion     string        `flag:"go-version,Go version to use (auto-detected from go.mod)"`
 | 
						|
	CleanBefore   bool          `flag:"clean-before,default=true,Clean resources before test"`
 | 
						|
	CleanAfter    bool          `flag:"clean-after,default=true,Clean resources after test"`
 | 
						|
	KeepOnFailure bool          `flag:"keep-on-failure,default=false,Keep containers on test failure"`
 | 
						|
	LogsDir       string        `flag:"logs-dir,default=control_logs,Control logs directory"`
 | 
						|
	Verbose       bool          `flag:"verbose,default=false,Verbose output"`
 | 
						|
	Stats           bool          `flag:"stats,default=false,Collect and display container resource usage statistics"`
 | 
						|
	HSMemoryLimit   float64       `flag:"hs-memory-limit,default=0,Fail test if any Headscale container exceeds this memory limit in MB (0 = disabled)"`
 | 
						|
	TSMemoryLimit   float64       `flag:"ts-memory-limit,default=0,Fail test if any Tailscale container exceeds this memory limit in MB (0 = disabled)"`
 | 
						|
}
 | 
						|
 | 
						|
// runIntegrationTest executes the integration test workflow.
 | 
						|
func runIntegrationTest(env *command.Env) error {
 | 
						|
	args := env.Args
 | 
						|
	if len(args) > 0 && runConfig.TestPattern == "" {
 | 
						|
		runConfig.TestPattern = args[0]
 | 
						|
	}
 | 
						|
 | 
						|
	if runConfig.TestPattern == "" {
 | 
						|
		return ErrTestPatternRequired
 | 
						|
	}
 | 
						|
 | 
						|
	if runConfig.GoVersion == "" {
 | 
						|
		runConfig.GoVersion = detectGoVersion()
 | 
						|
	}
 | 
						|
 | 
						|
	// Run pre-flight checks
 | 
						|
	if runConfig.Verbose {
 | 
						|
		log.Printf("Running pre-flight system checks...")
 | 
						|
	}
 | 
						|
	if err := runDoctorCheck(env.Context()); err != nil {
 | 
						|
		return fmt.Errorf("pre-flight checks failed: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	if runConfig.Verbose {
 | 
						|
		log.Printf("Running test: %s", runConfig.TestPattern)
 | 
						|
		log.Printf("Go version: %s", runConfig.GoVersion)
 | 
						|
		log.Printf("Timeout: %s", runConfig.Timeout)
 | 
						|
		log.Printf("Use PostgreSQL: %t", runConfig.UsePostgres)
 | 
						|
	}
 | 
						|
 | 
						|
	return runTestContainer(env.Context(), &runConfig)
 | 
						|
}
 | 
						|
 | 
						|
// detectGoVersion reads the Go version from go.mod file.
 | 
						|
func detectGoVersion() string {
 | 
						|
	goModPath := filepath.Join("..", "..", "go.mod")
 | 
						|
 | 
						|
	if _, err := os.Stat("go.mod"); err == nil {
 | 
						|
		goModPath = "go.mod"
 | 
						|
	} else if _, err := os.Stat("../../go.mod"); err == nil {
 | 
						|
		goModPath = "../../go.mod"
 | 
						|
	}
 | 
						|
 | 
						|
	content, err := os.ReadFile(goModPath)
 | 
						|
	if err != nil {
 | 
						|
		return "1.24"
 | 
						|
	}
 | 
						|
 | 
						|
	lines := splitLines(string(content))
 | 
						|
	for _, line := range lines {
 | 
						|
		if len(line) > 3 && line[:3] == "go " {
 | 
						|
			version := line[3:]
 | 
						|
			if idx := indexOf(version, " "); idx != -1 {
 | 
						|
				version = version[:idx]
 | 
						|
			}
 | 
						|
 | 
						|
			return version
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return "1.24"
 | 
						|
}
 | 
						|
 | 
						|
// splitLines splits a string into lines without using strings.Split.
 | 
						|
func splitLines(s string) []string {
 | 
						|
	var lines []string
 | 
						|
	var current string
 | 
						|
 | 
						|
	for _, char := range s {
 | 
						|
		if char == '\n' {
 | 
						|
			lines = append(lines, current)
 | 
						|
			current = ""
 | 
						|
		} else {
 | 
						|
			current += string(char)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if current != "" {
 | 
						|
		lines = append(lines, current)
 | 
						|
	}
 | 
						|
 | 
						|
	return lines
 | 
						|
}
 | 
						|
 | 
						|
// indexOf finds the first occurrence of substr in s.
 | 
						|
func indexOf(s, substr string) int {
 | 
						|
	for i := 0; i <= len(s)-len(substr); i++ {
 | 
						|
		if s[i:i+len(substr)] == substr {
 | 
						|
			return i
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return -1
 | 
						|
}
 |