File: activepids_test.go

package info (click to toggle)
opensnitch 1.6.9-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,980 kB
  • sloc: python: 12,604; ansic: 1,965; sh: 435; makefile: 239; xml: 50; sql: 3
file content (104 lines) | stat: -rw-r--r-- 3,099 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package procmon

import (
	"fmt"
	"math/rand"
	"os"
	"os/exec"
	"syscall"
	"testing"
	"time"
)

//TestMonitorActivePids starts helper processes, adds them to activePids
//and then kills them and checks if monitorActivePids() removed the killed processes
//from activePids
func TestMonitorActivePids(t *testing.T) {

	if os.Getenv("helperBinaryMode") == "on" {
		//we are in the "helper binary" mode, we were started with helperCmd.Start() (see below)
		//do nothing, just wait to be killed
		time.Sleep(time.Second * 10)
		os.Exit(1) //will never get here; but keep it here just in case
	}

	//we are in a normal "go test" mode
	tmpDir := "/tmp/ostest_" + randString()
	os.Mkdir(tmpDir, 0777)
	fmt.Println("tmp dir", tmpDir)
	defer os.RemoveAll(tmpDir)

	go MonitorActivePids()

	//build a "helper binary" with "go test -c -o /tmp/path" and put it into a tmp dir
	helperBinaryPath := tmpDir + "/helper1"
	goExecutable, _ := exec.LookPath("go")
	cmd := exec.Command(goExecutable, "test", "-c", "-o", helperBinaryPath)
	if err := cmd.Run(); err != nil {
		t.Error("Error running go test -c", err)
	}

	var numberOfHelpers = 5
	var helperProcs []*Process
	//start helper binaries
	for i := 0; i < numberOfHelpers; i++ {
		var helperCmd *exec.Cmd
		helperCmd = &exec.Cmd{
			Path: helperBinaryPath,
			Args: []string{helperBinaryPath},
			Env:  []string{"helperBinaryMode=on"},
		}
		if err := helperCmd.Start(); err != nil {
			t.Error("Error starting helper binary", err)
		}
		go func() {
			helperCmd.Wait() //must Wait(), otherwise the helper process becomes a zombie when kill()ed
		}()

		pid := helperCmd.Process.Pid
		proc := NewProcess(pid, helperBinaryPath)
		helperProcs = append(helperProcs, proc)
		AddToActivePidsCache(uint64(pid), proc)
	}
	//sleep to make sure all processes started before we proceed
	time.Sleep(time.Second * 1)
	//make sure all PIDS are in the cache
	for i := 0; i < numberOfHelpers; i++ {
		proc := helperProcs[i]
		pid := proc.ID
		foundProc := findProcessInActivePidsCache(uint64(pid))
		if foundProc == nil {
			t.Error("PID not found among active processes", pid)
		}
		if proc.Path != foundProc.Path || proc.ID != foundProc.ID {
			t.Error("PID or path doesn't match with the found process")
		}
	}
	//kill all helpers except for one
	for i := 0; i < numberOfHelpers-1; i++ {
		if err := syscall.Kill(helperProcs[i].ID, syscall.SIGTERM); err != nil {
			t.Error("error in syscall.Kill", err)
		}
	}
	//give the cache time to remove killed processes
	time.Sleep(time.Second * 1)

	//make sure only the alive process is in the cache
	foundProc := findProcessInActivePidsCache(uint64(helperProcs[numberOfHelpers-1].ID))
	if foundProc == nil {
		t.Error("last alive PID is not found among active processes", foundProc)
	}
	if len(activePids) != 1 {
		t.Error("more than 1 active PIDs left in cache")
	}
}

func randString() string {
	rand.Seed(time.Now().UnixNano())
	var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
	b := make([]rune, 10)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}