11package cli
22
33import (
4+ "context"
5+ "fmt"
46 "io"
57 "os"
68 "strings"
79 "testing"
810
11+ "github.com/acorn-io/acorn/pkg/client"
12+
13+ apiv1 "github.com/acorn-io/acorn/pkg/apis/api.acorn.io/v1"
14+ v1 "github.com/acorn-io/acorn/pkg/apis/internal.acorn.io/v1"
15+ "github.com/acorn-io/acorn/pkg/mocks"
16+ "github.com/golang/mock/gomock"
17+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18+
919 "github.com/acorn-io/acorn/pkg/cli/testdata"
1020 "github.com/spf13/cobra"
1121
@@ -28,100 +38,271 @@ func TestRunArgs_Env(t *testing.T) {
2838 assert .Equal (t , "1" , opts .Env [1 ].Value )
2939}
3040
31- func TestRunMemory (t * testing.T ) {
41+ func TestRun (t * testing.T ) {
42+ baseMock := func (f * mocks.MockClient ) {
43+ f .EXPECT ().AppGet (gomock .Any (), gomock .Any ()).DoAndReturn (
44+ func (ctx context.Context , name string ) (* apiv1.App , error ) {
45+ switch name {
46+ case "dne" :
47+ return nil , fmt .Errorf ("error: app %s does not exist" , name )
48+ case "found" :
49+ return & apiv1.App {
50+ TypeMeta : metav1.TypeMeta {},
51+ ObjectMeta : metav1.ObjectMeta {Name : "found" },
52+ Spec : v1.AppInstanceSpec {Secrets : []v1.SecretBinding {{Secret : "found.secret" , Target : "found" }}},
53+ Status : v1.AppInstanceStatus {Ready : true },
54+ }, nil
55+ case "found.container" :
56+ return & apiv1.App {
57+ TypeMeta : metav1.TypeMeta {},
58+ ObjectMeta : metav1.ObjectMeta {Name : "found.container" },
59+ Spec : v1.AppInstanceSpec {Secrets : []v1.SecretBinding {{Secret : "found.secret" , Target : "found" }}},
60+ Status : v1.AppInstanceStatus {},
61+ }, nil
62+ }
63+ return nil , nil
64+ }).AnyTimes ()
65+ f .EXPECT ().AppRun (gomock .Any (), gomock .Any (), gomock .Any ()).DoAndReturn (
66+ func (ctx context.Context , image string , opts * client.AppRunOptions ) (* apiv1.App , error ) {
67+ switch image {
68+ case "dne" :
69+ return nil , fmt .Errorf ("error: app %s does not exist" , image )
70+ case "found" :
71+ return & apiv1.App {
72+ TypeMeta : metav1.TypeMeta {},
73+ ObjectMeta : metav1.ObjectMeta {Name : "found" },
74+ Spec : v1.AppInstanceSpec {Secrets : []v1.SecretBinding {{Secret : "found.secret" , Target : "found" }}},
75+ Status : v1.AppInstanceStatus {Ready : true },
76+ }, nil
77+ case "found.container" :
78+ return & apiv1.App {
79+ TypeMeta : metav1.TypeMeta {},
80+ ObjectMeta : metav1.ObjectMeta {Name : "found.container" },
81+ Spec : v1.AppInstanceSpec {Secrets : []v1.SecretBinding {{Secret : "found.secret" , Target : "found" }}},
82+ Status : v1.AppInstanceStatus {},
83+ }, nil
84+ }
85+ return nil , fmt .Errorf ("error: app %s does not exist" , image )
86+ }).AnyTimes ()
87+ }
88+
3289 type fields struct {
33- All bool
34- Type []string
35- Force bool
90+ Quiet bool
91+ Output string
92+ All bool
93+ Force bool
3694 }
3795 type args struct {
38- cmd * cobra.Command
39- args []string
40- client * testdata.MockClient
96+ cmd * cobra.Command
97+ args []string
4198 }
42- var _ , w , _ = os .Pipe ()
4399 tests := []struct {
44- name string
45- fields fields
46- args args
47- wantErr bool
48- wantOut string
49- commandContext CommandContext
100+ name string
101+ fields fields
102+ args args
103+ wantErr bool
104+ wantOut string
105+ prepare func ( t * testing. T , f * mocks. MockClient )
50106 }{
51107 {
52108 name : "acorn run -h" , fields : fields {
53109 All : false ,
54- Type : nil ,
55110 Force : true ,
56111 },
57- commandContext : CommandContext {
58- ClientFactory : & testdata.MockClientFactory {},
59- StdOut : w ,
60- StdErr : w ,
61- StdIn : strings .NewReader ("" ),
62- },
112+
63113 args : args {
64- args : []string {"-h" },
65- client : & testdata.MockClient {},
114+ args : []string {"-h" },
66115 },
67116 wantErr : false ,
68117 wantOut : "./testdata/run/acorn_run_help.txt" ,
69118 },
70119 {
71120 name : "acorn run -m found.container=256Miii found " , fields : fields {
72121 All : false ,
73- Type : nil ,
74122 Force : true ,
75123 },
76- commandContext : CommandContext {
77- ClientFactory : & testdata.MockClientFactory {},
78- StdOut : w ,
79- StdErr : w ,
80- StdIn : strings .NewReader ("" ),
81- },
82124 args : args {
83- args : []string {"-m found.container=256Miii" , "found" },
84- client : & testdata.MockClient {},
125+ args : []string {"-m found.container=256Miii" , "found" },
126+ },
127+ prepare : func (t * testing.T , f * mocks.MockClient ) {
128+ t .Helper ()
129+ f .EXPECT ().Info (gomock .Any ()).Return (
130+ []apiv1.Info {
131+ {
132+ TypeMeta : metav1.TypeMeta {},
133+ ObjectMeta : metav1.ObjectMeta {},
134+ Spec : apiv1.InfoSpec {},
135+ },
136+ }, nil )
85137 },
86138 wantErr : true ,
87139 wantOut : "invalid number \" 256Miii\" " ,
88140 },
89141 {
90142 name : "acorn run -m found.container=notallowed found " , fields : fields {
91143 All : false ,
92- Type : nil ,
93144 Force : true ,
94145 },
95- commandContext : CommandContext {
96- ClientFactory : & testdata.MockClientFactory {},
97- StdOut : w ,
98- StdErr : w ,
99- StdIn : strings .NewReader ("" ),
100- },
146+
101147 args : args {
102- args : []string {"-m found.container=notallowed" , "found" },
103- client : & testdata.MockClient {},
148+ args : []string {"-m found.container=notallowed" , "found" },
149+ },
150+ prepare : func (t * testing.T , f * mocks.MockClient ) {
151+ t .Helper ()
152+ f .EXPECT ().Info (gomock .Any ()).Return (
153+ []apiv1.Info {
154+ {
155+ TypeMeta : metav1.TypeMeta {},
156+ ObjectMeta : metav1.ObjectMeta {},
157+ Spec : apiv1.InfoSpec {},
158+ },
159+ }, nil )
104160 },
105161 wantErr : true ,
106162 wantOut : "illegal number start \" notallowed\" " ,
107163 },
164+ {
165+ name : "acorn run app name already in use" , fields : fields {
166+ All : false ,
167+ Force : true ,
168+ },
169+
170+ args : args {
171+ args : []string {"-n=found" , "run-name" },
172+ },
173+ prepare : func (t * testing.T , f * mocks.MockClient ) {
174+ t .Helper ()
175+ },
176+ wantErr : true ,
177+ wantOut : "app \" found\" already exists" ,
178+ },
179+ {
180+ name : "acorn run ./folder but folder doesn't exist" , fields : fields {
181+ All : false ,
182+ Force : true ,
183+ },
184+
185+ args : args {
186+ args : []string {"./folder" },
187+ },
188+ prepare : func (t * testing.T , f * mocks.MockClient ) {
189+ t .Helper ()
190+ f .EXPECT ().Info (gomock .Any ()).Return (
191+ []apiv1.Info {
192+ {
193+ TypeMeta : metav1.TypeMeta {},
194+ ObjectMeta : metav1.ObjectMeta {},
195+ Spec : apiv1.InfoSpec {},
196+ },
197+ }, nil )
198+ },
199+ wantErr : true ,
200+ wantOut : "error: app ./folder does not exist" ,
201+ },
202+ {
203+ name : "acorn_run_pointed_at_working_dir_without_acornfile" , fields : fields {
204+ All : false ,
205+ Force : true ,
206+ },
207+
208+ args : args {
209+ args : []string {"." },
210+ },
211+ prepare : func (t * testing.T , f * mocks.MockClient ) {
212+ t .Helper ()
213+ f .EXPECT ().Info (gomock .Any ()).Return (
214+ []apiv1.Info {
215+ {
216+ TypeMeta : metav1.TypeMeta {},
217+ ObjectMeta : metav1.ObjectMeta {},
218+ Spec : apiv1.InfoSpec {},
219+ },
220+ }, nil )
221+ },
222+ wantErr : true ,
223+ wantOut : "open Acornfile: no such file or directory" ,
224+ },
225+ {
226+ name : "acorn_run_points_at_file" , fields : fields {
227+ All : false ,
228+ Force : true ,
229+ },
230+ args : args {
231+ args : []string {"Acornfile_temp" },
232+ },
233+ prepare : func (t * testing.T , f * mocks.MockClient ) {
234+ t .Helper ()
235+ // Create a placeholder acorn file
236+ dir , err := os .Getwd ()
237+ if err != nil {
238+ t .Fatalf ("failed to get current working directory: %v" , err )
239+ }
240+ file , err := os .Create (dir + "/Acornfile_temp" )
241+ if err != nil {
242+ t .Fatalf ("failed to get current working directory: %v" , err )
243+ }
244+ t .Cleanup (func () { os .Remove (file .Name ()) })
245+
246+ if _ , err = file .Write ([]byte ("content" )); err != nil {
247+ t .Fatal (err .Error ())
248+ }
249+ if err = file .Close (); err != nil {
250+ t .Fatal (err )
251+ }
252+ if err != nil {
253+ t .Fatal ()
254+ }
255+
256+ f .EXPECT ().Info (gomock .Any ()).Return (
257+ []apiv1.Info {
258+ {
259+ TypeMeta : metav1.TypeMeta {},
260+ ObjectMeta : metav1.ObjectMeta {},
261+ Spec : apiv1.InfoSpec {},
262+ },
263+ }, nil )
264+ },
265+ wantErr : true ,
266+ wantOut : "Acornfile_temp is not a directory" ,
267+ },
108268 }
109269 for _ , tt := range tests {
110270 t .Run (tt .name , func (t * testing.T ) {
271+ ctrl := gomock .NewController (t )
272+ //Mocked client for cli's client calls.
273+ mClient := mocks .NewMockClient (ctrl )
274+
275+ baseMock (mClient )
276+ if tt .prepare != nil {
277+ tt .prepare (t , mClient )
278+ }
279+
111280 r , w , _ := os .Pipe ()
112281 os .Stdout = w
113- tt .args .cmd = NewRun (tt .commandContext )
282+ // Mock client factory just returns the gomock client.
283+ tt .args .cmd = NewRun (CommandContext {
284+ ClientFactory : & testdata.MockClientFactoryManual {
285+ Client : mClient ,
286+ },
287+ StdOut : w ,
288+ StdErr : w ,
289+ StdIn : strings .NewReader ("" ),
290+ })
114291 tt .args .cmd .SetArgs (tt .args .args )
115292 err := tt .args .cmd .Execute ()
293+
116294 if err != nil && ! tt .wantErr {
117295 assert .Failf (t , "got err when err not expected" , "got err: %s" , err .Error ())
118296 } else if err != nil && tt .wantErr {
119297 assert .Equal (t , tt .wantOut , err .Error ())
120298 } else {
121299 w .Close ()
122300 out , _ := io .ReadAll (r )
123- testOut , _ := os .ReadFile (tt .wantOut )
124- assert .Equal (t , string (testOut ), string (out ))
301+ wantOut := tt .wantOut
302+ if testOut , err := os .ReadFile (tt .wantOut ); err == nil {
303+ wantOut = string (testOut )
304+ }
305+ assert .Equal (t , wantOut , string (out ))
125306 }
126307 })
127308 }
0 commit comments