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