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