...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package mock
15
16 import (
17 "path"
18 "reflect"
19 "sync"
20
21 "github.com/pingcap/failpoint"
22 )
23
24
25 type Finalizer func() error
26
27 type mockPoints struct {
28 m map[string]interface{}
29 l sync.Mutex
30 }
31
32 func (p *mockPoints) set(fpname string, value interface{}) {
33 p.l.Lock()
34 defer p.l.Unlock()
35
36 p.m[fpname] = value
37 }
38
39 func (p *mockPoints) get(fpname string) interface{} {
40 p.l.Lock()
41 defer p.l.Unlock()
42
43 return p.m[fpname]
44 }
45
46 func (p *mockPoints) clr(fpname string) {
47 p.l.Lock()
48 defer p.l.Unlock()
49
50 delete(p.m, fpname)
51 }
52
53 var points = mockPoints{m: make(map[string]interface{})}
54
55
56 func On(fpname string) interface{} {
57 var ret interface{}
58 failpoint.Inject(fpname, func() {
59 ret = points.get(fpname)
60 })
61 return ret
62 }
63
64
65 func With(fpname string, value interface{}) Finalizer {
66 if err := failpoint.Enable(failpath(fpname), "return(true)"); err != nil {
67 panic(err)
68 }
69 points.set(fpname, value)
70 return func() error { return Reset(fpname) }
71 }
72
73
74 func Reset(fpname string) error {
75 if err := failpoint.Disable(failpath(fpname)); err != nil {
76 return err
77 }
78 points.clr(fpname)
79 return nil
80 }
81
82 func failpath(fpname string) string {
83 type em struct{}
84 return path.Join(reflect.TypeOf(em{}).PkgPath(), fpname)
85 }
86