github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/snap/cmd_interface_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 ) 33 34 func (s *SnapSuite) TestInterfaceHelp(c *C) { 35 msg := `Usage: 36 snap.test interface [interface-OPTIONS] [<interface>] 37 38 The interface command shows details of snap interfaces. 39 40 If no interface name is provided, a list of interface names with at least 41 one connection is shown, or a list of all interfaces if --all is provided. 42 43 [interface command options] 44 --attrs Show interface attributes 45 --all Include unused interfaces 46 47 [interface command arguments] 48 <interface>: Show details of a specific interface 49 ` 50 s.testSubCommandHelp(c, "interface", msg) 51 } 52 53 func (s *SnapSuite) TestInterfaceListEmpty(c *C) { 54 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 55 c.Check(r.Method, Equals, "GET") 56 c.Check(r.URL.Path, Equals, "/v2/interfaces") 57 c.Check(r.URL.RawQuery, Equals, "select=connected") 58 body, err := ioutil.ReadAll(r.Body) 59 c.Check(err, IsNil) 60 c.Check(body, DeepEquals, []byte{}) 61 EncodeResponseBody(c, w, map[string]interface{}{ 62 "type": "sync", 63 "result": []*client.Interface{}, 64 }) 65 }) 66 rest, err := Parser(Client()).ParseArgs([]string{"interface"}) 67 c.Assert(err, ErrorMatches, "no interfaces currently connected") 68 c.Assert(rest, DeepEquals, []string{"interface"}) 69 c.Assert(s.Stdout(), Equals, "") 70 c.Assert(s.Stderr(), Equals, "") 71 } 72 73 func (s *SnapSuite) TestInterfaceListAllEmpty(c *C) { 74 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 75 c.Check(r.Method, Equals, "GET") 76 c.Check(r.URL.Path, Equals, "/v2/interfaces") 77 c.Check(r.URL.RawQuery, Equals, "select=all") 78 body, err := ioutil.ReadAll(r.Body) 79 c.Check(err, IsNil) 80 c.Check(body, DeepEquals, []byte{}) 81 EncodeResponseBody(c, w, map[string]interface{}{ 82 "type": "sync", 83 "result": []*client.Interface{}, 84 }) 85 }) 86 rest, err := Parser(Client()).ParseArgs([]string{"interface", "--all"}) 87 c.Assert(err, ErrorMatches, "no interfaces found") 88 c.Assert(rest, DeepEquals, []string{"--all"}) // XXX: feels like a bug in go-flags. 89 c.Assert(s.Stdout(), Equals, "") 90 c.Assert(s.Stderr(), Equals, "") 91 } 92 93 func (s *SnapSuite) TestInterfaceList(c *C) { 94 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 95 c.Check(r.Method, Equals, "GET") 96 c.Check(r.URL.Path, Equals, "/v2/interfaces") 97 c.Check(r.URL.RawQuery, Equals, "select=connected") 98 body, err := ioutil.ReadAll(r.Body) 99 c.Check(err, IsNil) 100 c.Check(body, DeepEquals, []byte{}) 101 EncodeResponseBody(c, w, map[string]interface{}{ 102 "type": "sync", 103 "result": []*client.Interface{{ 104 Name: "network", 105 Summary: "allows access to the network", 106 }, { 107 Name: "network-bind", 108 Summary: "allows providing services on the network", 109 }}, 110 }) 111 }) 112 rest, err := Parser(Client()).ParseArgs([]string{"interface"}) 113 c.Assert(err, IsNil) 114 c.Assert(rest, DeepEquals, []string{}) 115 expectedStdout := "" + 116 "Name Summary\n" + 117 "network allows access to the network\n" + 118 "network-bind allows providing services on the network\n" 119 c.Assert(s.Stdout(), Equals, expectedStdout) 120 c.Assert(s.Stderr(), Equals, "") 121 } 122 123 func (s *SnapSuite) TestInterfaceListAll(c *C) { 124 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 125 c.Check(r.Method, Equals, "GET") 126 c.Check(r.URL.Path, Equals, "/v2/interfaces") 127 c.Check(r.URL.RawQuery, Equals, "select=all") 128 body, err := ioutil.ReadAll(r.Body) 129 c.Check(err, IsNil) 130 c.Check(body, DeepEquals, []byte{}) 131 EncodeResponseBody(c, w, map[string]interface{}{ 132 "type": "sync", 133 "result": []*client.Interface{{ 134 Name: "network", 135 Summary: "allows access to the network", 136 }, { 137 Name: "network-bind", 138 Summary: "allows providing services on the network", 139 }, { 140 Name: "unused", 141 Summary: "just an unused interface, nothing to see here", 142 }}, 143 }) 144 }) 145 rest, err := Parser(Client()).ParseArgs([]string{"interface", "--all"}) 146 c.Assert(err, IsNil) 147 c.Assert(rest, DeepEquals, []string{}) 148 expectedStdout := "" + 149 "Name Summary\n" + 150 "network allows access to the network\n" + 151 "network-bind allows providing services on the network\n" + 152 "unused just an unused interface, nothing to see here\n" 153 c.Assert(s.Stdout(), Equals, expectedStdout) 154 c.Assert(s.Stderr(), Equals, "") 155 } 156 157 func (s *SnapSuite) TestInterfaceDetails(c *C) { 158 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 159 c.Check(r.Method, Equals, "GET") 160 c.Check(r.URL.Path, Equals, "/v2/interfaces") 161 c.Check(r.URL.RawQuery, Equals, "doc=true&names=network&plugs=true&select=all&slots=true") 162 body, err := ioutil.ReadAll(r.Body) 163 c.Check(err, IsNil) 164 c.Check(body, DeepEquals, []byte{}) 165 EncodeResponseBody(c, w, map[string]interface{}{ 166 "type": "sync", 167 "result": []*client.Interface{{ 168 Name: "network", 169 Summary: "allows access to the network", 170 DocURL: "http://example.org/about-the-network-interface", 171 Plugs: []client.Plug{ 172 {Snap: "deepin-music", Name: "network"}, 173 {Snap: "http", Name: "network"}, 174 }, 175 Slots: []client.Slot{{Snap: "system", Name: "network"}}, 176 }}, 177 }) 178 }) 179 rest, err := Parser(Client()).ParseArgs([]string{"interface", "network"}) 180 c.Assert(err, IsNil) 181 c.Assert(rest, DeepEquals, []string{}) 182 expectedStdout := "" + 183 "name: network\n" + 184 "summary: allows access to the network\n" + 185 "documentation: http://example.org/about-the-network-interface\n" + 186 "plugs:\n" + 187 " - deepin-music\n" + 188 " - http\n" + 189 "slots:\n" + 190 " - system\n" 191 c.Assert(s.Stdout(), Equals, expectedStdout) 192 c.Assert(s.Stderr(), Equals, "") 193 } 194 195 func (s *SnapSuite) TestInterfaceDetailsAndAttrs(c *C) { 196 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 197 c.Check(r.Method, Equals, "GET") 198 c.Check(r.URL.Path, Equals, "/v2/interfaces") 199 c.Check(r.URL.RawQuery, Equals, "doc=true&names=serial-port&plugs=true&select=all&slots=true") 200 body, err := ioutil.ReadAll(r.Body) 201 c.Check(err, IsNil) 202 c.Check(body, DeepEquals, []byte{}) 203 EncodeResponseBody(c, w, map[string]interface{}{ 204 "type": "sync", 205 "result": []*client.Interface{{ 206 Name: "serial-port", 207 Summary: "allows providing or using a specific serial port", 208 Plugs: []client.Plug{ 209 {Snap: "minicom", Name: "serial-port"}, 210 }, 211 Slots: []client.Slot{{ 212 Snap: "gizmo-gadget", 213 Name: "debug-serial-port", 214 Label: "serial port for debugging", 215 Attrs: map[string]interface{}{ 216 "header": "pin-array", 217 "location": "internal", 218 "path": "/dev/ttyS0", 219 "number": 1, 220 }, 221 }}, 222 }}, 223 }) 224 }) 225 rest, err := Parser(Client()).ParseArgs([]string{"interface", "--attrs", "serial-port"}) 226 c.Assert(err, IsNil) 227 c.Assert(rest, DeepEquals, []string{}) 228 expectedStdout := "" + 229 "name: serial-port\n" + 230 "summary: allows providing or using a specific serial port\n" + 231 "plugs:\n" + 232 " - minicom\n" + 233 "slots:\n" + 234 " - gizmo-gadget:debug-serial-port (serial port for debugging):\n" + 235 " header: pin-array\n" + 236 " location: internal\n" + 237 " number: 1\n" + 238 " path: /dev/ttyS0\n" 239 c.Assert(s.Stdout(), Equals, expectedStdout) 240 c.Assert(s.Stderr(), Equals, "") 241 } 242 243 func (s *SnapSuite) TestInterfaceCompletion(c *C) { 244 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 245 c.Assert(r.Method, Equals, "GET") 246 c.Check(r.URL.Path, Equals, "/v2/interfaces") 247 c.Check(r.URL.RawQuery, Equals, "select=all") 248 EncodeResponseBody(c, w, map[string]interface{}{ 249 "type": "sync", 250 "result": []*client.Interface{{ 251 Name: "network", 252 Summary: "allows access to the network", 253 }, { 254 Name: "network-bind", 255 Summary: "allows providing services on the network", 256 }}, 257 }) 258 }) 259 os.Setenv("GO_FLAGS_COMPLETION", "verbose") 260 defer os.Unsetenv("GO_FLAGS_COMPLETION") 261 262 expected := []flags.Completion{} 263 parser := Parser(Client()) 264 parser.CompletionHandler = func(obtained []flags.Completion) { 265 c.Check(obtained, DeepEquals, expected) 266 } 267 268 expected = []flags.Completion{ 269 {Item: "network", Description: "allows access to the network"}, 270 {Item: "network-bind", Description: "allows providing services on the network"}, 271 } 272 _, err := parser.ParseArgs([]string{"interface", ""}) 273 c.Assert(err, IsNil) 274 275 expected = []flags.Completion{ 276 {Item: "network-bind", Description: "allows providing services on the network"}, 277 } 278 _, err = parser.ParseArgs([]string{"interface", "network-"}) 279 c.Assert(err, IsNil) 280 281 expected = []flags.Completion{} 282 _, err = parser.ParseArgs([]string{"interface", "bogus"}) 283 c.Assert(err, IsNil) 284 285 c.Assert(s.Stdout(), Equals, "") 286 c.Assert(s.Stderr(), Equals, "") 287 }