gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/kmod/backend_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 kmod_test
    21  
    22  import (
    23  	"path/filepath"
    24  	"testing"
    25  
    26  	. "gopkg.in/check.v1"
    27  
    28  	"gitee.com/mysnapcore/mysnapd/dirs"
    29  	"gitee.com/mysnapcore/mysnapd/interfaces"
    30  	"gitee.com/mysnapcore/mysnapd/interfaces/ifacetest"
    31  	"gitee.com/mysnapcore/mysnapd/interfaces/kmod"
    32  	"gitee.com/mysnapcore/mysnapd/osutil"
    33  	"gitee.com/mysnapcore/mysnapd/snap"
    34  	"gitee.com/mysnapcore/mysnapd/testutil"
    35  	"gitee.com/mysnapcore/mysnapd/timings"
    36  )
    37  
    38  func Test(t *testing.T) {
    39  	TestingT(t)
    40  }
    41  
    42  type backendSuite struct {
    43  	ifacetest.BackendSuite
    44  	modprobeCmd *testutil.MockCmd
    45  	meas        *timings.Span
    46  }
    47  
    48  var _ = Suite(&backendSuite{})
    49  
    50  var testedConfinementOpts = []interfaces.ConfinementOptions{
    51  	{},
    52  	{DevMode: true},
    53  	{JailMode: true},
    54  	{Classic: true},
    55  }
    56  
    57  func (s *backendSuite) SetUpTest(c *C) {
    58  	s.Backend = &kmod.Backend{}
    59  	s.BackendSuite.SetUpTest(c)
    60  	c.Assert(s.Repo.AddBackend(s.Backend), IsNil)
    61  	s.modprobeCmd = testutil.MockCommand(c, "modprobe", "")
    62  
    63  	perf := timings.New(nil)
    64  	s.meas = perf.StartSpan("", "")
    65  }
    66  
    67  func (s *backendSuite) TearDownTest(c *C) {
    68  	s.modprobeCmd.Restore()
    69  	s.BackendSuite.TearDownTest(c)
    70  }
    71  
    72  func (s *backendSuite) TestName(c *C) {
    73  	c.Check(s.Backend.Name(), Equals, interfaces.SecurityKMod)
    74  }
    75  
    76  func (s *backendSuite) TestInstallingSnapCreatesModulesConf(c *C) {
    77  	// NOTE: Hand out a permanent snippet so that .conf file is generated.
    78  	s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error {
    79  		spec.AddModule("module1")
    80  		spec.AddModule("module2")
    81  		return nil
    82  	}
    83  
    84  	path := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf")
    85  	c.Assert(osutil.FileExists(path), Equals, false)
    86  
    87  	for _, opts := range testedConfinementOpts {
    88  		s.modprobeCmd.ForgetCalls()
    89  		snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0)
    90  
    91  		c.Assert(osutil.FileExists(path), Equals, true)
    92  		c.Assert(path, testutil.FileEquals, "# This file is automatically generated.\nmodule1\nmodule2\n")
    93  
    94  		c.Assert(s.modprobeCmd.Calls(), DeepEquals, [][]string{
    95  			{"modprobe", "--syslog", "module1"},
    96  			{"modprobe", "--syslog", "module2"},
    97  		})
    98  		s.RemoveSnap(c, snapInfo)
    99  	}
   100  }
   101  
   102  func (s *backendSuite) TestRemovingSnapRemovesModulesConf(c *C) {
   103  	// NOTE: Hand out a permanent snippet so that .conf file is generated.
   104  	s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error {
   105  		spec.AddModule("module1")
   106  		spec.AddModule("module2")
   107  		return nil
   108  	}
   109  
   110  	path := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf")
   111  	c.Assert(osutil.FileExists(path), Equals, false)
   112  
   113  	for _, opts := range testedConfinementOpts {
   114  		snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0)
   115  		c.Assert(osutil.FileExists(path), Equals, true)
   116  		s.RemoveSnap(c, snapInfo)
   117  		c.Assert(osutil.FileExists(path), Equals, false)
   118  	}
   119  }
   120  
   121  func (s *backendSuite) TestInstallingSnapCreatesModprobeConf(c *C) {
   122  	s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error {
   123  		spec.AddModule("module1")
   124  		spec.SetModuleOptions("module1", "opt1=true opt2=2")
   125  		spec.DisallowModule("module2")
   126  		return nil
   127  	}
   128  
   129  	modulesPath := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf")
   130  	c.Assert(osutil.FileExists(modulesPath), Equals, false)
   131  	modprobePath := filepath.Join(dirs.SnapKModModprobeDir, "snap.samba.conf")
   132  	c.Assert(osutil.FileExists(modprobePath), Equals, false)
   133  
   134  	for _, opts := range testedConfinementOpts {
   135  		s.modprobeCmd.ForgetCalls()
   136  		snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0)
   137  
   138  		c.Assert(osutil.FileExists(modulesPath), Equals, true)
   139  		c.Assert(modulesPath, testutil.FileEquals, "# This file is automatically generated.\nmodule1\n")
   140  
   141  		c.Assert(osutil.FileExists(modprobePath), Equals, true)
   142  		c.Assert(modprobePath, testutil.FileEquals, `# Generated by snapd. Do not edit
   143  
   144  blacklist module2
   145  options module1 opt1=true opt2=2
   146  `)
   147  
   148  		c.Assert(s.modprobeCmd.Calls(), DeepEquals, [][]string{
   149  			{"modprobe", "--syslog", "module1"},
   150  		})
   151  		s.RemoveSnap(c, snapInfo)
   152  	}
   153  }
   154  
   155  func (s *backendSuite) TestRemovingSnapRemovesModprobeConf(c *C) {
   156  	s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error {
   157  		spec.AddModule("module1")
   158  		spec.SetModuleOptions("module1", "opt1=true opt2=2")
   159  		spec.DisallowModule("module2")
   160  		return nil
   161  	}
   162  
   163  	modulesPath := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf")
   164  	c.Assert(osutil.FileExists(modulesPath), Equals, false)
   165  	modprobePath := filepath.Join(dirs.SnapKModModprobeDir, "snap.samba.conf")
   166  	c.Assert(osutil.FileExists(modprobePath), Equals, false)
   167  
   168  	for _, opts := range testedConfinementOpts {
   169  		snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0)
   170  		c.Assert(osutil.FileExists(modulesPath), Equals, true)
   171  		c.Assert(osutil.FileExists(modprobePath), Equals, true)
   172  		s.RemoveSnap(c, snapInfo)
   173  		c.Assert(osutil.FileExists(modulesPath), Equals, false)
   174  		c.Assert(osutil.FileExists(modprobePath), Equals, false)
   175  	}
   176  }
   177  
   178  func (s *backendSuite) TestSecurityIsStable(c *C) {
   179  	// NOTE: Hand out a permanent snippet so that .conf file is generated.
   180  	s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error {
   181  		spec.AddModule("module1")
   182  		spec.AddModule("module2")
   183  		return nil
   184  	}
   185  
   186  	for _, opts := range testedConfinementOpts {
   187  		snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0)
   188  		s.modprobeCmd.ForgetCalls()
   189  		err := s.Backend.Setup(snapInfo, opts, s.Repo, s.meas)
   190  		c.Assert(err, IsNil)
   191  		// modules conf is not re-loaded when nothing changes
   192  		c.Check(s.modprobeCmd.Calls(), HasLen, 0)
   193  		s.RemoveSnap(c, snapInfo)
   194  	}
   195  }
   196  
   197  func (s *backendSuite) TestSandboxFeatures(c *C) {
   198  	c.Assert(s.Backend.SandboxFeatures(), DeepEquals, []string{"mediated-modprobe"})
   199  }