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

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016 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  	"io/ioutil"
    24  	"net/http"
    25  	"os"
    26  
    27  	"github.com/jessevdk/go-flags"
    28  	. "gopkg.in/check.v1"
    29  
    30  	"github.com/snapcore/snapd/client"
    31  	. "github.com/snapcore/snapd/cmd/snap"
    32  	"github.com/snapcore/snapd/testutil"
    33  )
    34  
    35  func (s *SnapSuite) TestInterfacesZeroSlotsOnePlug(c *C) {
    36  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    37  		c.Check(r.Method, Equals, "GET")
    38  		c.Check(r.URL.Path, Equals, "/v2/connections")
    39  		body, err := ioutil.ReadAll(r.Body)
    40  		c.Check(err, IsNil)
    41  		c.Check(body, DeepEquals, []byte{})
    42  		EncodeResponseBody(c, w, map[string]interface{}{
    43  			"type": "sync",
    44  			"result": client.Connections{
    45  				Plugs: []client.Plug{
    46  					{
    47  						Snap: "keyboard-lights",
    48  						Name: "capslock-led",
    49  					},
    50  				},
    51  			},
    52  		})
    53  	})
    54  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
    55  	c.Assert(err, IsNil)
    56  	c.Assert(rest, DeepEquals, []string{})
    57  	expectedStdout := "" +
    58  		"Slot  Plug\n" +
    59  		"-     keyboard-lights:capslock-led\n"
    60  	c.Assert(s.Stdout(), Equals, expectedStdout)
    61  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
    62  }
    63  
    64  func (s *SnapSuite) TestInterfacesZeroPlugsOneSlot(c *C) {
    65  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    66  		c.Check(r.Method, Equals, "GET")
    67  		c.Check(r.URL.Path, Equals, "/v2/connections")
    68  		body, err := ioutil.ReadAll(r.Body)
    69  		c.Check(err, IsNil)
    70  		c.Check(body, DeepEquals, []byte{})
    71  		EncodeResponseBody(c, w, map[string]interface{}{
    72  			"type": "sync",
    73  			"result": client.Connections{
    74  				Slots: []client.Slot{
    75  					{
    76  						Snap:      "canonical-pi2",
    77  						Name:      "pin-13",
    78  						Interface: "bool-file",
    79  						Label:     "Pin 13",
    80  					},
    81  				},
    82  			},
    83  		})
    84  	})
    85  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
    86  	c.Assert(err, IsNil)
    87  	c.Assert(rest, DeepEquals, []string{})
    88  	expectedStdout := "" +
    89  		"Slot                  Plug\n" +
    90  		"canonical-pi2:pin-13  -\n"
    91  	c.Assert(s.Stdout(), Equals, expectedStdout)
    92  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
    93  }
    94  
    95  func (s *SnapSuite) TestInterfacesOneSlotOnePlug(c *C) {
    96  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    97  		c.Check(r.Method, Equals, "GET")
    98  		c.Check(r.URL.Path, Equals, "/v2/connections")
    99  		body, err := ioutil.ReadAll(r.Body)
   100  		c.Check(err, IsNil)
   101  		c.Check(body, DeepEquals, []byte{})
   102  		EncodeResponseBody(c, w, map[string]interface{}{
   103  			"type": "sync",
   104  			"result": client.Connections{
   105  				Slots: []client.Slot{
   106  					{
   107  						Snap:      "canonical-pi2",
   108  						Name:      "pin-13",
   109  						Interface: "bool-file",
   110  						Label:     "Pin 13",
   111  						Connections: []client.PlugRef{
   112  							{
   113  								Snap: "keyboard-lights",
   114  								Name: "capslock-led",
   115  							},
   116  						},
   117  					},
   118  				},
   119  				Plugs: []client.Plug{
   120  					{
   121  						Snap:      "keyboard-lights",
   122  						Name:      "capslock-led",
   123  						Interface: "bool-file",
   124  						Label:     "Capslock indicator LED",
   125  						Connections: []client.SlotRef{
   126  							{
   127  								Snap: "canonical-pi2",
   128  								Name: "pin-13",
   129  							},
   130  						},
   131  					},
   132  				},
   133  			},
   134  		})
   135  	})
   136  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
   137  	c.Assert(err, IsNil)
   138  	c.Assert(rest, DeepEquals, []string{})
   139  	expectedStdout := "" +
   140  		"Slot                  Plug\n" +
   141  		"canonical-pi2:pin-13  keyboard-lights:capslock-led\n"
   142  	c.Assert(s.Stdout(), Equals, expectedStdout)
   143  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   144  
   145  	s.SetUpTest(c)
   146  	// should be the same
   147  	rest, err = Parser(Client()).ParseArgs([]string{"interfaces", "canonical-pi2"})
   148  	c.Assert(err, IsNil)
   149  	c.Assert(rest, DeepEquals, []string{})
   150  	c.Assert(s.Stdout(), Equals, expectedStdout)
   151  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   152  
   153  	s.SetUpTest(c)
   154  	// and the same again
   155  	rest, err = Parser(Client()).ParseArgs([]string{"interfaces", "keyboard-lights"})
   156  	c.Assert(err, IsNil)
   157  	c.Assert(rest, DeepEquals, []string{})
   158  	c.Assert(s.Stdout(), Equals, expectedStdout)
   159  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   160  }
   161  
   162  func (s *SnapSuite) TestInterfacesTwoPlugs(c *C) {
   163  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   164  		c.Check(r.Method, Equals, "GET")
   165  		c.Check(r.URL.Path, Equals, "/v2/connections")
   166  		body, err := ioutil.ReadAll(r.Body)
   167  		c.Check(err, IsNil)
   168  		c.Check(body, DeepEquals, []byte{})
   169  		EncodeResponseBody(c, w, map[string]interface{}{
   170  			"type": "sync",
   171  			"result": client.Connections{
   172  				Slots: []client.Slot{
   173  					{
   174  						Snap:      "canonical-pi2",
   175  						Name:      "pin-13",
   176  						Interface: "bool-file",
   177  						Label:     "Pin 13",
   178  						Connections: []client.PlugRef{
   179  							{
   180  								Snap: "keyboard-lights",
   181  								Name: "capslock-led",
   182  							},
   183  							{
   184  								Snap: "keyboard-lights",
   185  								Name: "scrollock-led",
   186  							},
   187  						},
   188  					},
   189  				},
   190  			},
   191  		})
   192  	})
   193  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
   194  	c.Assert(err, IsNil)
   195  	c.Assert(rest, DeepEquals, []string{})
   196  	expectedStdout := "" +
   197  		"Slot                  Plug\n" +
   198  		"canonical-pi2:pin-13  keyboard-lights:capslock-led,keyboard-lights:scrollock-led\n"
   199  	c.Assert(s.Stdout(), Equals, expectedStdout)
   200  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   201  }
   202  
   203  func (s *SnapSuite) TestInterfacesPlugsWithCommonName(c *C) {
   204  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   205  		c.Check(r.Method, Equals, "GET")
   206  		c.Check(r.URL.Path, Equals, "/v2/connections")
   207  		body, err := ioutil.ReadAll(r.Body)
   208  		c.Check(err, IsNil)
   209  		c.Check(body, DeepEquals, []byte{})
   210  		EncodeResponseBody(c, w, map[string]interface{}{
   211  			"type": "sync",
   212  			"result": client.Connections{
   213  				Slots: []client.Slot{
   214  					{
   215  						Snap:      "canonical-pi2",
   216  						Name:      "network-listening",
   217  						Interface: "network-listening",
   218  						Label:     "Ability to be a network service",
   219  						Connections: []client.PlugRef{
   220  							{
   221  								Snap: "paste-daemon",
   222  								Name: "network-listening",
   223  							},
   224  							{
   225  								Snap: "time-daemon",
   226  								Name: "network-listening",
   227  							},
   228  						},
   229  					},
   230  				},
   231  				Plugs: []client.Plug{
   232  					{
   233  						Snap:      "paste-daemon",
   234  						Name:      "network-listening",
   235  						Interface: "network-listening",
   236  						Label:     "Ability to be a network service",
   237  						Connections: []client.SlotRef{
   238  							{
   239  								Snap: "canonical-pi2",
   240  								Name: "network-listening",
   241  							},
   242  						},
   243  					},
   244  					{
   245  						Snap:      "time-daemon",
   246  						Name:      "network-listening",
   247  						Interface: "network-listening",
   248  						Label:     "Ability to be a network service",
   249  						Connections: []client.SlotRef{
   250  							{
   251  								Snap: "canonical-pi2",
   252  								Name: "network-listening",
   253  							},
   254  						},
   255  					},
   256  				},
   257  			},
   258  		})
   259  	})
   260  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
   261  	c.Assert(err, IsNil)
   262  	c.Assert(rest, DeepEquals, []string{})
   263  	expectedStdout := "" +
   264  		"Slot                             Plug\n" +
   265  		"canonical-pi2:network-listening  paste-daemon,time-daemon\n"
   266  	c.Assert(s.Stdout(), Equals, expectedStdout)
   267  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   268  }
   269  
   270  func (s *SnapSuite) TestInterfacesOsSnapSlots(c *C) {
   271  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   272  		c.Check(r.Method, Equals, "GET")
   273  		c.Check(r.URL.Path, Equals, "/v2/connections")
   274  		body, err := ioutil.ReadAll(r.Body)
   275  		c.Check(err, IsNil)
   276  		c.Check(body, DeepEquals, []byte{})
   277  		EncodeResponseBody(c, w, map[string]interface{}{
   278  			"type": "sync",
   279  			"result": client.Connections{
   280  				Slots: []client.Slot{
   281  					{
   282  						Snap:      "system",
   283  						Name:      "network-listening",
   284  						Interface: "network-listening",
   285  						Label:     "Ability to be a network service",
   286  						Connections: []client.PlugRef{
   287  							{
   288  								Snap: "paste-daemon",
   289  								Name: "network-listening",
   290  							},
   291  							{
   292  								Snap: "time-daemon",
   293  								Name: "network-listening",
   294  							},
   295  						},
   296  					},
   297  				},
   298  				Plugs: []client.Plug{
   299  					{
   300  						Snap:      "paste-daemon",
   301  						Name:      "network-listening",
   302  						Interface: "network-listening",
   303  						Label:     "Ability to be a network service",
   304  						Connections: []client.SlotRef{
   305  							{
   306  								Snap: "system",
   307  								Name: "network-listening",
   308  							},
   309  						},
   310  					},
   311  					{
   312  						Snap:      "time-daemon",
   313  						Name:      "network-listening",
   314  						Interface: "network-listening",
   315  						Label:     "Ability to be a network service",
   316  						Connections: []client.SlotRef{
   317  							{
   318  								Snap: "system",
   319  								Name: "network-listening",
   320  							},
   321  						},
   322  					},
   323  				},
   324  			},
   325  		})
   326  	})
   327  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
   328  	c.Assert(err, IsNil)
   329  	c.Assert(rest, DeepEquals, []string{})
   330  	expectedStdout := "" +
   331  		"Slot                Plug\n" +
   332  		":network-listening  paste-daemon,time-daemon\n"
   333  	c.Assert(s.Stdout(), Equals, expectedStdout)
   334  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   335  }
   336  
   337  func (s *SnapSuite) TestInterfacesTwoSlotsAndFiltering(c *C) {
   338  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   339  		c.Check(r.Method, Equals, "GET")
   340  		c.Check(r.URL.Path, Equals, "/v2/connections")
   341  		body, err := ioutil.ReadAll(r.Body)
   342  		c.Check(err, IsNil)
   343  		c.Check(body, DeepEquals, []byte{})
   344  		EncodeResponseBody(c, w, map[string]interface{}{
   345  			"type": "sync",
   346  			"result": client.Connections{
   347  				Slots: []client.Slot{
   348  					{
   349  						Snap:      "canonical-pi2",
   350  						Name:      "debug-console",
   351  						Interface: "serial-port",
   352  						Label:     "Serial port on the expansion header",
   353  						Connections: []client.PlugRef{
   354  							{
   355  								Snap: "core",
   356  								Name: "debug-console",
   357  							},
   358  						},
   359  					},
   360  					{
   361  						Snap:      "canonical-pi2",
   362  						Name:      "pin-13",
   363  						Interface: "bool-file",
   364  						Label:     "Pin 13",
   365  						Connections: []client.PlugRef{
   366  							{
   367  								Snap: "keyboard-lights",
   368  								Name: "capslock-led",
   369  							},
   370  						},
   371  					},
   372  				},
   373  			},
   374  		})
   375  	})
   376  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces", "-i=serial-port"})
   377  	c.Assert(err, IsNil)
   378  	c.Assert(rest, DeepEquals, []string{})
   379  	expectedStdout := "" +
   380  		"Slot                         Plug\n" +
   381  		"canonical-pi2:debug-console  core\n"
   382  	c.Assert(s.Stdout(), Equals, expectedStdout)
   383  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   384  }
   385  
   386  func (s *SnapSuite) TestInterfacesOfSpecificSnap(c *C) {
   387  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   388  		c.Check(r.Method, Equals, "GET")
   389  		c.Check(r.URL.Path, Equals, "/v2/connections")
   390  		body, err := ioutil.ReadAll(r.Body)
   391  		c.Check(err, IsNil)
   392  		c.Check(body, DeepEquals, []byte{})
   393  		EncodeResponseBody(c, w, map[string]interface{}{
   394  			"type": "sync",
   395  			"result": client.Connections{
   396  				Slots: []client.Slot{
   397  					{
   398  						Snap:      "cheese",
   399  						Name:      "photo-trigger",
   400  						Interface: "bool-file",
   401  						Label:     "Photo trigger",
   402  					},
   403  					{
   404  						Snap:      "wake-up-alarm",
   405  						Name:      "toggle",
   406  						Interface: "bool-file",
   407  						Label:     "Alarm toggle",
   408  					},
   409  					{
   410  						Snap:      "wake-up-alarm",
   411  						Name:      "snooze",
   412  						Interface: "bool-file",
   413  						Label:     "Alarm snooze",
   414  					},
   415  				},
   416  			},
   417  		})
   418  	})
   419  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces", "wake-up-alarm"})
   420  	c.Assert(err, IsNil)
   421  	c.Assert(rest, DeepEquals, []string{})
   422  	expectedStdout := "" +
   423  		"Slot                  Plug\n" +
   424  		"wake-up-alarm:toggle  -\n" +
   425  		"wake-up-alarm:snooze  -\n"
   426  	c.Assert(s.Stdout(), Equals, expectedStdout)
   427  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   428  }
   429  
   430  func (s *SnapSuite) TestInterfacesOfSystemNicknameSnap(c *C) {
   431  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   432  		c.Check(r.Method, Equals, "GET")
   433  		c.Check(r.URL.Path, Equals, "/v2/connections")
   434  		body, err := ioutil.ReadAll(r.Body)
   435  		c.Check(err, IsNil)
   436  		c.Check(body, DeepEquals, []byte{})
   437  		EncodeResponseBody(c, w, map[string]interface{}{
   438  			"type": "sync",
   439  			"result": client.Connections{
   440  				Slots: []client.Slot{
   441  					{
   442  						Snap:        "system",
   443  						Name:        "core-support",
   444  						Interface:   "some-iface",
   445  						Connections: []client.PlugRef{{Snap: "core", Name: "core-support-plug"}},
   446  					}, {
   447  						Snap:      "foo",
   448  						Name:      "foo-slot",
   449  						Interface: "foo-slot-iface",
   450  					},
   451  				},
   452  				Plugs: []client.Plug{
   453  					{
   454  						Snap:        "core",
   455  						Name:        "core-support-plug",
   456  						Interface:   "some-iface",
   457  						Connections: []client.SlotRef{{Snap: "system", Name: "core-support"}},
   458  					},
   459  				},
   460  			},
   461  		})
   462  	})
   463  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces", "system"})
   464  	c.Assert(err, IsNil)
   465  	c.Assert(rest, DeepEquals, []string{})
   466  	expectedStdout := "" +
   467  		"Slot           Plug\n" +
   468  		":core-support  core:core-support-plug\n"
   469  	c.Assert(s.Stdout(), Equals, expectedStdout)
   470  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   471  
   472  	s.ResetStdStreams()
   473  
   474  	// when called with system nickname we get the same output
   475  	rest, err = Parser(Client()).ParseArgs([]string{"interfaces", "system"})
   476  	c.Assert(err, IsNil)
   477  	c.Assert(rest, DeepEquals, []string{})
   478  	expectedStdoutSystem := "" +
   479  		"Slot           Plug\n" +
   480  		":core-support  core:core-support-plug\n"
   481  	c.Assert(s.Stdout(), Equals, expectedStdoutSystem)
   482  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   483  }
   484  
   485  func (s *SnapSuite) TestInterfacesOfSpecificSnapAndSlot(c *C) {
   486  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   487  		c.Check(r.Method, Equals, "GET")
   488  		c.Check(r.URL.Path, Equals, "/v2/connections")
   489  		body, err := ioutil.ReadAll(r.Body)
   490  		c.Check(err, IsNil)
   491  		c.Check(body, DeepEquals, []byte{})
   492  		EncodeResponseBody(c, w, map[string]interface{}{
   493  			"type": "sync",
   494  			"result": client.Connections{
   495  				Slots: []client.Slot{
   496  					{
   497  						Snap:      "cheese",
   498  						Name:      "photo-trigger",
   499  						Interface: "bool-file",
   500  						Label:     "Photo trigger",
   501  					},
   502  					{
   503  						Snap:      "wake-up-alarm",
   504  						Name:      "toggle",
   505  						Interface: "bool-file",
   506  						Label:     "Alarm toggle",
   507  					},
   508  					{
   509  						Snap:      "wake-up-alarm",
   510  						Name:      "snooze",
   511  						Interface: "bool-file",
   512  						Label:     "Alarm snooze",
   513  					},
   514  				},
   515  			},
   516  		})
   517  	})
   518  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces", "wake-up-alarm:snooze"})
   519  	c.Assert(err, IsNil)
   520  	c.Assert(rest, DeepEquals, []string{})
   521  	expectedStdout := "" +
   522  		"Slot                  Plug\n" +
   523  		"wake-up-alarm:snooze  -\n"
   524  	c.Assert(s.Stdout(), Equals, expectedStdout)
   525  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   526  }
   527  
   528  func (s *SnapSuite) TestInterfacesNothingAtAll(c *C) {
   529  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   530  		c.Check(r.Method, Equals, "GET")
   531  		c.Check(r.URL.Path, Equals, "/v2/connections")
   532  		body, err := ioutil.ReadAll(r.Body)
   533  		c.Check(err, IsNil)
   534  		c.Check(body, DeepEquals, []byte{})
   535  		EncodeResponseBody(c, w, map[string]interface{}{
   536  			"type":   "sync",
   537  			"result": client.Connections{},
   538  		})
   539  	})
   540  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces"})
   541  	c.Assert(err, ErrorMatches, "no interfaces found")
   542  	// XXX: not sure why this is returned, I guess that's what happens when a
   543  	// command Execute returns an error.
   544  	c.Assert(rest, DeepEquals, []string{"interfaces"})
   545  	c.Assert(s.Stdout(), Equals, "")
   546  	c.Assert(s.Stderr(), Equals, "")
   547  }
   548  
   549  func (s *SnapSuite) TestInterfacesOfSpecificType(c *C) {
   550  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   551  		c.Check(r.Method, Equals, "GET")
   552  		c.Check(r.URL.Path, Equals, "/v2/connections")
   553  		body, err := ioutil.ReadAll(r.Body)
   554  		c.Check(err, IsNil)
   555  		c.Check(body, DeepEquals, []byte{})
   556  		EncodeResponseBody(c, w, map[string]interface{}{
   557  			"type": "sync",
   558  			"result": client.Connections{
   559  				Slots: []client.Slot{
   560  					{
   561  						Snap:      "cheese",
   562  						Name:      "photo-trigger",
   563  						Interface: "bool-file",
   564  						Label:     "Photo trigger",
   565  					},
   566  					{
   567  						Snap:      "wake-up-alarm",
   568  						Name:      "toggle",
   569  						Interface: "bool-file",
   570  						Label:     "Alarm toggle",
   571  					},
   572  					{
   573  						Snap:      "wake-up-alarm",
   574  						Name:      "snooze",
   575  						Interface: "bool-file",
   576  						Label:     "Alarm snooze",
   577  					},
   578  				},
   579  			},
   580  		})
   581  	})
   582  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces", "-i", "bool-file"})
   583  	c.Assert(err, IsNil)
   584  	c.Assert(rest, DeepEquals, []string{})
   585  	expectedStdout := "" +
   586  		"Slot                  Plug\n" +
   587  		"cheese:photo-trigger  -\n" +
   588  		"wake-up-alarm:toggle  -\n" +
   589  		"wake-up-alarm:snooze  -\n"
   590  	c.Assert(s.Stdout(), Equals, expectedStdout)
   591  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   592  }
   593  
   594  func (s *SnapSuite) TestInterfacesCompletion(c *C) {
   595  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   596  		switch r.URL.Path {
   597  		case "/v2/connections":
   598  			c.Assert(r.Method, Equals, "GET")
   599  			EncodeResponseBody(c, w, map[string]interface{}{
   600  				"type":   "sync",
   601  				"result": fortestingConnectionList,
   602  			})
   603  		default:
   604  			c.Fatalf("unexpected path %q", r.URL.Path)
   605  		}
   606  	})
   607  	os.Setenv("GO_FLAGS_COMPLETION", "verbose")
   608  	defer os.Unsetenv("GO_FLAGS_COMPLETION")
   609  
   610  	expected := []flags.Completion{}
   611  	parser := Parser(Client())
   612  	parser.CompletionHandler = func(obtained []flags.Completion) {
   613  		c.Check(obtained, DeepEquals, expected)
   614  	}
   615  
   616  	expected = []flags.Completion{{Item: "canonical-pi2:"}, {Item: "core:"}, {Item: "keyboard-lights:"}, {Item: "paste-daemon:"}, {Item: "potato:"}, {Item: "wake-up-alarm:"}}
   617  	_, err := parser.ParseArgs([]string{"interfaces", ""})
   618  	c.Assert(err, IsNil)
   619  
   620  	expected = []flags.Completion{{Item: "paste-daemon:network-listening", Description: "plug"}}
   621  	_, err = parser.ParseArgs([]string{"interfaces", "pa"})
   622  	c.Assert(err, IsNil)
   623  
   624  	expected = []flags.Completion{{Item: "wake-up-alarm:toggle", Description: "slot"}}
   625  	_, err = parser.ParseArgs([]string{"interfaces", "wa"})
   626  	c.Assert(err, IsNil)
   627  
   628  	c.Assert(s.Stdout(), Equals, "")
   629  	c.Assert(s.Stderr(), Equals, "")
   630  }
   631  
   632  func (s *SnapSuite) TestInterfacesCoreNicknamedSystem(c *C) {
   633  	s.checkConnectionsSystemCoreRemapping(c, "core", "system")
   634  }
   635  
   636  func (s *SnapSuite) TestInterfacesSnapdNicknamedSystem(c *C) {
   637  	s.checkConnectionsSystemCoreRemapping(c, "snapd", "system")
   638  }
   639  
   640  func (s *SnapSuite) TestInterfacesSnapdNicknamedCore(c *C) {
   641  	s.checkConnectionsSystemCoreRemapping(c, "snapd", "core")
   642  }
   643  
   644  func (s *SnapSuite) TestInterfacesCoreSnap(c *C) {
   645  	s.checkConnectionsSystemCoreRemapping(c, "core", "core")
   646  }
   647  
   648  func (s *SnapSuite) checkConnectionsSystemCoreRemapping(c *C, apiSnapName, cliSnapName string) {
   649  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   650  		c.Check(r.Method, Equals, "GET")
   651  		c.Check(r.URL.Path, Equals, "/v2/connections")
   652  		body, err := ioutil.ReadAll(r.Body)
   653  		c.Check(err, IsNil)
   654  		c.Check(body, DeepEquals, []byte{})
   655  		EncodeResponseBody(c, w, map[string]interface{}{
   656  			"type": "sync",
   657  			"result": client.Connections{
   658  				Slots: []client.Slot{
   659  					{
   660  						Snap: apiSnapName,
   661  						Name: "network",
   662  					},
   663  				},
   664  			},
   665  		})
   666  	})
   667  	rest, err := Parser(Client()).ParseArgs([]string{"interfaces", cliSnapName})
   668  	c.Assert(err, IsNil)
   669  	c.Assert(rest, DeepEquals, []string{})
   670  	expectedStdout := "" +
   671  		"Slot      Plug\n" +
   672  		":network  -\n"
   673  	c.Assert(s.Stdout(), Equals, expectedStdout)
   674  	c.Assert(s.Stderr(), testutil.EqualsWrapped, InterfacesDeprecationNotice)
   675  }