mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
Keep a cache of open files, reducing the number of open/close cycles in the /proc dir
This commit is contained in:
@@ -1,24 +1,37 @@
|
||||
package proc_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/weaveworks/scope/probe/proc"
|
||||
"github.com/weaveworks/scope/test"
|
||||
)
|
||||
|
||||
type mockedProcess struct {
|
||||
ID, Comm, Cmdline string
|
||||
}
|
||||
|
||||
func (p mockedProcess) Name() string { return p.ID }
|
||||
func (p mockedProcess) Size() int64 { return 0 }
|
||||
func (p mockedProcess) Mode() os.FileMode { return 0 }
|
||||
func (p mockedProcess) ModTime() time.Time { return time.Now() }
|
||||
func (p mockedProcess) IsDir() bool { return true }
|
||||
func (p mockedProcess) Sys() interface{} { return nil }
|
||||
|
||||
func TestProcReaderProcesses(t *testing.T) {
|
||||
processes := map[string]proc.MockedProcess{
|
||||
"3": {Id: "3", Comm: "curl\n", Cmdline: "curl\000google.com"},
|
||||
"2": {Id: "2", Comm: "bash\n"},
|
||||
"4": {Id: "4", Comm: "apache\n"},
|
||||
"notapid": {Id: "notapid"},
|
||||
"1": {Id: "1", Comm: "init\n"},
|
||||
processes := map[string]mockedProcess{
|
||||
"3": {ID: "3", Comm: "curl\n", Cmdline: "curl\000google.com"},
|
||||
"2": {ID: "2", Comm: "bash\n"},
|
||||
"4": {ID: "4", Comm: "apache\n"},
|
||||
"notapid": {ID: "notapid"},
|
||||
"1": {ID: "1", Comm: "init\n"},
|
||||
}
|
||||
|
||||
want := map[int]proc.Process{
|
||||
@@ -29,17 +42,16 @@ func TestProcReaderProcesses(t *testing.T) {
|
||||
}
|
||||
|
||||
// use a mocked /proc that reads from our mocked processes
|
||||
procDir := proc.MockedProcDir{
|
||||
ReadDirFunc: func(path string) ([]os.FileInfo, error) {
|
||||
result := []os.FileInfo{}
|
||||
for _, p := range processes {
|
||||
result = append(result, p)
|
||||
procDir := mockedDir{
|
||||
ReadDirNamesFunc: func(path string) ([]string, error) {
|
||||
result := []string{}
|
||||
for k := range processes {
|
||||
result = append(result, k)
|
||||
}
|
||||
return result, nil
|
||||
},
|
||||
|
||||
ReadFileFunc: func(path string) ([]byte, error) {
|
||||
splits := strings.Split(path, "/")
|
||||
OpenFunc: func(filename string) (proc.File, error) {
|
||||
splits := strings.Split(filename, "/")
|
||||
pid := splits[len(splits)-2]
|
||||
process, ok := processes[pid]
|
||||
if !ok {
|
||||
@@ -47,22 +59,30 @@ func TestProcReaderProcesses(t *testing.T) {
|
||||
}
|
||||
|
||||
file := splits[len(splits)-1]
|
||||
var content []byte
|
||||
switch file {
|
||||
case "comm":
|
||||
return []byte(process.Comm), nil
|
||||
content = []byte(process.Comm)
|
||||
case "stat":
|
||||
pid, _ := strconv.Atoi(splits[len(splits)-2])
|
||||
parent := pid - 1
|
||||
return []byte(fmt.Sprintf("%d na R %d 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1", pid, parent)), nil
|
||||
content = []byte(fmt.Sprintf("%d na R %d 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1", pid, parent))
|
||||
case "cmdline":
|
||||
return []byte(process.Cmdline), nil
|
||||
content = []byte(process.Cmdline)
|
||||
default:
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not found")
|
||||
return mockedFile{
|
||||
ReadIntoFunc: func(buf *bytes.Buffer) error {
|
||||
_, err := buf.Write(content)
|
||||
return err
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
procReader := proc.NewProcReader(procDir)
|
||||
procReader := proc.NewReader(procDir)
|
||||
have := map[int]proc.Process{}
|
||||
err := procReader.Processes(func(p proc.Process) {
|
||||
have[p.PID] = p
|
||||
|
||||
Reference in New Issue
Block a user