2021-03-19 19:05:45 +01:00
|
|
|
package procmon
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
2021-03-24 01:16:47 +01:00
|
|
|
"time"
|
2021-03-19 19:05:45 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestCacheProcs(t *testing.T) {
|
|
|
|
fdList := []string{"0", "1", "2"}
|
2021-07-21 15:04:23 +02:00
|
|
|
pidsCache.add(fmt.Sprint("/proc/", myPid, "/fd/"), fdList, myPid)
|
|
|
|
t.Log("Pids in cache: ", pidsCache.countItems())
|
2021-03-19 19:05:45 +01:00
|
|
|
|
|
|
|
t.Run("Test addProcEntry", func(t *testing.T) {
|
2021-07-21 15:04:23 +02:00
|
|
|
if pidsCache.countItems() != 1 {
|
2021-03-19 19:05:45 +01:00
|
|
|
t.Error("pidsCache should be 1")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-07-21 15:04:23 +02:00
|
|
|
oldPid := pidsCache.getItem(0)
|
|
|
|
pidsCache.add(fmt.Sprint("/proc/", myPid, "/fd/"), fdList, myPid)
|
2021-03-19 19:05:45 +01:00
|
|
|
t.Run("Test addProcEntry update", func(t *testing.T) {
|
2021-07-21 15:04:23 +02:00
|
|
|
if pidsCache.countItems() != 1 {
|
|
|
|
t.Error("pidsCache should still be 1!", pidsCache)
|
2021-03-19 19:05:45 +01:00
|
|
|
}
|
2021-03-24 01:16:47 +01:00
|
|
|
oldTime := time.Unix(0, oldPid.LastSeen)
|
2021-07-21 15:04:23 +02:00
|
|
|
newTime := time.Unix(0, pidsCache.getItem(0).LastSeen)
|
2021-03-24 01:16:47 +01:00
|
|
|
if oldTime.Equal(newTime) == false {
|
|
|
|
t.Error("pidsCache, time not updated: ", oldTime, newTime)
|
2021-03-19 19:05:45 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-07-21 15:04:23 +02:00
|
|
|
pidsCache.add("/proc/2/fd", fdList, 2)
|
|
|
|
pidsCache.delete(2)
|
2021-03-19 19:05:45 +01:00
|
|
|
t.Run("Test deleteProcEntry", func(t *testing.T) {
|
2021-07-21 15:04:23 +02:00
|
|
|
if pidsCache.countItems() != 1 {
|
|
|
|
t.Error("pidsCache should be 1:", pidsCache.countItems())
|
2021-03-19 19:05:45 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-07-21 15:04:23 +02:00
|
|
|
pid, _ := pidsCache.getPid(0, "", "/dev/null")
|
2021-03-19 19:05:45 +01:00
|
|
|
t.Run("Test getPidFromCache", func(t *testing.T) {
|
|
|
|
if pid != myPid {
|
2021-07-21 15:04:23 +02:00
|
|
|
t.Error("pid not found in cache", pidsCache.countItems())
|
2021-03-19 19:05:45 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-08-11 14:00:23 +02:00
|
|
|
// should not crash, and the number of items should still be 1
|
|
|
|
pidsCache.deleteItem(1)
|
|
|
|
t.Run("Test deleteItem check bounds", func(t *testing.T) {
|
|
|
|
if pidsCache.countItems() != 1 {
|
|
|
|
t.Error("deleteItem check bounds error", pidsCache.countItems())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
pidsCache.deleteItem(0)
|
|
|
|
t.Run("Test deleteItem", func(t *testing.T) {
|
|
|
|
if pidsCache.countItems() != 0 {
|
|
|
|
t.Error("deleteItem error", pidsCache.countItems())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
t.Log("items in cache:", pidsCache.countItems())
|
|
|
|
|
2021-03-24 01:16:47 +01:00
|
|
|
// the key of an inodeCache entry is formed as: inodeNumer + srcIP + srcPort + dstIP + dstPort
|
|
|
|
inodeKey := "000000000127.0.0.144444127.0.0.153"
|
2021-07-21 15:04:23 +02:00
|
|
|
// add() expects a path to the inode fd (/proc/<pid>/fd/12345), but as getPid() will check the path in order to retrieve the pid,
|
|
|
|
// we just set it to "" and it'll use /proc/<pid>/exe
|
|
|
|
inodesCache.add(inodeKey, "", myPid)
|
2021-03-24 01:16:47 +01:00
|
|
|
t.Run("Test addInodeEntry", func(t *testing.T) {
|
2021-07-21 15:04:23 +02:00
|
|
|
if _, found := inodesCache.items[inodeKey]; !found {
|
|
|
|
t.Error("inodesCache, inode not added:", len(inodesCache.items), inodesCache.items)
|
2021-03-24 01:16:47 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-07-21 15:04:23 +02:00
|
|
|
pid = inodesCache.getPid(inodeKey)
|
2021-03-24 01:16:47 +01:00
|
|
|
t.Run("Test getPidByInodeFromCache", func(t *testing.T) {
|
|
|
|
if pid != myPid {
|
2021-07-21 15:04:23 +02:00
|
|
|
t.Error("inode not found in cache", pid, inodeKey, len(inodesCache.items), inodesCache.items)
|
2021-03-24 01:16:47 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// should delete all inodes of a pid
|
2021-07-21 15:04:23 +02:00
|
|
|
inodesCache.delete(myPid)
|
2021-03-24 01:16:47 +01:00
|
|
|
t.Run("Test deleteInodeEntry", func(t *testing.T) {
|
2021-07-21 15:04:23 +02:00
|
|
|
if _, found := inodesCache.items[inodeKey]; found {
|
|
|
|
t.Error("inodesCache, key found in cache but it should not exist", inodeKey, len(inodesCache.items), inodesCache.items)
|
2021-03-19 19:05:45 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test getPidDescriptorsFromCache descriptors (inodes) reordering.
|
|
|
|
// When an inode (descriptor) is found, if it's pushed to the top of the list,
|
|
|
|
// the next time we look for it will cost -10x.
|
|
|
|
// Without reordering, the inode 0 will always be found on the 10th position,
|
|
|
|
// taking an average of 100us instead of 30.
|
|
|
|
// Benchmark results with reordering: ~5600ns/op, without: ~56000ns/op.
|
|
|
|
func BenchmarkGetPid(b *testing.B) {
|
|
|
|
fdList := []string{"10", "9", "8", "7", "6", "5", "4", "3", "2", "1", "0"}
|
2021-07-21 15:04:23 +02:00
|
|
|
pidsCache.add(fmt.Sprint("/proc/", myPid, "/fd/"), fdList, myPid)
|
2021-03-19 19:05:45 +01:00
|
|
|
for i := 0; i < b.N; i++ {
|
2021-07-21 15:04:23 +02:00
|
|
|
pidsCache.getPid(0, "", "/dev/null")
|
2021-03-19 19:05:45 +01:00
|
|
|
}
|
|
|
|
}
|