gitee.com/mysnapcore/mysnapd@v0.1.0/cmd/snap/cmd_debug_migrate_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2022 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  	snap "gitee.com/mysnapcore/mysnapd/cmd/snap"
    27  	"gopkg.in/check.v1"
    28  	. "gopkg.in/check.v1"
    29  )
    30  
    31  type MigrateHomeSuite struct {
    32  	BaseSnapSuite
    33  }
    34  
    35  var _ = check.Suite(&MigrateHomeSuite{})
    36  
    37  // failRequest logs an error message, fails the test and returns a proper error
    38  // to the client. Use this instead of panic() or c.Fatal() because those crash
    39  // the server and leave the client hanging/retrying.
    40  func failRequest(msg string, w http.ResponseWriter, c *C) {
    41  	c.Error(msg)
    42  	w.WriteHeader(400)
    43  	fmt.Fprintf(w, `{"type": "error", "status-code": 400, "result": {"message": %q}}`, msg)
    44  }
    45  
    46  func serverWithChange(chgRsp string, c *C) func(w http.ResponseWriter, r *http.Request) {
    47  	var n int
    48  	return func(w http.ResponseWriter, r *http.Request) {
    49  		switch n {
    50  		case 0:
    51  			c.Check(r.Method, check.Equals, "POST")
    52  			c.Check(r.URL.Path, check.Equals, "/v2/debug")
    53  			c.Check(DecodedRequestBody(c, r), check.DeepEquals, map[string]interface{}{
    54  				"action": "migrate-home",
    55  				"snaps":  []interface{}{"foo"},
    56  			})
    57  			w.WriteHeader(202)
    58  			fmt.Fprintln(w, `{"type": "async", "status-code": 202, "result": {}, "change": "12"}`)
    59  
    60  		case 1:
    61  			c.Check(r.Method, check.Equals, "GET")
    62  			c.Check(r.URL.Path, check.Equals, "/v2/changes/12")
    63  			fmt.Fprintf(w, chgRsp)
    64  
    65  		default:
    66  			failRequest(fmt.Sprintf("server expected to get 2 requests, now on %d", n+1), w, c)
    67  		}
    68  
    69  		n++
    70  	}
    71  }
    72  
    73  func (s *MigrateHomeSuite) TestMigrateHome(c *C) {
    74  	rsp := serverWithChange(`{"type": "sync", "result": {"ready": true, "status": "Done", "data": {"snap-names": ["foo"]}}}\n`, c)
    75  	s.RedirectClientToTestServer(rsp)
    76  
    77  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"debug", "migrate-home", "foo"})
    78  	c.Assert(err, check.IsNil)
    79  	c.Assert(rest, check.DeepEquals, []string{})
    80  	c.Check(s.Stdout(), check.Equals, "foo's home directory was migrated to ~/Snap\n")
    81  	c.Check(s.Stderr(), check.Equals, "")
    82  }
    83  
    84  func (s *MigrateHomeSuite) TestMigrateHomeManySnaps(c *C) {
    85  	n := 0
    86  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
    87  		switch n {
    88  		case 0:
    89  			c.Check(r.Method, check.Equals, "POST")
    90  			c.Check(r.URL.Path, check.Equals, "/v2/debug")
    91  			c.Check(DecodedRequestBody(c, r), check.DeepEquals, map[string]interface{}{
    92  				"action": "migrate-home",
    93  				"snaps":  []interface{}{"foo", "bar"},
    94  			})
    95  			w.WriteHeader(202)
    96  			fmt.Fprintln(w, `{"type": "async", "status-code": 202, "result": {}, "change": "12"}`)
    97  
    98  		case 1:
    99  			c.Check(r.Method, check.Equals, "GET")
   100  			c.Check(r.URL.Path, check.Equals, "/v2/changes/12")
   101  			fmt.Fprintf(w, `{"type": "sync", "result": {"ready": true, "status": "Done", "data": {"snap-names": ["foo", "bar"]}}}\n`)
   102  
   103  		default:
   104  			failRequest(fmt.Sprintf("server expected to get 2 requests, now on %d", n+1), w, c)
   105  		}
   106  
   107  		n++
   108  	})
   109  
   110  	rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"debug", "migrate-home", "foo", "bar"})
   111  	c.Assert(err, check.IsNil)
   112  	c.Assert(rest, check.DeepEquals, []string{})
   113  	c.Check(s.Stdout(), check.Equals, "\"foo\", \"bar\" migrated their home directories to ~/Snap\n")
   114  	c.Check(s.Stderr(), check.Equals, "")
   115  }
   116  
   117  func (s *MigrateHomeSuite) TestMigrateHomeNoSnaps(c *C) {
   118  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   119  		failRequest("unexpected request on server", w, c)
   120  	})
   121  
   122  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"debug", "migrate-home"})
   123  	c.Assert(err, check.ErrorMatches, "the required argument .* was not provided")
   124  	c.Check(s.Stdout(), check.Equals, "")
   125  	c.Check(s.Stderr(), check.Equals, "")
   126  }
   127  
   128  func (s *MigrateHomeSuite) TestMigrateHomeServerError(c *C) {
   129  	s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) {
   130  		w.WriteHeader(500)
   131  		fmt.Fprintf(w, `{"type": "error", "status-code": 500, "result": {"message": "boom"}}`)
   132  	})
   133  
   134  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"debug", "migrate-home", "foo"})
   135  	c.Assert(err, check.ErrorMatches, "boom")
   136  	c.Check(s.Stdout(), check.Equals, "")
   137  	c.Check(s.Stderr(), check.Equals, "")
   138  }
   139  
   140  func (s *MigrateHomeSuite) TestMigrateHomeBadChangeNoSnaps(c *C) {
   141  	// broken change response: missing required "snap-names"
   142  	srv := serverWithChange(`{"type": "sync", "result": {"ready": true, "status": "Done", "data": {"snap-names": []}}}\n`, c)
   143  	s.RedirectClientToTestServer(srv)
   144  
   145  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"debug", "migrate-home", "foo"})
   146  	c.Assert(err, check.ErrorMatches, `expected "migrate-home" change to have non-empty "snap-names"`)
   147  	c.Check(s.Stdout(), check.Equals, "")
   148  	c.Check(s.Stderr(), check.Equals, "")
   149  }
   150  
   151  func (s *MigrateHomeSuite) TestMigrateHomeBadChangeNoData(c *C) {
   152  	// broken change response: missing data
   153  	srv := serverWithChange(`{"type": "sync", "result": {"ready": true, "status": "Done"}}\n`, c)
   154  	s.RedirectClientToTestServer(srv)
   155  
   156  	_, err := snap.Parser(snap.Client()).ParseArgs([]string{"debug", "migrate-home", "foo"})
   157  	c.Assert(err, check.ErrorMatches, `cannot get "snap-names" from change`)
   158  	c.Check(s.Stdout(), check.Equals, "")
   159  	c.Check(s.Stderr(), check.Equals, "")
   160  }