// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package procstats import ( "math/rand" "testing" "github.com/mitchellh/go-ps" "github.com/shoenig/test/must" ) type mockProcess struct { pid int ppid int } func (p *mockProcess) Pid() int { return p.pid } func (p *mockProcess) PPid() int { return p.ppid } func (p *mockProcess) Executable() string { return "" } func mockProc(pid, ppid int) *mockProcess { return &mockProcess{pid: pid, ppid: ppid} } func genMockProcs(needles, haystack int) ([]ps.Process, []ProcessID) { procs := []ps.Process{mockProc(1, 1), mockProc(42, 1)} expect := []ProcessID{42} // TODO: make this into a tree structure, not just a linear tree for i := range needles { parent := 42 + i pid := parent + 1 procs = append(procs, mockProc(pid, parent)) expect = append(expect, pid) } for i := range haystack { parent := 200 + i pid := parent + 1 procs = append(procs, mockProc(pid, parent)) } rand.Shuffle(len(procs), func(i, j int) { procs[i], procs[j] = procs[j], procs[i] }) return procs, expect } func Test_list(t *testing.T) { cases := []struct { name string needles int haystack int }{ { name: "minimal", needles: 2, haystack: 10, }, { name: "small needles small haystack", needles: 5, haystack: 200, }, { name: "small needles large haystack", needles: 10, haystack: 1000, }, { name: "moderate needles giant haystack", needles: 20, haystack: 2000, }, } for _, tc := range cases { const executorPID = 42 t.Run(tc.name, func(t *testing.T) { procs, expect := genMockProcs(tc.needles, tc.haystack) lister := func() ([]ps.Process, error) { return procs, nil } result := list(executorPID, lister) must.SliceContainsAll(t, expect, result.Slice(), must.Sprintf("exp: %v; got: %v", expect, result), ) }) } }