github.com/stulluk/snapd@v0.0.0-20210611110309-f6d5d5bd24b0/cmd/snap/cmd_known_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  	"fmt"
    24  	"net/http"
    25  	"net/http/httptest"
    26  	"net/url"
    27  
    28  	"github.com/jessevdk/go-flags"
    29  	"gopkg.in/check.v1"
    30  
    31  	"github.com/snapcore/snapd/client"
    32  	"github.com/snapcore/snapd/store"
    33  
    34  	snap "github.com/snapcore/snapd/cmd/snap"
    35  )
    36  
    37  // acquire example data via:
    38  // curl  -H "accept: application/x.ubuntu.assertion" https://assertions.ubuntu.com/v1/assertions/model/16/canonical/pi2
    39  const mockModelAssertion = `type: model
    40  authority-id: canonical
    41  series: 16
    42  brand-id: canonical
    43  model: pi99
    44  architecture: armhf
    45  gadget: pi99
    46  kernel: pi99-kernel
    47  timestamp: 2016-08-31T00:00:00.0Z
    48  sign-key-sha3-384: 9tydnLa6MTJ-jaQTFUXEwHl1yRx7ZS4K5cyFDhYDcPzhS7uyEkDxdUjg9g08BtNn
    49  
    50  AcLorsomethingthatlooksvaguelylikeasignature==
    51  `
    52  
    53  func (s *SnapSuite) TestKnownViaSnapd(c *check.C) {
    54  	n := 0
    55  	expectedQuery := url.Values{
    56  		"series":   []string{"16"},
    57  		"brand-id": []string{"canonical"},
    58  		"model":    []string{"pi99"},
    59  	}
    60  
    61  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    62  		switch n {
    63  		case 0:
    64  			c.Check(r.URL.Path, check.Equals, "/v2/assertions/model")
    65  			c.Check(r.URL.Query(), check.DeepEquals, expectedQuery)
    66  			w.Header().Set("X-Ubuntu-Assertions-Count", "1")
    67  			fmt.Fprintln(w, mockModelAssertion)
    68  		default:
    69  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
    70  		}
    71  		n++
    72  	})
    73  
    74  	// first run "normal"
    75  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "model", "series=16", "brand-id=canonical", "model=pi99"})
    76  	c.Assert(err, check.IsNil)
    77  	c.Assert(rest, check.DeepEquals, []string{})
    78  	c.Check(s.Stdout(), check.Equals, mockModelAssertion)
    79  	c.Check(s.Stderr(), check.Equals, "")
    80  	c.Check(n, check.Equals, 1)
    81  
    82  	// then with "--remote"
    83  	n = 0
    84  	s.stdout.Reset()
    85  	expectedQuery["remote"] = []string{"true"}
    86  	rest, err = snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "model", "series=16", "brand-id=canonical", "model=pi99"})
    87  	c.Assert(err, check.IsNil)
    88  	c.Assert(rest, check.DeepEquals, []string{})
    89  	c.Check(s.Stdout(), check.Equals, mockModelAssertion)
    90  	c.Check(s.Stderr(), check.Equals, "")
    91  	c.Check(n, check.Equals, 1)
    92  }
    93  
    94  func (s *SnapSuite) TestKnownRemoteViaSnapd(c *check.C) {
    95  	n := 0
    96  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    97  		switch n {
    98  		case 0:
    99  			c.Check(r.URL.Path, check.Equals, "/v2/assertions/model")
   100  			c.Check(r.URL.Query(), check.DeepEquals, url.Values{
   101  				"series":   []string{"16"},
   102  				"brand-id": []string{"canonical"},
   103  				"model":    []string{"pi99"},
   104  				"remote":   []string{"true"},
   105  			})
   106  			w.Header().Set("X-Ubuntu-Assertions-Count", "1")
   107  			fmt.Fprintln(w, mockModelAssertion)
   108  		default:
   109  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   110  		}
   111  		n++
   112  	})
   113  
   114  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "model", "series=16", "brand-id=canonical", "model=pi99"})
   115  	c.Assert(err, check.IsNil)
   116  	c.Assert(rest, check.DeepEquals, []string{})
   117  	c.Check(s.Stdout(), check.Equals, mockModelAssertion)
   118  	c.Check(s.Stderr(), check.Equals, "")
   119  	c.Check(n, check.Equals, 1)
   120  }
   121  
   122  func (s *SnapSuite) TestKnownRemoteDirect(c *check.C) {
   123  	var server *httptest.Server
   124  
   125  	restorer := snap.MockStoreNew(func(cfg *store.Config, stoCtx store.DeviceAndAuthContext) *store.Store {
   126  		if cfg == nil {
   127  			cfg = store.DefaultConfig()
   128  		}
   129  		serverURL, _ := url.Parse(server.URL)
   130  		cfg.AssertionsBaseURL = serverURL
   131  		return store.New(cfg, stoCtx)
   132  	})
   133  	defer restorer()
   134  
   135  	n := 0
   136  	server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   137  		c.Assert(r.URL.Path, check.Matches, ".*/assertions/.*") // sanity check request
   138  		switch n {
   139  		case 0:
   140  			c.Check(r.Method, check.Equals, "GET")
   141  			c.Check(r.URL.Path, check.Equals, "/v2/assertions/model/16/canonical/pi99")
   142  			fmt.Fprintln(w, mockModelAssertion)
   143  		default:
   144  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   145  		}
   146  
   147  		n++
   148  	}))
   149  
   150  	// first test "--remote --direct"
   151  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "--direct", "model", "series=16", "brand-id=canonical", "model=pi99"})
   152  	c.Assert(err, check.IsNil)
   153  	c.Assert(rest, check.DeepEquals, []string{})
   154  	c.Check(s.Stdout(), check.Equals, mockModelAssertion)
   155  	c.Check(s.Stderr(), check.Equals, "")
   156  	c.Check(n, check.Equals, 1)
   157  
   158  	// "--direct" behave the same as "--remote --direct"
   159  	s.stdout.Reset()
   160  	n = 0
   161  	rest, err = snap.Parser(snap.Client()).ParseArgs([]string{"known", "--direct", "model", "series=16", "brand-id=canonical", "model=pi99"})
   162  	c.Assert(err, check.IsNil)
   163  	c.Assert(rest, check.DeepEquals, []string{})
   164  	c.Check(s.Stdout(), check.Equals, mockModelAssertion)
   165  	c.Check(s.Stderr(), check.Equals, "")
   166  	c.Check(n, check.Equals, 1)
   167  }
   168  
   169  func (s *SnapSuite) TestKnownRemoteAutoFallback(c *check.C) {
   170  	var server *httptest.Server
   171  
   172  	restorer := snap.MockStoreNew(func(cfg *store.Config, stoCtx store.DeviceAndAuthContext) *store.Store {
   173  		if cfg == nil {
   174  			cfg = store.DefaultConfig()
   175  		}
   176  		serverURL, _ := url.Parse(server.URL)
   177  		cfg.AssertionsBaseURL = serverURL
   178  		return store.New(cfg, stoCtx)
   179  	})
   180  	defer restorer()
   181  
   182  	n := 0
   183  	server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   184  		c.Assert(r.URL.Path, check.Matches, ".*/assertions/.*") // sanity check request
   185  		switch n {
   186  		case 0:
   187  			c.Check(r.Method, check.Equals, "GET")
   188  			c.Check(r.URL.Path, check.Equals, "/v2/assertions/model/16/canonical/pi99")
   189  			fmt.Fprintln(w, mockModelAssertion)
   190  		default:
   191  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   192  		}
   193  		n++
   194  	}))
   195  
   196  	cli := snap.Client()
   197  	cli.Hijack(func(*http.Request) (*http.Response, error) {
   198  		return nil, client.ConnectionError{Err: fmt.Errorf("no snapd")}
   199  	})
   200  
   201  	rest, err := snap.Parser(cli).ParseArgs([]string{"known", "--remote", "model", "series=16", "brand-id=canonical", "model=pi99"})
   202  	c.Assert(err, check.IsNil)
   203  	c.Assert(rest, check.DeepEquals, []string{})
   204  	c.Check(s.Stdout(), check.Equals, mockModelAssertion)
   205  	c.Check(s.Stderr(), check.Equals, "")
   206  }
   207  
   208  func (s *SnapSuite) TestKnownRemoteMissingPrimaryKey(c *check.C) {
   209  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "--direct", "model", "series=16", "brand-id=canonical"})
   210  	c.Assert(err, check.ErrorMatches, `cannot query remote assertion: must provide primary key: model`)
   211  }
   212  
   213  func (s *SnapSuite) TestAssertTypeNameCompletion(c *check.C) {
   214  	n := 0
   215  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   216  		switch n {
   217  		case 0:
   218  			c.Check(r.Method, check.Equals, "GET")
   219  			c.Check(r.URL.Path, check.Equals, "/v2/assertions")
   220  			fmt.Fprintln(w, `{"type": "sync", "result": { "types": [ "account", "... more stuff ...", "validation" ] } }`)
   221  		default:
   222  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   223  		}
   224  
   225  		n++
   226  	})
   227  
   228  	c.Check(snap.AssertTypeNameCompletion("v"), check.DeepEquals, []flags.Completion{{Item: "validation"}})
   229  	c.Check(n, check.Equals, 1)
   230  }