github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/interfaces/core_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 interfaces_test
    21  
    22  import (
    23  	"fmt"
    24  	"testing"
    25  
    26  	. "gopkg.in/check.v1"
    27  
    28  	. "github.com/snapcore/snapd/interfaces"
    29  	"github.com/snapcore/snapd/interfaces/ifacetest"
    30  	"github.com/snapcore/snapd/snap"
    31  	"github.com/snapcore/snapd/snap/snaptest"
    32  	"github.com/snapcore/snapd/testutil"
    33  )
    34  
    35  func Test(t *testing.T) {
    36  	TestingT(t)
    37  }
    38  
    39  type CoreSuite struct {
    40  	testutil.BaseTest
    41  }
    42  
    43  var _ = Suite(&CoreSuite{})
    44  
    45  func (s *CoreSuite) SetUpTest(c *C) {
    46  	s.BaseTest.SetUpTest(c)
    47  	s.BaseTest.AddCleanup(snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {}))
    48  }
    49  
    50  func (s *CoreSuite) TearDownTest(c *C) {
    51  	s.BaseTest.TearDownTest(c)
    52  }
    53  
    54  func (s *CoreSuite) TestValidateDBusBusName(c *C) {
    55  	// https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names
    56  	validNames := []string{
    57  		"a.b", "a.b.c", "a.b1", "a.b1.c2d",
    58  		"a_a.b", "a_a.b_b.c_c", "a_a.b_b1", "a_a.b_b1.c_c2d_d",
    59  		"a-a.b", "a-a.b-b.c-c", "a-a.b-b1", "a-a.b-b1.c-c2d-d",
    60  	}
    61  	for _, name := range validNames {
    62  		err := ValidateDBusBusName(name)
    63  		c.Assert(err, IsNil)
    64  	}
    65  
    66  	invalidNames := []string{
    67  		// must not start with ':'
    68  		":a.b",
    69  		// only from [A-Z][a-z][0-9]_-
    70  		"@.a",
    71  		// elements may not start with number
    72  		"0.a",
    73  		"a.0a",
    74  		// must have more than one element
    75  		"a",
    76  		"a_a",
    77  		"a-a",
    78  		// element must not begin with '.'
    79  		".a",
    80  		// each element must be at least 1 character
    81  		"a.",
    82  		"a..b",
    83  		".a.b",
    84  		"a.b.",
    85  	}
    86  	for _, name := range invalidNames {
    87  		err := ValidateDBusBusName(name)
    88  		c.Assert(err, ErrorMatches, `invalid DBus bus name: ".*"`)
    89  	}
    90  
    91  	// must not be empty
    92  	err := ValidateDBusBusName("")
    93  	c.Assert(err, ErrorMatches, `DBus bus name must be set`)
    94  
    95  	// must not exceed maximum length
    96  	longName := make([]byte, 256)
    97  	for i := range longName {
    98  		longName[i] = 'b'
    99  	}
   100  	// make it look otherwise valid (a.bbbb...)
   101  	longName[0] = 'a'
   102  	longName[1] = '.'
   103  	err = ValidateDBusBusName(string(longName))
   104  	c.Assert(err, ErrorMatches, `DBus bus name is too long \(must be <= 255\)`)
   105  }
   106  
   107  // PlugRef.String works as expected
   108  func (s *CoreSuite) TestPlugRefString(c *C) {
   109  	ref := PlugRef{Snap: "snap", Name: "plug"}
   110  	c.Check(ref.String(), Equals, "snap:plug")
   111  	refPtr := &PlugRef{Snap: "snap", Name: "plug"}
   112  	c.Check(refPtr.String(), Equals, "snap:plug")
   113  }
   114  
   115  // SlotRef.String works as expected
   116  func (s *CoreSuite) TestSlotRefString(c *C) {
   117  	ref := SlotRef{Snap: "snap", Name: "slot"}
   118  	c.Check(ref.String(), Equals, "snap:slot")
   119  	refPtr := &SlotRef{Snap: "snap", Name: "slot"}
   120  	c.Check(refPtr.String(), Equals, "snap:slot")
   121  }
   122  
   123  // ConnRef.ID works as expected
   124  func (s *CoreSuite) TestConnRefID(c *C) {
   125  	conn := &ConnRef{
   126  		PlugRef: PlugRef{Snap: "consumer", Name: "plug"},
   127  		SlotRef: SlotRef{Snap: "producer", Name: "slot"},
   128  	}
   129  	c.Check(conn.ID(), Equals, "consumer:plug producer:slot")
   130  }
   131  
   132  // ParseConnRef works as expected
   133  func (s *CoreSuite) TestParseConnRef(c *C) {
   134  	ref, err := ParseConnRef("consumer:plug producer:slot")
   135  	c.Assert(err, IsNil)
   136  	c.Check(ref, DeepEquals, &ConnRef{
   137  		PlugRef: PlugRef{Snap: "consumer", Name: "plug"},
   138  		SlotRef: SlotRef{Snap: "producer", Name: "slot"},
   139  	})
   140  	_, err = ParseConnRef("garbage")
   141  	c.Assert(err, ErrorMatches, `malformed connection identifier: "garbage"`)
   142  	_, err = ParseConnRef("snap:plug:garbage snap:slot")
   143  	c.Assert(err, ErrorMatches, `malformed connection identifier: ".*"`)
   144  	_, err = ParseConnRef("snap:plug snap:slot:garbage")
   145  	c.Assert(err, ErrorMatches, `malformed connection identifier: ".*"`)
   146  }
   147  
   148  func (s *CoreSuite) TestSanitizePlug(c *C) {
   149  	info := snaptest.MockInfo(c, `
   150  name: snap
   151  version: 0
   152  plugs:
   153    plug:
   154      interface: iface
   155  `, nil)
   156  	plug := info.Plugs["plug"]
   157  	c.Assert(BeforePreparePlug(&ifacetest.TestInterface{
   158  		InterfaceName: "iface",
   159  	}, plug), IsNil)
   160  	c.Assert(BeforePreparePlug(&ifacetest.TestInterface{
   161  		InterfaceName:             "iface",
   162  		BeforePreparePlugCallback: func(plug *snap.PlugInfo) error { return fmt.Errorf("broken") },
   163  	}, plug), ErrorMatches, "broken")
   164  	c.Assert(BeforePreparePlug(&ifacetest.TestInterface{
   165  		InterfaceName: "other",
   166  	}, plug), ErrorMatches, `cannot sanitize plug "snap:plug" \(interface "iface"\) using interface "other"`)
   167  }
   168  
   169  func (s *CoreSuite) TestSanitizeSlot(c *C) {
   170  	info := snaptest.MockInfo(c, `
   171  name: snap
   172  version: 0
   173  slots:
   174    slot:
   175      interface: iface
   176  `, nil)
   177  	slot := info.Slots["slot"]
   178  	c.Assert(BeforePrepareSlot(&ifacetest.TestInterface{
   179  		InterfaceName: "iface",
   180  	}, slot), IsNil)
   181  	c.Assert(BeforePrepareSlot(&ifacetest.TestInterface{
   182  		InterfaceName:             "iface",
   183  		BeforePrepareSlotCallback: func(slot *snap.SlotInfo) error { return fmt.Errorf("broken") },
   184  	}, slot), ErrorMatches, "broken")
   185  	c.Assert(BeforePrepareSlot(&ifacetest.TestInterface{
   186  		InterfaceName: "other",
   187  	}, slot), ErrorMatches, `cannot sanitize slot "snap:slot" \(interface "iface"\) using interface "other"`)
   188  }