mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-21 17:21:09 +01:00
149 lines
4.1 KiB
Go
149 lines
4.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"runtime"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/crawlab-team/crawlab/core/utils"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
// TestRunner_ZombieProcessPrevention tests the zombie process prevention mechanisms
|
|
func TestRunner_ZombieProcessPrevention(t *testing.T) {
|
|
r := &Runner{
|
|
tid: primitive.NewObjectID(),
|
|
pid: 12345, // Mock PID
|
|
Logger: utils.NewLogger("TestTaskRunner"),
|
|
}
|
|
|
|
// Initialize context
|
|
r.ctx, r.cancel = context.WithCancel(context.Background())
|
|
defer r.cancel()
|
|
|
|
// Test that process group configuration is set on Unix systems
|
|
if runtime.GOOS != "windows" {
|
|
// This would normally be tested in an integration test with actual process spawning
|
|
t.Log("✅ Process group configuration available for Unix systems")
|
|
}
|
|
|
|
// Test zombie cleanup methods exist and can be called
|
|
r.cleanupOrphanedProcesses() // Should not panic
|
|
t.Log("✅ Zombie cleanup methods callable without panic")
|
|
|
|
// Test process group killing method
|
|
if runtime.GOOS != "windows" {
|
|
r.killProcessGroup() // Should handle invalid PID gracefully
|
|
t.Log("✅ Process group killing handles invalid PID gracefully")
|
|
}
|
|
}
|
|
|
|
// TestRunner_ProcessGroupManagement tests process group creation
|
|
func TestRunner_ProcessGroupManagement(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("Process groups not supported on Windows")
|
|
}
|
|
|
|
r := &Runner{
|
|
tid: primitive.NewObjectID(),
|
|
Logger: utils.NewLogger("TestTaskRunner"),
|
|
}
|
|
|
|
// Initialize context
|
|
r.ctx, r.cancel = context.WithCancel(context.Background())
|
|
defer r.cancel()
|
|
|
|
// Test that the process group setup logic doesn't panic
|
|
// We can't actually test configureCmd without proper task/spider setup
|
|
// but we can test that the syscall configuration is properly set
|
|
|
|
// Test process group killing with invalid PID (should not crash)
|
|
r.pid = -1 // Invalid PID
|
|
r.killProcessGroup() // Should handle gracefully
|
|
|
|
t.Log("✅ Process group management methods handle edge cases properly")
|
|
}
|
|
|
|
// TestRunner_ZombieMonitor tests the zombie monitoring functionality
|
|
func TestRunner_ZombieMonitor(t *testing.T) {
|
|
r := &Runner{
|
|
tid: primitive.NewObjectID(),
|
|
Logger: utils.NewLogger("TestTaskRunner"),
|
|
}
|
|
|
|
// Initialize context
|
|
r.ctx, r.cancel = context.WithCancel(context.Background())
|
|
|
|
// Start zombie monitor
|
|
r.startZombieMonitor()
|
|
|
|
// Let it run briefly
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// Cancel and cleanup
|
|
r.cancel()
|
|
|
|
t.Log("✅ Zombie monitor starts and stops cleanly")
|
|
}
|
|
|
|
// TestRunner_OrphanedProcessCleanup tests orphaned process detection
|
|
func TestRunner_OrphanedProcessCleanup(t *testing.T) {
|
|
r := &Runner{
|
|
tid: primitive.NewObjectID(),
|
|
Logger: utils.NewLogger("TestTaskRunner"),
|
|
}
|
|
|
|
// Initialize context
|
|
r.ctx, r.cancel = context.WithCancel(context.Background())
|
|
defer r.cancel()
|
|
|
|
// Test scanning for orphaned processes (should not find any in test environment)
|
|
r.scanAndKillChildProcesses()
|
|
|
|
t.Log("✅ Orphaned process scanning completes without error")
|
|
}
|
|
|
|
// TestRunner_SignalHandling tests signal handling for process groups
|
|
func TestRunner_SignalHandling(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("Signal handling test not applicable on Windows")
|
|
}
|
|
|
|
r := &Runner{
|
|
tid: primitive.NewObjectID(),
|
|
pid: os.Getpid(), // Use current process PID for testing
|
|
Logger: utils.NewLogger("TestTaskRunner"),
|
|
}
|
|
|
|
// Test that signal sending doesn't crash
|
|
// Note: This sends signals to our own process group, which should be safe
|
|
err := syscall.Kill(-r.pid, syscall.Signal(0)) // Signal 0 tests if process exists
|
|
if err != nil {
|
|
t.Logf("Signal test returned expected error: %v", err)
|
|
}
|
|
|
|
t.Log("✅ Signal handling functionality works")
|
|
}
|
|
|
|
// BenchmarkRunner_ZombieCheck benchmarks zombie process checking
|
|
func BenchmarkRunner_ZombieCheck(b *testing.B) {
|
|
r := &Runner{
|
|
tid: primitive.NewObjectID(),
|
|
pid: os.Getpid(),
|
|
Logger: utils.NewLogger("BenchmarkTaskRunner"),
|
|
}
|
|
|
|
// Initialize context
|
|
r.ctx, r.cancel = context.WithCancel(context.Background())
|
|
defer r.cancel()
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
r.checkForZombieProcesses()
|
|
}
|
|
}
|