github.com/rigado/snapd@v2.42.5-go-mod+incompatible/cmd/snap/cmd_debug_timings_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2019 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package main_test
    21  
    22  import (
    23  	"fmt"
    24  	"net/http"
    25  	"strings"
    26  
    27  	. "gopkg.in/check.v1"
    28  
    29  	"github.com/snapcore/snapd/cmd/snap"
    30  )
    31  
    32  type timingsCmdArgs struct {
    33  	args, stdout, stderr, error string
    34  }
    35  
    36  var timingsTests = []timingsCmdArgs{{
    37  	args:  "debug timings",
    38  	error: "please provide change ID or type with --last=<type>, or query for --ensure=<name> or --startup=<name>",
    39  }, {
    40  	args:  "debug timings --ensure=seed 9",
    41  	error: "cannot use change id, 'startup' or 'ensure' together",
    42  }, {
    43  	args:  "debug timings --ensure=seed --startup=ifacemgr",
    44  	error: "cannot use change id, 'startup' or 'ensure' together",
    45  }, {
    46  	args:  "debug timings --last=install --all",
    47  	error: "cannot use 'all' with change id or 'last'",
    48  }, {
    49  	args:  "debug timings --last=remove",
    50  	error: `no changes of type "remove" found`,
    51  }, {
    52  	args:  "debug timings --startup=load-state 9",
    53  	error: "cannot use change id, 'startup' or 'ensure' together",
    54  }, {
    55  	args:  "debug timings --all 9",
    56  	error: "cannot use 'all' with change id or 'last'",
    57  }, {
    58  	args: "debug timings --last=install",
    59  	stdout: "ID   Status        Doing      Undoing  Summary\n" +
    60  		"40   Doing         910ms            -  task bar summary\n" +
    61  		" ^                   1ms            -    foo summary\n" +
    62  		"  ^                  1ms            -      bar summary\n\n",
    63  }, {
    64  	args: "debug timings 1",
    65  	stdout: "ID   Status        Doing      Undoing  Summary\n" +
    66  		"40   Doing         910ms            -  task bar summary\n" +
    67  		" ^                   1ms            -    foo summary\n" +
    68  		"  ^                  1ms            -      bar summary\n\n",
    69  }, {
    70  	args: "debug timings 1 --verbose",
    71  	stdout: "ID   Status        Doing      Undoing  Label  Summary\n" +
    72  		"40   Doing         910ms            -  bar    task bar summary\n" +
    73  		" ^                   1ms            -  foo      foo summary\n" +
    74  		"  ^                  1ms            -  bar        bar summary\n\n",
    75  }, {
    76  	args: "debug timings --ensure=seed",
    77  	stdout: "ID    Status        Doing      Undoing  Summary\n" +
    78  		"seed                    -            -  \n" +
    79  		" ^                    8ms            -    baz summary\n" +
    80  		"  ^                   8ms            -      booze summary\n" +
    81  		"40    Doing         910ms            -  task bar summary\n" +
    82  		" ^                    1ms            -    foo summary\n" +
    83  		"  ^                   1ms            -      bar summary\n\n",
    84  }, {
    85  	args: "debug timings --ensure=seed --all",
    86  	stdout: "ID    Status        Doing      Undoing  Summary\n" +
    87  		"seed                    -            -  \n" +
    88  		" ^                    8ms            -    bar summary 1\n" +
    89  		" ^                    8ms            -    bar summary 2\n" +
    90  		"40    Doing         910ms            -  task bar summary\n" +
    91  		" ^                    1ms            -    foo summary\n" +
    92  		"  ^                   1ms            -      bar summary\n\n",
    93  }, {
    94  	args: "debug timings --ensure=seed --all --verbose",
    95  	stdout: "ID    Status        Doing      Undoing  Label  Summary\n" +
    96  		"seed                    -            -         \n" +
    97  		" ^                    8ms            -  abc      bar summary 1\n" +
    98  		" ^                    8ms            -  abc      bar summary 2\n" +
    99  		"40    Doing         910ms            -  bar    task bar summary\n" +
   100  		" ^                    1ms            -  foo      foo summary\n" +
   101  		"  ^                   1ms            -  bar        bar summary\n\n",
   102  }, {
   103  	args: "debug timings --startup=ifacemgr",
   104  	stdout: "ID        Status        Doing      Undoing  Summary\n" +
   105  		"ifacemgr                    -            -  \n" +
   106  		" ^                        8ms            -    baz summary\n" +
   107  		"  ^                       8ms            -      booze summary\n\n",
   108  }, {
   109  	args: "debug timings --startup=ifacemgr --all",
   110  	stdout: "ID        Status        Doing      Undoing  Summary\n" +
   111  		"ifacemgr                    -            -  \n" +
   112  		" ^                        8ms            -    baz summary\n" +
   113  		" ^                        9ms            -    baz summary\n\n",
   114  }}
   115  
   116  func (s *SnapSuite) TestGetDebugTimings(c *C) {
   117  	s.mockCmdTimingsAPI(c)
   118  
   119  	restore := main.MockIsStdinTTY(true)
   120  	defer restore()
   121  
   122  	for _, test := range timingsTests {
   123  		s.stdout.Truncate(0)
   124  		s.stderr.Truncate(0)
   125  
   126  		c.Logf("Test: %s", test.args)
   127  
   128  		_, err := main.Parser(main.Client()).ParseArgs(strings.Fields(test.args))
   129  		if test.error != "" {
   130  			c.Check(err, ErrorMatches, test.error)
   131  		} else {
   132  			c.Check(err, IsNil)
   133  			c.Check(s.Stderr(), Equals, test.stderr)
   134  			c.Check(s.Stdout(), Equals, test.stdout)
   135  		}
   136  	}
   137  }
   138  
   139  func (s *SnapSuite) mockCmdTimingsAPI(c *C) {
   140  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   141  		c.Assert(r.Method, Equals, "GET")
   142  
   143  		if r.URL.Path == "/v2/debug" {
   144  			q := r.URL.Query()
   145  			aspect := q.Get("aspect")
   146  			c.Assert(aspect, Equals, "change-timings")
   147  
   148  			changeID := q.Get("change-id")
   149  			ensure := q.Get("ensure")
   150  			startup := q.Get("startup")
   151  			all := q.Get("all")
   152  
   153  			switch {
   154  			case changeID == "1":
   155  				fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":[
   156  				{"change-id":"1", "change-timings":{
   157  					"40":{"doing-time":910000000,
   158  						"doing-timings":[
   159  							{"label":"foo", "summary": "foo summary", "duration": 1000001},
   160  							{"level":1, "label":"bar", "summary": "bar summary", "duration": 1000002}
   161  				]}}}]}`)
   162  			case ensure == "seed" && all == "false":
   163  				fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":[
   164  					{"change-id":"1",
   165  						"ensure-timings": [
   166  								{"label":"baz", "summary": "baz summary", "duration": 8000001},
   167  								{"level":1, "label":"booze", "summary": "booze summary", "duration": 8000002}
   168  							],
   169  						"change-timings":{
   170  							"40":{"doing-time":910000000,
   171  								"doing-timings":[
   172  									{"label":"foo", "summary": "foo summary", "duration": 1000001},
   173  									{"level":1, "label":"bar", "summary": "bar summary", "duration": 1000002}
   174  					]}}}]}`)
   175  			case ensure == "seed" && all == "true":
   176  				fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":[
   177  						{"change-id":"1",
   178  							"ensure-timings": [
   179  									{"label":"abc", "summary": "bar summary 1", "duration": 8000001},
   180  									{"label":"abc", "summary": "bar summary 2", "duration": 8000002}
   181  								],
   182  							"change-timings":{
   183  								"40":{"doing-time":910000000,
   184  									"doing-timings":[
   185  										{"label":"foo", "summary": "foo summary", "duration": 1000001},
   186  										{"level":1, "label":"bar", "summary": "bar summary", "duration": 1000002}
   187  						]}}}]}`)
   188  			case startup == "ifacemgr" && all == "false":
   189  				fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":[
   190  					{"startup-timings": [
   191  								{"label":"baz", "summary": "baz summary", "duration": 8000001},
   192  								{"level":1, "label":"booze", "summary": "booze summary", "duration": 8000002}
   193  					]}]}`)
   194  			case startup == "ifacemgr" && all == "true":
   195  				fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":[
   196  					{"startup-timings": [
   197  						{"label":"baz", "summary": "baz summary", "duration": 8000001},
   198  						{"label":"baz", "summary": "baz summary", "duration": 9000001}
   199  					]}]}`)
   200  			default:
   201  				c.Errorf("unexpected request: %s, %s, %s", changeID, ensure, all)
   202  			}
   203  			return
   204  		}
   205  
   206  		// request for all changes on --last=...
   207  		if r.URL.Path == "/v2/changes" {
   208  			fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":[{
   209  				"id":   "1",
   210  				"kind": "install-snap",
   211  				"summary": "a",
   212  				"status": "Doing",
   213  				"ready": false,
   214  				"spawn-time": "2016-04-21T01:02:03Z",
   215  				"ready-time": "2016-04-21T01:02:04Z",
   216  				"tasks": [{"id":"99", "kind": "bar", "summary": ".", "status": "Doing", "progress": {"done": 0, "total": 1}, "spawn-time": "2016-04-21T01:02:03Z", "ready-time": "2016-04-21T01:02:04Z"}]
   217  			  }]}`)
   218  			return
   219  		}
   220  
   221  		// request for specific change
   222  		if r.URL.Path == "/v2/changes/1" {
   223  			fmt.Fprintln(w, `{"type":"sync","status-code":200,"status":"OK","result":{
   224  				"id":   "1",
   225  				"kind": "foo",
   226  				"summary": "a",
   227  				"status": "Doing",
   228  				"ready": false,
   229  				"spawn-time": "2016-04-21T01:02:03Z",
   230  				"ready-time": "2016-04-21T01:02:04Z",
   231  				"tasks": [{"id":"40", "kind": "bar", "summary": "task bar summary", "status": "Doing", "progress": {"done": 0, "total": 1}, "spawn-time": "2016-04-21T01:02:03Z", "ready-time": "2016-04-21T01:02:04Z"}]
   232  			  }}`)
   233  			return
   234  		}
   235  
   236  		c.Errorf("unexpected path %q", r.URL.Path)
   237  	})
   238  }