github.com/chipaca/snappy@v0.0.0-20210104084008-1f06296fe8ad/cmd/snap/cmd_recovery_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 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  
    26  	. "gopkg.in/check.v1"
    27  
    28  	snap "github.com/snapcore/snapd/cmd/snap"
    29  	"github.com/snapcore/snapd/release"
    30  )
    31  
    32  func (s *SnapSuite) TestRecoveryHelp(c *C) {
    33  	msg := `Usage:
    34    snap.test recovery [recovery-OPTIONS]
    35  
    36  The recovery command lists the available recovery systems.
    37  
    38  With --show-keys it displays recovery keys that can be used to unlock the
    39  encrypted partitions if the device-specific automatic unlocking does not work.
    40  
    41  [recovery command options]
    42        --color=[auto|never|always]     Use a little bit of color to highlight
    43                                        some things. (default: auto)
    44        --unicode=[auto|never|always]   Use a little bit of Unicode to improve
    45                                        legibility. (default: auto)
    46        --show-keys                     Show recovery keys (if available) to
    47                                        unlock encrypted partitions.
    48  `
    49  	s.testSubCommandHelp(c, "recovery", msg)
    50  }
    51  
    52  func (s *SnapSuite) TestRecovery(c *C) {
    53  	n := 0
    54  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    55  		switch n {
    56  		case 0:
    57  			c.Check(r.Method, Equals, "GET")
    58  			c.Check(r.URL.Path, Equals, "/v2/systems")
    59  			c.Check(r.URL.RawQuery, Equals, "")
    60  			fmt.Fprintln(w, `{"type": "sync", "result": {
    61          "systems": [
    62             {
    63                  "current": true,
    64                  "label": "20200101",
    65                  "model": {
    66                      "model": "model-id-1",
    67                      "brand-id": "brand-id-1",
    68                      "display-name": "Wonky Model"
    69                  },
    70                  "brand": {
    71                      "id": "brand-id-1",
    72                      "username": "brand-1",
    73                      "display-name": "Wonky Publishing"
    74                  },
    75                  "actions": [
    76                      {"title": "recover", "mode": "recover"},
    77                      {"title": "reinstall", "mode": "install"}
    78                  ]
    79             },
    80             {
    81                  "label": "20200802",
    82                  "model": {
    83                      "model": "model-id-2",
    84                      "brand-id": "brand-id-1",
    85                      "display-name": "Other Model"
    86                  },
    87                  "brand": {
    88                      "id": "brand-id-2",
    89                      "username": "brand-2",
    90                      "display-name": "Other Publishing"
    91                  },
    92                  "actions": [
    93                      {"title": "recover", "mode": "recover"},
    94                      {"title": "reinstall", "mode": "install"}
    95                  ]
    96             }
    97          ]
    98  }}`)
    99  		default:
   100  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   101  		}
   102  
   103  		n++
   104  	})
   105  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"recovery"})
   106  	c.Assert(err, IsNil)
   107  	c.Assert(rest, DeepEquals, []string{})
   108  	c.Check(s.Stdout(), Equals, `
   109  Label     Brand    Model       Notes
   110  20200101  brand-1  model-id-1  current
   111  20200802  brand-2  model-id-2  -
   112  `[1:])
   113  	c.Check(s.Stderr(), Equals, "")
   114  }
   115  
   116  func (s *SnapSuite) TestNoRecoverySystems(c *C) {
   117  	n := 0
   118  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   119  		switch n {
   120  		case 0:
   121  			c.Check(r.Method, Equals, "GET")
   122  			c.Check(r.URL.Path, Equals, "/v2/systems")
   123  			c.Check(r.URL.RawQuery, Equals, "")
   124  			fmt.Fprintln(w, `{"type": "sync", "result": {}}`)
   125  		default:
   126  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   127  		}
   128  
   129  		n++
   130  	})
   131  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"recovery"})
   132  	c.Assert(err, IsNil)
   133  	c.Assert(rest, DeepEquals, []string{})
   134  	c.Check(s.Stdout(), Equals, "")
   135  	c.Check(s.Stderr(), Equals, "No recovery systems available.\n")
   136  }
   137  
   138  func (s *SnapSuite) TestNoRecoverySystemsError(c *C) {
   139  	n := 0
   140  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   141  		switch n {
   142  		case 0:
   143  			c.Check(r.Method, Equals, "GET")
   144  			c.Check(r.URL.Path, Equals, "/v2/systems")
   145  			c.Check(r.URL.RawQuery, Equals, "")
   146  			fmt.Fprintln(w, `{"type": "error", "result": {"message": "permission denied"}, "status-code": 403}`)
   147  		default:
   148  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   149  		}
   150  
   151  		n++
   152  	})
   153  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"recovery"})
   154  	c.Check(err, ErrorMatches, `cannot list recovery systems: permission denied`)
   155  }
   156  
   157  func (s *SnapSuite) TestRecoveryShowRecoveryKeyOnClassicErrors(c *C) {
   158  	restore := release.MockOnClassic(true)
   159  	defer restore()
   160  
   161  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   162  		c.Fatalf("unexpected server call")
   163  	})
   164  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"recovery", "--show-keys"})
   165  	c.Assert(err, ErrorMatches, `command "show-keys" is not available on classic systems`)
   166  }
   167  
   168  func (s *SnapSuite) TestRecoveryShowRecoveryKeyHappy(c *C) {
   169  	restore := release.MockOnClassic(false)
   170  	defer restore()
   171  
   172  	n := 0
   173  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   174  		switch n {
   175  		case 0:
   176  			c.Check(r.Method, Equals, "GET")
   177  			c.Check(r.URL.Path, Equals, "/v2/system-recovery-keys")
   178  			c.Check(r.URL.RawQuery, Equals, "")
   179  			fmt.Fprintln(w, `{"type": "sync", "result": {"recovery-key": "61665-00531-54469-09783-47273-19035-40077-28287", "reinstall-key":"1234"}}`)
   180  		default:
   181  			c.Fatalf("expected to get 1 requests, now on %d", n+1)
   182  		}
   183  
   184  		n++
   185  	})
   186  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"recovery", "--show-keys"})
   187  	c.Assert(err, IsNil)
   188  	c.Assert(rest, DeepEquals, []string{})
   189  	c.Check(s.Stdout(), Equals, `recovery:   61665-00531-54469-09783-47273-19035-40077-28287
   190  reinstall:  1234
   191  `)
   192  	c.Check(s.Stderr(), Equals, "")
   193  	c.Check(n, Equals, 1)
   194  }