@@ -4,73 +4,137 @@ import (
4
4
"context"
5
5
"encoding/json"
6
6
"fmt"
7
+ "io"
7
8
"os"
8
9
"os/exec"
9
10
"reflect"
10
11
"time"
11
12
)
12
13
13
- type Mock struct {
14
+ type MockItemDispenser interface {
15
+ NextMockItem () * MockItem
16
+ }
17
+
18
+ type MockItem struct {
14
19
Args []string `json:"args"`
15
20
Stdout string `json:"stdout"`
16
21
Stderr string `json:"stderr"`
17
22
SleepDuration time.Duration `json:"sleep"`
18
23
ExitCode int `json:"exit_code"`
24
+
25
+ MockError string `json:"error"`
19
26
}
20
27
21
- func (m * Mock ) MarshalJSON () ([]byte , error ) {
22
- type t Mock
28
+ func (m * MockItem ) MarshalJSON () ([]byte , error ) {
29
+ type t MockItem
23
30
return json .Marshal ((* t )(m ))
24
31
}
25
32
26
- func (m * Mock ) UnmarshalJSON (b []byte ) error {
27
- type t Mock
33
+ func (m * MockItem ) UnmarshalJSON (b []byte ) error {
34
+ type t MockItem
28
35
return json .Unmarshal (b , (* t )(m ))
29
36
}
30
37
31
- func MockExecutor (m * Mock ) * Executor {
32
- if m == nil {
33
- m = & Mock {}
38
+ type MockQueue struct {
39
+ Q []* MockItem
40
+ }
41
+
42
+ type MockCall MockItem
43
+
44
+ func (mc * MockCall ) MarshalJSON () ([]byte , error ) {
45
+ item := (* MockItem )(mc )
46
+ q := MockQueue {
47
+ Q : []* MockItem {item },
34
48
}
49
+ return json .Marshal (q )
50
+ }
35
51
36
- path , ctxFunc := mockCommandCtxFunc (m )
52
+ func (mc * MockCall ) UnmarshalJSON (b []byte ) error {
53
+ q := MockQueue {}
54
+ err := json .Unmarshal (b , & q )
55
+ if err != nil {
56
+ return err
57
+ }
58
+
59
+ mc = (* MockCall )(q .Q [0 ])
60
+ return nil
61
+ }
62
+
63
+ func (mc * MockCall ) NextMockItem () * MockItem {
64
+ return (* MockItem )(mc )
65
+ }
66
+
67
+ func (mc * MockQueue ) NextMockItem () * MockItem {
68
+ if len (mc .Q ) == 0 {
69
+ return & MockItem {
70
+ MockError : "no more calls expected" ,
71
+ }
72
+ }
73
+
74
+ var mi * MockItem
75
+ mi , mc .Q = mc .Q [0 ], mc .Q [1 :]
76
+
77
+ return mi
78
+ }
79
+
80
+ func MockExecutor (md MockItemDispenser ) * Executor {
81
+ if md == nil {
82
+ md = & MockCall {
83
+ MockError : "no mocks provided" ,
84
+ }
85
+ }
86
+
87
+ path , ctxFunc := mockCommandCtxFunc (md )
37
88
executor := NewExecutor (context .Background (), path )
38
89
executor .cmdCtxFunc = ctxFunc
39
90
return executor
40
91
}
41
92
42
- func mockCommandCtxFunc (e * Mock ) (string , cmdCtxFunc ) {
93
+ func mockCommandCtxFunc (md MockItemDispenser ) (string , cmdCtxFunc ) {
43
94
return os .Args [0 ], func (ctx context.Context , path string , arg ... string ) * exec.Cmd {
44
95
cmd := exec .CommandContext (ctx , os .Args [0 ], os .Args [1 :]... )
45
96
46
- expectedJson , _ := e .MarshalJSON ()
97
+ b , err := md .NextMockItem ().MarshalJSON ()
98
+ if err != nil {
99
+ panic (err )
100
+ }
101
+ expectedJson := string (b )
47
102
cmd .Env = []string {"TF_LS_MOCK=" + string (expectedJson )}
48
103
49
104
return cmd
50
105
}
51
106
}
52
107
53
- func ExecuteMock (rawMockData string ) int {
54
- e := & Mock {}
55
- err := e .UnmarshalJSON ([]byte (rawMockData ))
108
+ func ExecuteMockData (rawMockData string ) int {
109
+ mi := & MockItem {}
110
+ err := mi .UnmarshalJSON ([]byte (rawMockData ))
56
111
if err != nil {
57
- fmt .Fprint (os .Stderr , "unable to unmarshal mock response" )
112
+ fmt .Fprintf (os .Stderr , "unable to unmarshal mock response: %s" , err )
113
+ return 1
114
+ }
115
+ return validateMockItem (mi , os .Args [1 :], os .Stdout , os .Stderr )
116
+ }
117
+
118
+ func validateMockItem (m * MockItem , args []string , stdout , stderr io.Writer ) int {
119
+ if m .MockError != "" {
120
+ fmt .Fprintf (stderr , m .MockError )
58
121
return 1
59
122
}
60
123
61
- givenArgs := os .Args [1 :]
62
- if ! reflect .DeepEqual (e .Args , givenArgs ) {
63
- fmt .Fprintf (os .Stderr , "arguments don't match.\n expected: %q\n given: %q\n " ,
64
- e .Args , givenArgs )
124
+ givenArgs := args
125
+ if ! reflect .DeepEqual (m .Args , givenArgs ) {
126
+ fmt .Fprintf (stderr ,
127
+ "arguments don't match.\n expected: %q\n given: %q\n " ,
128
+ m .Args , givenArgs )
65
129
return 1
66
130
}
67
131
68
- if e .SleepDuration > 0 {
69
- time .Sleep (e .SleepDuration )
132
+ if m .SleepDuration > 0 {
133
+ time .Sleep (m .SleepDuration )
70
134
}
71
135
72
- fmt .Fprint (os . Stdout , e .Stdout )
73
- fmt .Fprint (os . Stderr , e .Stderr )
136
+ fmt .Fprint (stdout , m .Stdout )
137
+ fmt .Fprint (stderr , m .Stderr )
74
138
75
- return e .ExitCode
139
+ return m .ExitCode
76
140
}
0 commit comments