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  }