github.com/ethanhsieh/snapd@v0.0.0-20210615102523-3db9b8e4edc5/daemon/api_aliases_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-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 daemon_test
    21  
    22  import (
    23  	"bytes"
    24  	"context"
    25  	"encoding/json"
    26  	"net/http"
    27  	"net/http/httptest"
    28  	"os"
    29  	"path/filepath"
    30  
    31  	"gopkg.in/check.v1"
    32  
    33  	"github.com/snapcore/snapd/daemon"
    34  	"github.com/snapcore/snapd/dirs"
    35  	"github.com/snapcore/snapd/osutil"
    36  	"github.com/snapcore/snapd/overlord/snapstate"
    37  	"github.com/snapcore/snapd/overlord/state"
    38  	"github.com/snapcore/snapd/snap"
    39  )
    40  
    41  var _ = check.Suite(&aliasesSuite{})
    42  
    43  type aliasesSuite struct {
    44  	apiBaseSuite
    45  }
    46  
    47  const aliasYaml = `
    48  name: alias-snap
    49  version: 1
    50  apps:
    51   app:
    52   app2:
    53  `
    54  
    55  func (s *aliasesSuite) TestAliasSuccess(c *check.C) {
    56  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
    57  	c.Assert(err, check.IsNil)
    58  	d := s.daemon(c)
    59  
    60  	s.mockSnap(c, aliasYaml)
    61  
    62  	oldAutoAliases := snapstate.AutoAliases
    63  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
    64  		return nil, nil
    65  	}
    66  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
    67  
    68  	d.Overlord().Loop()
    69  	defer d.Overlord().Stop()
    70  
    71  	action := &daemon.AliasAction{
    72  		Action: "alias",
    73  		Snap:   "alias-snap",
    74  		App:    "app",
    75  		Alias:  "alias1",
    76  	}
    77  	text, err := json.Marshal(action)
    78  	c.Assert(err, check.IsNil)
    79  	buf := bytes.NewBuffer(text)
    80  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
    81  	c.Assert(err, check.IsNil)
    82  	rec := httptest.NewRecorder()
    83  	s.req(c, req, nil).ServeHTTP(rec, req)
    84  	c.Assert(rec.Code, check.Equals, 202)
    85  	var body map[string]interface{}
    86  	err = json.Unmarshal(rec.Body.Bytes(), &body)
    87  	c.Check(err, check.IsNil)
    88  	id := body["change"].(string)
    89  
    90  	st := d.Overlord().State()
    91  	st.Lock()
    92  	chg := st.Change(id)
    93  	st.Unlock()
    94  	c.Assert(chg, check.NotNil)
    95  
    96  	<-chg.Ready()
    97  
    98  	st.Lock()
    99  	err = chg.Err()
   100  	st.Unlock()
   101  	c.Assert(err, check.IsNil)
   102  
   103  	// sanity check
   104  	c.Check(osutil.IsSymlink(filepath.Join(dirs.SnapBinariesDir, "alias1")), check.Equals, true)
   105  }
   106  
   107  func (s *aliasesSuite) TestAliasChangeConflict(c *check.C) {
   108  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
   109  	c.Assert(err, check.IsNil)
   110  	s.daemon(c)
   111  
   112  	s.mockSnap(c, aliasYaml)
   113  
   114  	s.simulateConflict("alias-snap")
   115  
   116  	oldAutoAliases := snapstate.AutoAliases
   117  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
   118  		return nil, nil
   119  	}
   120  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
   121  
   122  	action := &daemon.AliasAction{
   123  		Action: "alias",
   124  		Snap:   "alias-snap",
   125  		App:    "app",
   126  		Alias:  "alias1",
   127  	}
   128  	text, err := json.Marshal(action)
   129  	c.Assert(err, check.IsNil)
   130  	buf := bytes.NewBuffer(text)
   131  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
   132  	c.Assert(err, check.IsNil)
   133  	rec := httptest.NewRecorder()
   134  	s.req(c, req, nil).ServeHTTP(rec, req)
   135  	c.Check(rec.Code, check.Equals, 409)
   136  
   137  	var body map[string]interface{}
   138  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   139  	c.Check(err, check.IsNil)
   140  	c.Check(body, check.DeepEquals, map[string]interface{}{
   141  		"status-code": 409.,
   142  		"status":      "Conflict",
   143  		"result": map[string]interface{}{
   144  			"message": `snap "alias-snap" has "manip" change in progress`,
   145  			"kind":    "snap-change-conflict",
   146  			"value": map[string]interface{}{
   147  				"change-kind": "manip",
   148  				"snap-name":   "alias-snap",
   149  			},
   150  		},
   151  		"type": "error"})
   152  }
   153  
   154  func (s *aliasesSuite) TestAliasErrors(c *check.C) {
   155  	s.daemon(c)
   156  
   157  	errScenarios := []struct {
   158  		mangle func(*daemon.AliasAction)
   159  		err    string
   160  	}{
   161  		{func(a *daemon.AliasAction) { a.Action = "" }, `unsupported alias action: ""`},
   162  		{func(a *daemon.AliasAction) { a.Action = "what" }, `unsupported alias action: "what"`},
   163  		{func(a *daemon.AliasAction) { a.Snap = "lalala" }, `snap "lalala" is not installed`},
   164  		{func(a *daemon.AliasAction) { a.Alias = ".foo" }, `invalid alias name: ".foo"`},
   165  		{func(a *daemon.AliasAction) { a.Aliases = []string{"baz"} }, `cannot interpret request, snaps can no longer be expected to declare their aliases`},
   166  	}
   167  
   168  	for _, scen := range errScenarios {
   169  		action := &daemon.AliasAction{
   170  			Action: "alias",
   171  			Snap:   "alias-snap",
   172  			App:    "app",
   173  			Alias:  "alias1",
   174  		}
   175  		scen.mangle(action)
   176  
   177  		text, err := json.Marshal(action)
   178  		c.Assert(err, check.IsNil)
   179  		buf := bytes.NewBuffer(text)
   180  		req, err := http.NewRequest("POST", "/v2/aliases", buf)
   181  		c.Assert(err, check.IsNil)
   182  
   183  		rspe := s.errorReq(c, req, nil)
   184  		c.Check(rspe.Status, check.Equals, 400)
   185  		c.Check(rspe.Message, check.Matches, scen.err)
   186  	}
   187  }
   188  
   189  func (s *aliasesSuite) TestUnaliasSnapSuccess(c *check.C) {
   190  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
   191  	c.Assert(err, check.IsNil)
   192  	d := s.daemon(c)
   193  
   194  	s.mockSnap(c, aliasYaml)
   195  
   196  	oldAutoAliases := snapstate.AutoAliases
   197  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
   198  		return nil, nil
   199  	}
   200  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
   201  
   202  	d.Overlord().Loop()
   203  	defer d.Overlord().Stop()
   204  
   205  	action := &daemon.AliasAction{
   206  		Action: "unalias",
   207  		Snap:   "alias-snap",
   208  	}
   209  	text, err := json.Marshal(action)
   210  	c.Assert(err, check.IsNil)
   211  	buf := bytes.NewBuffer(text)
   212  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
   213  	c.Assert(err, check.IsNil)
   214  	rec := httptest.NewRecorder()
   215  	s.req(c, req, nil).ServeHTTP(rec, req)
   216  	c.Assert(rec.Code, check.Equals, 202)
   217  	var body map[string]interface{}
   218  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   219  	c.Check(err, check.IsNil)
   220  	id := body["change"].(string)
   221  
   222  	st := d.Overlord().State()
   223  	st.Lock()
   224  	chg := st.Change(id)
   225  	c.Check(chg.Summary(), check.Equals, `Disable all aliases for snap "alias-snap"`)
   226  	st.Unlock()
   227  	c.Assert(chg, check.NotNil)
   228  
   229  	<-chg.Ready()
   230  
   231  	st.Lock()
   232  	defer st.Unlock()
   233  	err = chg.Err()
   234  	c.Assert(err, check.IsNil)
   235  
   236  	// sanity check
   237  	var snapst snapstate.SnapState
   238  	err = snapstate.Get(st, "alias-snap", &snapst)
   239  	c.Assert(err, check.IsNil)
   240  	c.Check(snapst.AutoAliasesDisabled, check.Equals, true)
   241  }
   242  
   243  func (s *aliasesSuite) TestUnaliasDWIMSnapSuccess(c *check.C) {
   244  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
   245  	c.Assert(err, check.IsNil)
   246  	d := s.daemon(c)
   247  
   248  	s.mockSnap(c, aliasYaml)
   249  
   250  	oldAutoAliases := snapstate.AutoAliases
   251  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
   252  		return nil, nil
   253  	}
   254  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
   255  
   256  	d.Overlord().Loop()
   257  	defer d.Overlord().Stop()
   258  
   259  	action := &daemon.AliasAction{
   260  		Action: "unalias",
   261  		Snap:   "alias-snap",
   262  		Alias:  "alias-snap",
   263  	}
   264  	text, err := json.Marshal(action)
   265  	c.Assert(err, check.IsNil)
   266  	buf := bytes.NewBuffer(text)
   267  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
   268  	c.Assert(err, check.IsNil)
   269  	rec := httptest.NewRecorder()
   270  	s.req(c, req, nil).ServeHTTP(rec, req)
   271  	c.Assert(rec.Code, check.Equals, 202)
   272  	var body map[string]interface{}
   273  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   274  	c.Check(err, check.IsNil)
   275  	id := body["change"].(string)
   276  
   277  	st := d.Overlord().State()
   278  	st.Lock()
   279  	chg := st.Change(id)
   280  	c.Check(chg.Summary(), check.Equals, `Disable all aliases for snap "alias-snap"`)
   281  	st.Unlock()
   282  	c.Assert(chg, check.NotNil)
   283  
   284  	<-chg.Ready()
   285  
   286  	st.Lock()
   287  	defer st.Unlock()
   288  	err = chg.Err()
   289  	c.Assert(err, check.IsNil)
   290  
   291  	// sanity check
   292  	var snapst snapstate.SnapState
   293  	err = snapstate.Get(st, "alias-snap", &snapst)
   294  	c.Assert(err, check.IsNil)
   295  	c.Check(snapst.AutoAliasesDisabled, check.Equals, true)
   296  }
   297  
   298  func (s *aliasesSuite) TestUnaliasAliasSuccess(c *check.C) {
   299  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
   300  	c.Assert(err, check.IsNil)
   301  	d := s.daemon(c)
   302  
   303  	s.mockSnap(c, aliasYaml)
   304  
   305  	oldAutoAliases := snapstate.AutoAliases
   306  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
   307  		return nil, nil
   308  	}
   309  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
   310  
   311  	d.Overlord().Loop()
   312  	defer d.Overlord().Stop()
   313  
   314  	action := &daemon.AliasAction{
   315  		Action: "alias",
   316  		Snap:   "alias-snap",
   317  		App:    "app",
   318  		Alias:  "alias1",
   319  	}
   320  	text, err := json.Marshal(action)
   321  	c.Assert(err, check.IsNil)
   322  	buf := bytes.NewBuffer(text)
   323  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
   324  	c.Assert(err, check.IsNil)
   325  	rec := httptest.NewRecorder()
   326  	s.req(c, req, nil).ServeHTTP(rec, req)
   327  	c.Assert(rec.Code, check.Equals, 202)
   328  	var body map[string]interface{}
   329  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   330  	c.Check(err, check.IsNil)
   331  	id := body["change"].(string)
   332  
   333  	st := d.Overlord().State()
   334  	st.Lock()
   335  	chg := st.Change(id)
   336  	st.Unlock()
   337  	c.Assert(chg, check.NotNil)
   338  
   339  	<-chg.Ready()
   340  
   341  	st.Lock()
   342  	err = chg.Err()
   343  	st.Unlock()
   344  	c.Assert(err, check.IsNil)
   345  
   346  	// unalias
   347  	action = &daemon.AliasAction{
   348  		Action: "unalias",
   349  		Alias:  "alias1",
   350  	}
   351  	text, err = json.Marshal(action)
   352  	c.Assert(err, check.IsNil)
   353  	buf = bytes.NewBuffer(text)
   354  	req, err = http.NewRequest("POST", "/v2/aliases", buf)
   355  	c.Assert(err, check.IsNil)
   356  	rec = httptest.NewRecorder()
   357  	s.req(c, req, nil).ServeHTTP(rec, req)
   358  	c.Assert(rec.Code, check.Equals, 202)
   359  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   360  	c.Check(err, check.IsNil)
   361  	id = body["change"].(string)
   362  
   363  	st.Lock()
   364  	chg = st.Change(id)
   365  	c.Check(chg.Summary(), check.Equals, `Remove manual alias "alias1" for snap "alias-snap"`)
   366  	st.Unlock()
   367  	c.Assert(chg, check.NotNil)
   368  
   369  	<-chg.Ready()
   370  
   371  	st.Lock()
   372  	defer st.Unlock()
   373  	err = chg.Err()
   374  	c.Assert(err, check.IsNil)
   375  
   376  	// sanity check
   377  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapBinariesDir, "alias1")), check.Equals, false)
   378  }
   379  
   380  func (s *aliasesSuite) TestUnaliasDWIMAliasSuccess(c *check.C) {
   381  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
   382  	c.Assert(err, check.IsNil)
   383  	d := s.daemon(c)
   384  
   385  	s.mockSnap(c, aliasYaml)
   386  
   387  	oldAutoAliases := snapstate.AutoAliases
   388  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
   389  		return nil, nil
   390  	}
   391  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
   392  
   393  	d.Overlord().Loop()
   394  	defer d.Overlord().Stop()
   395  
   396  	action := &daemon.AliasAction{
   397  		Action: "alias",
   398  		Snap:   "alias-snap",
   399  		App:    "app",
   400  		Alias:  "alias1",
   401  	}
   402  	text, err := json.Marshal(action)
   403  	c.Assert(err, check.IsNil)
   404  	buf := bytes.NewBuffer(text)
   405  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
   406  	c.Assert(err, check.IsNil)
   407  	rec := httptest.NewRecorder()
   408  	s.req(c, req, nil).ServeHTTP(rec, req)
   409  	c.Assert(rec.Code, check.Equals, 202)
   410  	var body map[string]interface{}
   411  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   412  	c.Check(err, check.IsNil)
   413  	id := body["change"].(string)
   414  
   415  	st := d.Overlord().State()
   416  	st.Lock()
   417  	chg := st.Change(id)
   418  	st.Unlock()
   419  	c.Assert(chg, check.NotNil)
   420  
   421  	<-chg.Ready()
   422  
   423  	st.Lock()
   424  	err = chg.Err()
   425  	st.Unlock()
   426  	c.Assert(err, check.IsNil)
   427  
   428  	// DWIM unalias an alias
   429  	action = &daemon.AliasAction{
   430  		Action: "unalias",
   431  		Snap:   "alias1",
   432  		Alias:  "alias1",
   433  	}
   434  	text, err = json.Marshal(action)
   435  	c.Assert(err, check.IsNil)
   436  	buf = bytes.NewBuffer(text)
   437  	req, err = http.NewRequest("POST", "/v2/aliases", buf)
   438  	c.Assert(err, check.IsNil)
   439  	rec = httptest.NewRecorder()
   440  	s.req(c, req, nil).ServeHTTP(rec, req)
   441  	c.Assert(rec.Code, check.Equals, 202)
   442  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   443  	c.Check(err, check.IsNil)
   444  	id = body["change"].(string)
   445  
   446  	st.Lock()
   447  	chg = st.Change(id)
   448  	c.Check(chg.Summary(), check.Equals, `Remove manual alias "alias1" for snap "alias-snap"`)
   449  	st.Unlock()
   450  	c.Assert(chg, check.NotNil)
   451  
   452  	<-chg.Ready()
   453  
   454  	st.Lock()
   455  	defer st.Unlock()
   456  	err = chg.Err()
   457  	c.Assert(err, check.IsNil)
   458  
   459  	// sanity check
   460  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapBinariesDir, "alias1")), check.Equals, false)
   461  }
   462  
   463  func (s *aliasesSuite) TestPreferSuccess(c *check.C) {
   464  	err := os.MkdirAll(dirs.SnapBinariesDir, 0755)
   465  	c.Assert(err, check.IsNil)
   466  	d := s.daemon(c)
   467  
   468  	s.mockSnap(c, aliasYaml)
   469  
   470  	oldAutoAliases := snapstate.AutoAliases
   471  	snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) {
   472  		return nil, nil
   473  	}
   474  	defer func() { snapstate.AutoAliases = oldAutoAliases }()
   475  
   476  	d.Overlord().Loop()
   477  	defer d.Overlord().Stop()
   478  
   479  	action := &daemon.AliasAction{
   480  		Action: "prefer",
   481  		Snap:   "alias-snap",
   482  	}
   483  	text, err := json.Marshal(action)
   484  	c.Assert(err, check.IsNil)
   485  	buf := bytes.NewBuffer(text)
   486  	req, err := http.NewRequest("POST", "/v2/aliases", buf)
   487  	c.Assert(err, check.IsNil)
   488  	rec := httptest.NewRecorder()
   489  	s.req(c, req, nil).ServeHTTP(rec, req)
   490  	c.Assert(rec.Code, check.Equals, 202)
   491  	var body map[string]interface{}
   492  	err = json.Unmarshal(rec.Body.Bytes(), &body)
   493  	c.Check(err, check.IsNil)
   494  	id := body["change"].(string)
   495  
   496  	st := d.Overlord().State()
   497  	st.Lock()
   498  	chg := st.Change(id)
   499  	c.Check(chg.Summary(), check.Equals, `Prefer aliases of snap "alias-snap"`)
   500  	st.Unlock()
   501  	c.Assert(chg, check.NotNil)
   502  
   503  	<-chg.Ready()
   504  
   505  	st.Lock()
   506  	defer st.Unlock()
   507  	err = chg.Err()
   508  	c.Assert(err, check.IsNil)
   509  
   510  	// sanity check
   511  	var snapst snapstate.SnapState
   512  	err = snapstate.Get(st, "alias-snap", &snapst)
   513  	c.Assert(err, check.IsNil)
   514  	c.Check(snapst.AutoAliasesDisabled, check.Equals, false)
   515  }
   516  
   517  func (s *aliasesSuite) TestAliases(c *check.C) {
   518  	d := s.daemon(c)
   519  
   520  	st := d.Overlord().State()
   521  	st.Lock()
   522  	snapstate.Set(st, "alias-snap1", &snapstate.SnapState{
   523  		Sequence: []*snap.SideInfo{
   524  			{RealName: "alias-snap1", Revision: snap.R(11)},
   525  		},
   526  		Current: snap.R(11),
   527  		Active:  true,
   528  		Aliases: map[string]*snapstate.AliasTarget{
   529  			"alias1": {Manual: "cmd1x", Auto: "cmd1"},
   530  			"alias2": {Auto: "cmd2"},
   531  		},
   532  	})
   533  	snapstate.Set(st, "alias-snap2", &snapstate.SnapState{
   534  		Sequence: []*snap.SideInfo{
   535  			{RealName: "alias-snap2", Revision: snap.R(12)},
   536  		},
   537  		Current:             snap.R(12),
   538  		Active:              true,
   539  		AutoAliasesDisabled: true,
   540  		Aliases: map[string]*snapstate.AliasTarget{
   541  			"alias2": {Auto: "cmd2"},
   542  			"alias3": {Manual: "cmd3"},
   543  			"alias4": {Manual: "cmd4x", Auto: "cmd4"},
   544  		},
   545  	})
   546  	st.Unlock()
   547  
   548  	req, err := http.NewRequest("GET", "/v2/aliases", nil)
   549  	c.Assert(err, check.IsNil)
   550  
   551  	rsp := s.syncReq(c, req, nil)
   552  	c.Check(rsp.Status, check.Equals, 200)
   553  	c.Check(rsp.Result, check.DeepEquals, map[string]map[string]daemon.AliasStatus{
   554  		"alias-snap1": {
   555  			"alias1": {
   556  				Command: "alias-snap1.cmd1x",
   557  				Status:  "manual",
   558  				Manual:  "cmd1x",
   559  				Auto:    "cmd1",
   560  			},
   561  			"alias2": {
   562  				Command: "alias-snap1.cmd2",
   563  				Status:  "auto",
   564  				Auto:    "cmd2",
   565  			},
   566  		},
   567  		"alias-snap2": {
   568  			"alias2": {
   569  				Command: "alias-snap2.cmd2",
   570  				Status:  "disabled",
   571  				Auto:    "cmd2",
   572  			},
   573  			"alias3": {
   574  				Command: "alias-snap2.cmd3",
   575  				Status:  "manual",
   576  				Manual:  "cmd3",
   577  			},
   578  			"alias4": {
   579  				Command: "alias-snap2.cmd4x",
   580  				Status:  "manual",
   581  				Manual:  "cmd4x",
   582  				Auto:    "cmd4",
   583  			},
   584  		},
   585  	})
   586  
   587  }
   588  
   589  func (s *aliasesSuite) TestInstallUnaliased(c *check.C) {
   590  	var calledFlags snapstate.Flags
   591  
   592  	defer daemon.MockSnapstateInstall(func(ctx context.Context, s *state.State, name string, opts *snapstate.RevisionOptions, userID int, flags snapstate.Flags) (*state.TaskSet, error) {
   593  		calledFlags = flags
   594  
   595  		t := s.NewTask("fake-install-snap", "Doing a fake install")
   596  		return state.NewTaskSet(t), nil
   597  	})()
   598  
   599  	d := s.daemon(c)
   600  	inst := &daemon.SnapInstruction{
   601  		Action: "install",
   602  		// Install the snap without enabled automatic aliases
   603  		Unaliased: true,
   604  		Snaps:     []string{"fake"},
   605  	}
   606  
   607  	st := d.Overlord().State()
   608  	st.Lock()
   609  	defer st.Unlock()
   610  	_, _, err := inst.Dispatch()(inst, st)
   611  	c.Check(err, check.IsNil)
   612  
   613  	c.Check(calledFlags.Unaliased, check.Equals, true)
   614  }
   615  
   616  func (s *aliasesSuite) TestInstallIgnoreRunning(c *check.C) {
   617  	var calledFlags snapstate.Flags
   618  
   619  	defer daemon.MockSnapstateInstall(func(ctx context.Context, s *state.State, name string, opts *snapstate.RevisionOptions, userID int, flags snapstate.Flags) (*state.TaskSet, error) {
   620  		calledFlags = flags
   621  
   622  		t := s.NewTask("fake-install-snap", "Doing a fake install")
   623  		return state.NewTaskSet(t), nil
   624  	})()
   625  
   626  	d := s.daemon(c)
   627  	inst := &daemon.SnapInstruction{
   628  		Action: "install",
   629  		// Install the snap without enabled automatic aliases
   630  		IgnoreRunning: true,
   631  		Snaps:         []string{"fake"},
   632  	}
   633  
   634  	st := d.Overlord().State()
   635  	st.Lock()
   636  	defer st.Unlock()
   637  	_, _, err := inst.Dispatch()(inst, st)
   638  	c.Check(err, check.IsNil)
   639  
   640  	c.Check(calledFlags.IgnoreRunning, check.Equals, true)
   641  }