1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ptrace
18
19 import (
20 "encoding/binary"
21 "math/rand"
22 "os"
23 "os/exec"
24 "testing"
25 "time"
26 "unsafe"
27
28 "github.com/go-logr/zapr"
29 . "github.com/onsi/ginkgo"
30 . "github.com/onsi/gomega"
31 "go.uber.org/zap"
32 "sigs.k8s.io/controller-runtime/pkg/envtest/printer"
33
34 "github.com/chaos-mesh/chaos-mesh/test/pkg/timer"
35 )
36
37 func TestPTrace(t *testing.T) {
38 RegisterFailHandler(Fail)
39
40 RunSpecsWithDefaultAndCustomReporters(t,
41 "PTrace Suit",
42 []Reporter{printer.NewlineReporter{}})
43 }
44
45 var _ = BeforeSuite(func(done Done) {
46 rand.Seed(GinkgoRandomSeed())
47
48 By("change working directory")
49
50 err := os.Chdir("../../")
51 Expect(err).NotTo(HaveOccurred())
52
53 By("register logger")
54 zapLog, err := zap.NewDevelopment()
55 Expect(err).NotTo(HaveOccurred())
56 log := zapr.NewLogger(zapLog)
57 RegisterLogger(log)
58
59 close(done)
60 })
61
62
63
64
65 var _ = Describe("PTrace", func() {
66
67 var t *timer.Timer
68 var program *TracedProgram
69
70 BeforeEach(func() {
71 var err error
72
73 t, err = timer.StartTimer()
74 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
75
76 time.Sleep(time.Millisecond)
77
78 program, err = Trace(t.Pid())
79 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
80 })
81
82 AfterEach(func() {
83 err := program.Detach()
84 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
85
86 err = t.Stop()
87 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
88 })
89
90 It("should mmap slice successfully", func() {
91 Expect(program.Pid()).Should(Equal(t.Pid()))
92
93 helloWorld := []byte("Hello World")
94 entry, err := program.MmapSlice(helloWorld)
95 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
96
97 readBuf, err := program.ReadSlice(entry.StartAddress, uint64(len(helloWorld)))
98 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
99
100 Expect(*readBuf).Should(Equal(helloWorld))
101 })
102
103 It("double trace should get error", func() {
104 _, err := Trace(t.Pid())
105 Expect(err).Should(HaveOccurred())
106 })
107
108 It("should ptrace write slice successfully", func() {
109 helloWorld := []byte("Hello World")
110 addr, err := program.Mmap(uint64(len(helloWorld)), 0)
111 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
112
113 err = program.PtraceWriteSlice(addr, helloWorld)
114 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
115
116 readBuf, err := program.ReadSlice(addr, uint64(len(helloWorld)))
117 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
118
119 Expect(*readBuf).Should(Equal(helloWorld))
120 })
121
122 It("should write uint64 successfully", func() {
123 number := rand.Uint64()
124 size := uint64(unsafe.Sizeof(number))
125 expectBuf := make([]byte, size)
126 binary.LittleEndian.PutUint64(expectBuf, number)
127
128 addr, err := program.Mmap(size, 0)
129 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
130
131 err = program.WriteUint64ToAddr(addr, number)
132 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
133
134 readBuf, err := program.ReadSlice(addr, size)
135 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
136
137 Expect(*readBuf).Should(Equal(expectBuf))
138 })
139
140 It("should be able to detach and reattach", func() {
141 err := program.Detach()
142 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
143
144 program, err = Trace(t.Pid())
145 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
146 })
147
148 It("should be able to attach and detach multithread program", func() {
149 p := exec.Command("./bin/test/multithread_tracee")
150 err := p.Start()
151 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
152
153 time.Sleep(time.Millisecond)
154
155 pid := p.Process.Pid
156 program, err := Trace(pid)
157 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
158
159 err = program.Detach()
160 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
161
162 err = p.Process.Kill()
163 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
164 })
165 })
166