Files
gitea-tea/tests/integration/config_lock_unix_test.go

81 lines
1.7 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build unix
package integration
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"code.gitea.io/tea/modules/config"
)
func TestConfigLock_CrossProcess(t *testing.T) {
tmpDir, err := os.MkdirTemp("", "tea-lock-test")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.RemoveAll(tmpDir)
lockPath := filepath.Join(tmpDir, "config.yml.lock")
unlock, err := config.AcquireConfigLockForTesting(lockPath, 5*time.Second)
if err != nil {
t.Fatalf("failed to acquire lock: %v", err)
}
defer func() {
if err := unlock(); err != nil {
t.Fatalf("failed to release lock: %v", err)
}
}()
script := fmt.Sprintf(`
package main
import (
"os"
"syscall"
)
func main() {
file, err := os.OpenFile(%q, os.O_CREATE|os.O_RDWR, 0o600)
if err != nil {
os.Exit(2)
}
defer file.Close()
err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
if err != nil {
os.Exit(0)
}
syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
os.Exit(1)
}
`, lockPath)
scriptPath := filepath.Join(tmpDir, "locktest.go")
if err := os.WriteFile(scriptPath, []byte(script), 0o600); err != nil {
t.Fatalf("failed to write test script: %v", err)
}
cmd := exec.Command("go", "run", scriptPath)
if err := cmd.Run(); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if exitErr.ExitCode() == 1 {
t.Error("subprocess acquired lock when it should have been held")
} else if exitErr.ExitCode() == 2 {
t.Errorf("subprocess failed to open lock file: %v", err)
}
} else {
t.Errorf("subprocess execution failed: %v", err)
}
}
}