github.com/drycc/workflow-cli@v1.5.3-0.20240322092846-d4ee25983af9/cmd/ps_test.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "net/http" 8 "testing" 9 "time" 10 11 "github.com/drycc/controller-sdk-go/api" 12 dtime "github.com/drycc/controller-sdk-go/pkg/time" 13 "github.com/drycc/workflow-cli/pkg/testutil" 14 "github.com/stretchr/testify/assert" 15 "golang.org/x/net/websocket" 16 ) 17 18 func TestPrintProcesses(t *testing.T) { 19 var b bytes.Buffer 20 d, err := time.Parse("2006-01-02T15:04:05MST", "2023-11-15T11:55:16CST") 21 if err != nil { 22 t.Fatal(err) 23 } 24 pods := []api.Pods{ 25 { 26 Release: "v3", 27 Name: "benign-quilting-web-4084101150-c871y", 28 Type: "web", 29 State: "up", 30 Started: dtime.Time{Time: &d}, 31 }, 32 { 33 Release: "v3", 34 Name: "benign-quilting-worker-4084101150-c871y", 35 Type: "worker", 36 State: "up", 37 Started: dtime.Time{Time: &d}, 38 }, 39 } 40 cf, server, err := testutil.NewTestServerAndClient() 41 if err != nil { 42 t.Fatal(err) 43 } 44 defer server.Close() 45 46 printProcesses(&DryccCmd{WOut: &b, ConfigFile: cf}, "appname", pods) 47 48 assert.Equal(t, b.String(), `NAME RELEASE STATE PTYPE STARTED 49 benign-quilting-web-4084101150-c871y v3 up web 2023-11-15T11:55:16CST 50 benign-quilting-worker-4084101150-c871y v3 up worker 2023-11-15T11:55:16CST 51 `, "output") 52 } 53 54 func TestPsList(t *testing.T) { 55 t.Parallel() 56 cf, server, err := testutil.NewTestServerAndClient() 57 if err != nil { 58 t.Fatal(err) 59 } 60 defer server.Close() 61 var b bytes.Buffer 62 cmdr := DryccCmd{WOut: &b, ConfigFile: cf} 63 64 server.Mux.HandleFunc("/v2/apps/foo/pods/", func(w http.ResponseWriter, _ *http.Request) { 65 testutil.SetHeaders(w) 66 fmt.Fprintf(w, `{ 67 "count": 1, 68 "next": null, 69 "previous": null, 70 "results": [ 71 { 72 "release": "v2", 73 "type": "web", 74 "name": "foo-web-4084101150-c871y", 75 "state": "up", 76 "started": "2016-02-13T00:47:52" 77 } 78 ] 79 }`) 80 }) 81 82 err = cmdr.PsList("foo", -1) 83 assert.NoError(t, err) 84 85 assert.Equal(t, b.String(), `NAME RELEASE STATE PTYPE STARTED 86 foo-web-4084101150-c871y v2 up web 2016-02-13T00:47:52UTC 87 `, "output") 88 } 89 90 func TestPsExec(t *testing.T) { 91 t.Parallel() 92 cf, server, err := testutil.NewTestServerAndClient() 93 if err != nil { 94 t.Fatal(err) 95 } 96 defer server.Close() 97 var b bytes.Buffer 98 cmdr := DryccCmd{WOut: &b, ConfigFile: cf} 99 server.Mux.Handle( 100 "/v2/apps/foo/pods/foo-web-111/exec/", 101 websocket.Handler(func(conn *websocket.Conn) { 102 io.Copy(conn, conn) 103 }), 104 ) 105 err = cmdr.PsExec("foo", "foo-web-111", true, false, []string{"/bin/sh"}) 106 assert.NoError(t, err) 107 } 108 109 func TestPsLogs(t *testing.T) { 110 t.Parallel() 111 cf, server, err := testutil.NewTestServerAndClient() 112 if err != nil { 113 t.Fatal(err) 114 } 115 defer server.Close() 116 var b bytes.Buffer 117 cmdr := DryccCmd{WOut: &b, ConfigFile: cf} 118 server.Mux.Handle( 119 "/v2/apps/foo/pods/foo-web-111/logs/", 120 websocket.Handler(func(conn *websocket.Conn) { 121 conn.WriteClose(100) 122 }), 123 ) 124 err = cmdr.PsLogs("foo", "foo-web-111", 300, true, "runner") 125 assert.NoError(t, err) 126 } 127 128 type psTargetCases struct { 129 Targets []string 130 ExpectedError bool 131 ExpectedMap map[string]int 132 ExpectedMsg string 133 } 134 135 func TestParsePsTargets(t *testing.T) { 136 t.Parallel() 137 138 cases := []psTargetCases{ 139 {[]string{"test"}, true, nil, "'test' does not match the pattern 'type=num', ex: web=2"}, 140 {[]string{"test=a"}, true, nil, "'test=a' does not match the pattern 'type=num', ex: web=2"}, 141 {[]string{"test="}, true, nil, "'test=' does not match the pattern 'type=num', ex: web=2"}, 142 {[]string{"Test=2"}, true, nil, "'Test=2' does not match the pattern 'type=num', ex: web=2"}, 143 {[]string{"test=2"}, false, map[string]int{"test": 2}, ""}, 144 {[]string{"test-proc=2"}, false, map[string]int{"test-proc": 2}, ""}, 145 {[]string{"test1=2"}, false, map[string]int{"test1": 2}, ""}, 146 } 147 148 for _, check := range cases { 149 actual, err := parsePsTargets(check.Targets) 150 if check.ExpectedError { 151 assert.Equal(t, err.Error(), check.ExpectedMsg, "error") 152 } else { 153 assert.NoError(t, err) 154 assert.Equal(t, actual, check.ExpectedMap, "error") 155 } 156 } 157 } 158 159 func TestPsScale(t *testing.T) { 160 t.Parallel() 161 cf, server, err := testutil.NewTestServerAndClient() 162 if err != nil { 163 t.Fatal(err) 164 } 165 defer server.Close() 166 var b bytes.Buffer 167 cmdr := DryccCmd{WOut: &b, ConfigFile: cf} 168 err = cmdr.PsScale("foo", []string{"test"}) 169 assert.Equal(t, err.Error(), "'test' does not match the pattern 'type=num', ex: web=2", "error") 170 171 server.Mux.HandleFunc("/v2/apps/foo/pods/", func(w http.ResponseWriter, _ *http.Request) { 172 testutil.SetHeaders(w) 173 fmt.Fprintf(w, `{ 174 "count": 1, 175 "next": null, 176 "previous": null, 177 "results": [ 178 { 179 "release": "v2", 180 "type": "web", 181 "name": "foo-web-4084101150-c871y", 182 "state": "up", 183 "started": "2016-02-13T00:47:52" 184 } 185 ] 186 }`) 187 }) 188 189 server.Mux.HandleFunc("/v2/apps/foo/scale/", func(w http.ResponseWriter, r *http.Request) { 190 testutil.AssertBody(t, map[string]int{"web": 1}, r) 191 testutil.SetHeaders(w) 192 w.WriteHeader(http.StatusNoContent) 193 }) 194 195 b.Reset() 196 err = cmdr.PsScale("foo", []string{"web=1"}) 197 assert.NoError(t, err) 198 assert.Equal(t, testutil.StripProgress(b.String()), `Scaling processes... but first, coffee! 199 done in 0s 200 201 NAME RELEASE STATE PTYPE STARTED 202 foo-web-4084101150-c871y v2 up web 2016-02-13T00:47:52UTC 203 `, "output") 204 } 205 206 func TestPsRestart(t *testing.T) { 207 t.Parallel() 208 cf, server, err := testutil.NewTestServerAndClient() 209 if err != nil { 210 t.Fatal(err) 211 } 212 defer server.Close() 213 var b bytes.Buffer 214 cmdr := DryccCmd{WOut: &b, ConfigFile: cf} 215 216 server.Mux.HandleFunc("/v2/apps/foo/pods/restart/", func(w http.ResponseWriter, _ *http.Request) { 217 testutil.SetHeaders(w) 218 w.WriteHeader(http.StatusNoContent) 219 }) 220 221 b.Reset() 222 err = cmdr.PsRestart("foo", "") 223 assert.NoError(t, err) 224 225 server.Mux.HandleFunc("/v2/apps/coolapp/pods/restart/", func(w http.ResponseWriter, _ *http.Request) { 226 testutil.SetHeaders(w) 227 w.WriteHeader(http.StatusNoContent) 228 }) 229 230 b.Reset() 231 232 err = cmdr.PsRestart("coolapp", "") 233 assert.NoError(t, err) 234 235 server.Mux.HandleFunc("/v2/apps/testapp/pods/web/restart/", func(w http.ResponseWriter, _ *http.Request) { 236 testutil.SetHeaders(w) 237 w.WriteHeader(http.StatusNoContent) 238 }) 239 240 b.Reset() 241 242 err = cmdr.PsRestart("testapp", "web") 243 assert.NoError(t, err) 244 }