package env
import (
"fmt"
"net"
"os"
"path/filepath"
"time"
)
type Sandbox struct {
ID string RootDir string ConfigDir string SocketDir string ConsolePort int Env map[string]string
}
func NewSandbox() (*Sandbox, error) {
rootDir, err := os.MkdirTemp("", "vane_test_*")
if err != nil {
return nil, fmt.Errorf("failed to create temp root: %w", err)
}
configDir := filepath.Join(rootDir, "config")
socketDir := filepath.Join(rootDir, "socket")
subDirs := []string{
"listener",
"application",
"resolver",
"certs",
}
for _, sub := range subDirs {
path := filepath.Join(configDir, sub)
if err := os.MkdirAll(path, 0755); err != nil {
os.RemoveAll(rootDir) return nil, fmt.Errorf("failed to create config subdir %s: %w", sub, err)
}
}
if err := os.MkdirAll(socketDir, 0755); err != nil {
os.RemoveAll(rootDir)
return nil, fmt.Errorf("failed to create socket dir: %w", err)
}
port, err := GetFreePort()
if err != nil {
os.RemoveAll(rootDir)
return nil, fmt.Errorf("failed to allocate console port: %w", err)
}
return &Sandbox{
ID: filepath.Base(rootDir),
RootDir: rootDir,
ConfigDir: configDir,
SocketDir: socketDir,
ConsolePort: port,
Env: make(map[string]string),
}, nil
}
func (s *Sandbox) Cleanup() {
if s.RootDir != "" {
os.RemoveAll(s.RootDir)
}
}
func (s *Sandbox) WriteConfig(relativePath string, content []byte) error {
fullPath := filepath.Join(s.ConfigDir, relativePath)
dir := filepath.Dir(fullPath)
if err := os.MkdirAll(dir, 0755); err != nil {
return err
}
return os.WriteFile(fullPath, content, 0644)
}
func (s *Sandbox) ConnectConsole() (net.Conn, error) {
return net.DialTimeout("tcp", fmt.Sprintf("127.0.0.1:%d", s.ConsolePort), 500*time.Millisecond)
}