github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/interfaces/ifacetest/testiface_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2015-2017 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 ifacetest_test
    21  
    22  import (
    23  	"fmt"
    24  
    25  	. "gopkg.in/check.v1"
    26  
    27  	"github.com/snapcore/snapd/interfaces"
    28  	"github.com/snapcore/snapd/interfaces/apparmor"
    29  	"github.com/snapcore/snapd/interfaces/dbus"
    30  	"github.com/snapcore/snapd/interfaces/hotplug"
    31  	"github.com/snapcore/snapd/interfaces/ifacetest"
    32  	"github.com/snapcore/snapd/interfaces/seccomp"
    33  	"github.com/snapcore/snapd/snap"
    34  )
    35  
    36  type TestInterfaceSuite struct {
    37  	iface    interfaces.Interface
    38  	plugInfo *snap.PlugInfo
    39  	plug     *interfaces.ConnectedPlug
    40  	slotInfo *snap.SlotInfo
    41  	slot     *interfaces.ConnectedSlot
    42  }
    43  
    44  var _ = Suite(&TestInterfaceSuite{
    45  	iface: &ifacetest.TestInterface{
    46  		InterfaceName: "test",
    47  		InterfaceStaticInfo: interfaces.StaticInfo{
    48  			Summary: "summary",
    49  		},
    50  	},
    51  	plugInfo: &snap.PlugInfo{
    52  		Snap:      &snap.Info{SuggestedName: "snap"},
    53  		Name:      "name",
    54  		Interface: "test",
    55  	},
    56  	slotInfo: &snap.SlotInfo{
    57  		Snap:      &snap.Info{SuggestedName: "snap"},
    58  		Name:      "name",
    59  		Interface: "test",
    60  	},
    61  })
    62  
    63  // TestInterface has a working Name() function
    64  func (s *TestInterfaceSuite) TestName(c *C) {
    65  	c.Assert(s.iface.Name(), Equals, "test")
    66  	s.plug = interfaces.NewConnectedPlug(s.plugInfo, nil, nil)
    67  	s.slot = interfaces.NewConnectedSlot(s.slotInfo, nil, nil)
    68  }
    69  
    70  func (s *TestInterfaceSuite) TestStaticInfo(c *C) {
    71  	c.Assert(interfaces.StaticInfoOf(s.iface), Equals, interfaces.StaticInfo{
    72  		Summary: "summary",
    73  	})
    74  }
    75  
    76  // TestInterface has provisions to customize validation
    77  func (s *TestInterfaceSuite) TestBeforeConnectPlugError(c *C) {
    78  	iface := &ifacetest.TestInterface{
    79  		InterfaceName: "test",
    80  		BeforeConnectPlugCallback: func(plug *interfaces.ConnectedPlug) error {
    81  			return fmt.Errorf("plug validation failed")
    82  		},
    83  	}
    84  	err := iface.BeforeConnectPlug(s.plug)
    85  	c.Assert(err, ErrorMatches, "plug validation failed")
    86  }
    87  
    88  func (s *TestInterfaceSuite) TestBeforeConnectSlotError(c *C) {
    89  	iface := &ifacetest.TestInterface{
    90  		InterfaceName: "test",
    91  		BeforeConnectSlotCallback: func(slot *interfaces.ConnectedSlot) error {
    92  			return fmt.Errorf("slot validation failed")
    93  		},
    94  	}
    95  	err := iface.BeforeConnectSlot(s.slot)
    96  	c.Assert(err, ErrorMatches, "slot validation failed")
    97  }
    98  
    99  // TestInterface doesn't do any sanitization by default
   100  func (s *TestInterfaceSuite) TestSanitizePlugOK(c *C) {
   101  	c.Assert(interfaces.BeforePreparePlug(s.iface, s.plugInfo), IsNil)
   102  }
   103  
   104  // TestInterface has provisions to customize sanitization
   105  func (s *TestInterfaceSuite) TestSanitizePlugError(c *C) {
   106  	iface := &ifacetest.TestInterface{
   107  		InterfaceName: "test",
   108  		BeforePreparePlugCallback: func(plug *snap.PlugInfo) error {
   109  			return fmt.Errorf("sanitize plug failed")
   110  		},
   111  	}
   112  	c.Assert(interfaces.BeforePreparePlug(iface, s.plugInfo), ErrorMatches, "sanitize plug failed")
   113  }
   114  
   115  // TestInterface doesn't do any sanitization by default
   116  func (s *TestInterfaceSuite) TestSanitizeSlotOK(c *C) {
   117  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.slotInfo), IsNil)
   118  }
   119  
   120  // TestInterface has provisions to customize sanitization
   121  func (s *TestInterfaceSuite) TestSanitizeSlotError(c *C) {
   122  	iface := &ifacetest.TestInterface{
   123  		InterfaceName: "test",
   124  		BeforePrepareSlotCallback: func(slot *snap.SlotInfo) error {
   125  			return fmt.Errorf("sanitize slot failed")
   126  		},
   127  	}
   128  	c.Assert(interfaces.BeforePrepareSlot(iface, s.slotInfo), ErrorMatches, "sanitize slot failed")
   129  }
   130  
   131  // TestInterface hands out empty plug security snippets
   132  func (s *TestInterfaceSuite) TestPlugSnippet(c *C) {
   133  	iface := s.iface.(*ifacetest.TestInterface)
   134  
   135  	apparmorSpec := &apparmor.Specification{}
   136  	c.Assert(iface.AppArmorConnectedPlug(apparmorSpec, s.plug, s.slot), IsNil)
   137  	c.Assert(apparmorSpec.Snippets(), HasLen, 0)
   138  
   139  	seccompSpec := &seccomp.Specification{}
   140  	c.Assert(iface.SecCompConnectedPlug(seccompSpec, s.plug, s.slot), IsNil)
   141  	c.Assert(seccompSpec.Snippets(), HasLen, 0)
   142  
   143  	dbusSpec := &dbus.Specification{}
   144  	c.Assert(iface.DBusConnectedPlug(dbusSpec, s.plug, s.slot), IsNil)
   145  	c.Assert(dbusSpec.Snippets(), HasLen, 0)
   146  }
   147  
   148  // TestInterface hands out empty slot security snippets
   149  func (s *TestInterfaceSuite) TestSlotSnippet(c *C) {
   150  	iface := s.iface.(*ifacetest.TestInterface)
   151  
   152  	apparmorSpec := &apparmor.Specification{}
   153  	c.Assert(iface.AppArmorConnectedSlot(apparmorSpec, s.plug, s.slot), IsNil)
   154  	c.Assert(apparmorSpec.Snippets(), HasLen, 0)
   155  
   156  	seccompSpec := &seccomp.Specification{}
   157  	c.Assert(iface.SecCompConnectedSlot(seccompSpec, s.plug, s.slot), IsNil)
   158  	c.Assert(seccompSpec.Snippets(), HasLen, 0)
   159  
   160  	dbusSpec := &dbus.Specification{}
   161  	c.Assert(iface.DBusConnectedSlot(dbusSpec, s.plug, s.slot), IsNil)
   162  	c.Assert(dbusSpec.Snippets(), HasLen, 0)
   163  }
   164  
   165  func (s *TestInterfaceSuite) TestAutoConnect(c *C) {
   166  	c.Check(s.iface.AutoConnect(nil, nil), Equals, true)
   167  
   168  	iface := &ifacetest.TestInterface{AutoConnectCallback: func(*snap.PlugInfo, *snap.SlotInfo) bool { return false }}
   169  
   170  	c.Check(iface.AutoConnect(nil, nil), Equals, false)
   171  }
   172  
   173  func (s *TestInterfaceSuite) TestHotplugKeyError(c *C) {
   174  	iface := &ifacetest.TestHotplugInterface{
   175  		TestInterface: ifacetest.TestInterface{
   176  			InterfaceName: "test",
   177  		},
   178  		HotplugKeyCallback: func(deviceInfo *hotplug.HotplugDeviceInfo) (snap.HotplugKey, error) {
   179  			return "", fmt.Errorf("error")
   180  		},
   181  	}
   182  
   183  	c.Assert(iface.Name(), Equals, "test")
   184  
   185  	dev := &hotplug.HotplugDeviceInfo{}
   186  	key, err := iface.HotplugKey(dev)
   187  	c.Assert(err, ErrorMatches, "error")
   188  	c.Assert(key, DeepEquals, snap.HotplugKey(""))
   189  }
   190  
   191  func (s *TestInterfaceSuite) TestHotplugKeyOK(c *C) {
   192  	var iface interfaces.Interface
   193  	iface = &ifacetest.TestHotplugInterface{
   194  		TestInterface: ifacetest.TestInterface{
   195  			InterfaceName: "test",
   196  		},
   197  		HotplugKeyCallback: func(deviceInfo *hotplug.HotplugDeviceInfo) (snap.HotplugKey, error) {
   198  			return "key", nil
   199  		},
   200  	}
   201  
   202  	hotplugIface, ok := iface.(hotplug.HotplugKeyHandler)
   203  	c.Assert(ok, Equals, true)
   204  
   205  	dev := &hotplug.HotplugDeviceInfo{}
   206  	key, err := hotplugIface.HotplugKey(dev)
   207  	c.Assert(err, IsNil)
   208  	c.Assert(key, DeepEquals, snap.HotplugKey("key"))
   209  }
   210  
   211  func (s *TestInterfaceSuite) TestHotplugDeviceDetectedOK(c *C) {
   212  	iface := &ifacetest.TestHotplugInterface{
   213  		TestInterface: ifacetest.TestInterface{
   214  			InterfaceName: "test",
   215  		},
   216  		HotplugDeviceDetectedCallback: func(deviceInfo *hotplug.HotplugDeviceInfo) (*hotplug.ProposedSlot, error) {
   217  			return &hotplug.ProposedSlot{Name: "slot"}, nil
   218  		},
   219  	}
   220  
   221  	dev := &hotplug.HotplugDeviceInfo{}
   222  	slot, err := iface.HotplugDeviceDetected(dev)
   223  	c.Assert(err, IsNil)
   224  	c.Assert(slot.Name, Equals, "slot")
   225  }
   226  
   227  func (s *TestInterfaceSuite) TestHotplugDeviceDetectedError(c *C) {
   228  	iface := &ifacetest.TestHotplugInterface{
   229  		TestInterface: ifacetest.TestInterface{
   230  			InterfaceName: "test",
   231  		},
   232  		HotplugDeviceDetectedCallback: func(deviceInfo *hotplug.HotplugDeviceInfo) (*hotplug.ProposedSlot, error) {
   233  			return nil, fmt.Errorf("error")
   234  		},
   235  	}
   236  	dev := &hotplug.HotplugDeviceInfo{}
   237  	_, err := iface.HotplugDeviceDetected(dev)
   238  	c.Assert(err, ErrorMatches, "error")
   239  }