func (s *RepositorySuite) SetUpTest(c *C) { // NOTE: the names provider/consumer are confusing. They will be fixed shortly. provider, err := snap.InfoFromSnapYaml([]byte(` name: provider apps: app: plugs: plug: interface: interface label: label attr: value `)) c.Assert(err, IsNil) s.plug = &Plug{PlugInfo: provider.Plugs["plug"]} consumer, err := snap.InfoFromSnapYaml([]byte(` name: consumer apps: app: slots: slot: interface: interface label: label attr: value `)) c.Assert(err, IsNil) s.slot = &Slot{SlotInfo: consumer.Slots["slot"]} s.emptyRepo = NewRepository() s.testRepo = NewRepository() err = s.testRepo.AddInterface(s.iface) c.Assert(err, IsNil) }
func (s *DisconnectSnapSuite) SetUpTest(c *C) { s.repo = NewRepository() err := s.repo.AddInterface(&TestInterface{InterfaceName: "iface-a"}) c.Assert(err, IsNil) err = s.repo.AddInterface(&TestInterface{InterfaceName: "iface-b"}) c.Assert(err, IsNil) s.s1, err = snap.InfoFromSnapYaml([]byte(` name: s1 plugs: iface-a: slots: iface-b: `)) c.Assert(err, IsNil) err = s.repo.AddSnap(s.s1) c.Assert(err, IsNil) s.s2, err = snap.InfoFromSnapYaml([]byte(` name: s2 plugs: iface-b: slots: iface-a: `)) c.Assert(err, IsNil) err = s.repo.AddSnap(s.s2) c.Assert(err, IsNil) }
func (s *YamlSuite) TestUnmarshalSlotsImplicitlyDefinedExplicitlyBoundToApps(c *C) { // NOTE: yaml content cannot use tabs, indent the section with spaces. info, err := snap.InfoFromSnapYaml([]byte(` name: snap apps: app: slots: ["network-client"] `)) c.Assert(err, IsNil) c.Check(info.Name(), Equals, "snap") c.Check(info.Plugs, HasLen, 0) c.Check(info.Slots, HasLen, 1) c.Check(info.Apps, HasLen, 1) slot := info.Slots["network-client"] app := info.Apps["app"] c.Assert(slot, DeepEquals, &snap.SlotInfo{ Snap: info, Name: "network-client", Interface: "network-client", Apps: map[string]*snap.AppInfo{app.Name: app}, }) c.Assert(app, DeepEquals, &snap.AppInfo{ Snap: info, Name: "app", Slots: map[string]*snap.SlotInfo{slot.Name: slot}, }) }
func (s *BoolFileInterfaceSuite) SetUpTest(c *C) { info, err := snap.InfoFromSnapYaml([]byte(` name: ubuntu-core slots: gpio: interface: bool-file path: /sys/class/gpio/gpio13/value led: interface: bool-file path: "/sys/class/leds/input27::capslock/brightness" missing-path: bool-file bad-path: interface: bool-file path: path parent-dir-path: interface: bool-file path: "/sys/class/gpio/../value" bad-interface: other-interface plugs: plug: bool-file bad-interface: other-interface `)) c.Assert(err, IsNil) s.gpioSlot = &interfaces.Slot{SlotInfo: info.Slots["gpio"]} s.ledSlot = &interfaces.Slot{SlotInfo: info.Slots["led"]} s.missingPathSlot = &interfaces.Slot{SlotInfo: info.Slots["missing-path"]} s.badPathSlot = &interfaces.Slot{SlotInfo: info.Slots["bad-path"]} s.parentDirPathSlot = &interfaces.Slot{SlotInfo: info.Slots["parent-dir-path"]} s.badInterfaceSlot = &interfaces.Slot{SlotInfo: info.Slots["bad-interface"]} s.plug = &interfaces.Plug{PlugInfo: info.Plugs["plug"]} s.badInterfacePlug = &interfaces.Plug{PlugInfo: info.Plugs["bad-interface"]} }
func (s *YamlSuite) TestUnmarshalEmpty(c *C) { info, err := snap.InfoFromSnapYaml([]byte(``)) c.Assert(err, IsNil) c.Assert(info.Plugs, HasLen, 0) c.Assert(info.Slots, HasLen, 0) c.Assert(info.Apps, HasLen, 0) }
func (s *interfaceManagerSuite) mockSnap(c *C, yamlText string) *snap.Info { s.state.Lock() defer s.state.Unlock() // Parse the yaml snapInfo, err := snap.InfoFromSnapYaml([]byte(yamlText)) c.Assert(err, IsNil) snap.AddImplicitSlots(snapInfo) // Create on-disk yaml file (it is read by snapstate) dname := filepath.Join(dirs.SnapSnapsDir, snapInfo.Name(), strconv.Itoa(snapInfo.Revision), "meta") fname := filepath.Join(dname, "snap.yaml") err = os.MkdirAll(dname, 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(fname, []byte(yamlText), 0644) c.Assert(err, IsNil) // Put a side info into the state snapstate.Set(s.state, snapInfo.Name(), &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{{Revision: snapInfo.Revision}}, }) return snapInfo }
func (s *AddRemoveSuite) TestAddSnapComplexErrorHandling(c *C) { err := s.repo.AddInterface(&TestInterface{ InterfaceName: "invalid-plug-iface", SanitizePlugCallback: func(plug *Plug) error { return fmt.Errorf("plug is invalid") }, SanitizeSlotCallback: func(slot *Slot) error { return fmt.Errorf("slot is invalid") }, }) err = s.repo.AddInterface(&TestInterface{ InterfaceName: "invalid-slot-iface", SanitizePlugCallback: func(plug *Plug) error { return fmt.Errorf("plug is invalid") }, SanitizeSlotCallback: func(slot *Slot) error { return fmt.Errorf("slot is invalid") }, }) snapInfo, err := snap.InfoFromSnapYaml([]byte(` name: complex plugs: invalid-plug-iface: unknown-plug-iface: slots: invalid-slot-iface: unknown-slot-iface: `)) c.Assert(err, IsNil) err = s.repo.AddSnap(snapInfo) c.Check(err, ErrorMatches, `snap "complex" has bad plugs or slots: invalid-plug-iface \(plug is invalid\); invalid-slot-iface \(slot is invalid\); unknown-plug-iface, unknown-slot-iface \(unknown interface\)`) // Nothing was added c.Check(s.repo.Plug("complex", "invalid-plug-iface"), IsNil) c.Check(s.repo.Plug("complex", "unknown-plug-iface"), IsNil) c.Check(s.repo.Slot("complex", "invalid-slot-iface"), IsNil) c.Check(s.repo.Slot("complex", "unknown-slot-iface"), IsNil) }
func (s *InfoSnapYamlTestSuite) TestSimple(c *C) { info, err := snap.InfoFromSnapYaml(mockYaml) c.Assert(err, IsNil) c.Assert(info.Name(), Equals, "foo") c.Assert(info.Version, Equals, "1.0") c.Assert(info.Type, Equals, snap.TypeApp) }
func (s *apiSuite) mockSnap(c *C, yamlText string) *snap.Info { if s.d == nil { panic("call s.daemon(c) in your test first") } st := s.d.overlord.State() st.Lock() defer st.Unlock() // Parse the yaml snapInfo, err := snap.InfoFromSnapYaml([]byte(yamlText)) c.Assert(err, IsNil) snap.AddImplicitSlots(snapInfo) // Create on-disk yaml file (it is read by snapstate) dname := filepath.Join(dirs.SnapSnapsDir, snapInfo.Name(), strconv.Itoa(snapInfo.Revision), "meta") fname := filepath.Join(dname, "snap.yaml") err = os.MkdirAll(dname, 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(fname, []byte(yamlText), 0644) c.Assert(err, IsNil) // Put a side info into the state snapstate.Set(st, snapInfo.Name(), &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{{Revision: snapInfo.Revision}}, }) // Put the snap into the interface repository repo := s.d.overlord.InterfaceManager().Repository() err = repo.AddSnap(snapInfo) c.Assert(err, IsNil) return snapInfo }
// Info returns information like name, type etc about the package func (s *Snap) Info() (*snap.Info, error) { snapYaml, err := s.ReadFile("meta/snap.yaml") if err != nil { return nil, fmt.Errorf("info failed for %s: %s", s.path, err) } return snap.InfoFromSnapYaml(snapYaml) }
func (s *RepositorySuite) TestAutoConnectBlacklist(c *C) { // Add two interfaces, one with automatic connections, one with manual repo := s.emptyRepo err := repo.AddInterface(&TestInterface{InterfaceName: "auto", AutoConnectFlag: true}) c.Assert(err, IsNil) err = repo.AddInterface(&TestInterface{InterfaceName: "manual"}) c.Assert(err, IsNil) // Add a pair of snaps with plugs/slots using those two interfaces consumer, err := snap.InfoFromSnapYaml([]byte(` name: consumer plugs: auto: manual: `)) c.Assert(err, IsNil) producer, err := snap.InfoFromSnapYaml([]byte(` name: producer type: os slots: auto: manual: `)) c.Assert(err, IsNil) err = repo.AddSnap(producer) c.Assert(err, IsNil) err = repo.AddSnap(consumer) c.Assert(err, IsNil) // Sanity check, our test is valid because plug "auto" is a candidate // for auto-connection c.Assert(repo.AutoConnectCandidates("consumer", "auto"), HasLen, 1) // Without any connections in place, the plug "auto" is blacklisted // because in normal circumstances it would be auto-connected. blacklist := repo.AutoConnectBlacklist("consumer") c.Check(blacklist, DeepEquals, map[string]bool{"auto": true}) // Connect the "auto" plug and slots together err = repo.Connect("consumer", "auto", "producer", "auto") c.Assert(err, IsNil) // With the connection in place the "auto" plug is not blacklisted. blacklist = repo.AutoConnectBlacklist("consumer") c.Check(blacklist, IsNil) }
func (s *YamlSuite) TestSnapYamlTypeDefault(c *C) { y := []byte(`name: binary version: 1.0 `) info, err := snap.InfoFromSnapYaml(y) c.Assert(err, IsNil) c.Assert(info.Type, Equals, snap.TypeApp) }
// installSnap "installs" a snap from YAML. func (s *backendSuite) installSnap(c *C, devMode bool, snapYaml string) *snap.Info { snapInfo, err := snap.InfoFromSnapYaml([]byte(snapYaml)) c.Assert(err, IsNil) s.addPlugsSlots(c, snapInfo) err = s.backend.Setup(snapInfo, devMode, s.repo) c.Assert(err, IsNil) return snapInfo }
func (s *YamlSuite) TestSnapYamlNoArchitecturesParsing(c *C) { y := []byte(`name: binary version: 1.0 `) info, err := snap.InfoFromSnapYaml(y) c.Assert(err, IsNil) c.Assert(info.Architectures, DeepEquals, []string{"all"}) }
func (s *SnapTestSuite) TestGenerateHardwareYamlData(c *C) { info, err := snap.InfoFromSnapYaml(hardwareYaml) c.Assert(err, IsNil) output, err := generateUdevRuleContent(&info.Legacy.Gadget.Hardware.Assign[0]) c.Assert(err, IsNil) c.Assert(output, Equals, expectedUdevRule) }
func (s *YamlSuite) TestSnapYamlAssumesParsing(c *C) { y := []byte(`name: binary version: 1.0 assumes: [feature2, feature1] `) info, err := snap.InfoFromSnapYaml(y) c.Assert(err, IsNil) c.Assert(info.Assumes, DeepEquals, []string{"feature1", "feature2"}) }
func (s *YamlSuite) TestUnmarshalCorruptedSlotWithUnexpectedType(c *C) { // NOTE: yaml content cannot use tabs, indent the section with spaces. _, err := snap.InfoFromSnapYaml([]byte(` name: snap slots: net: 5 `)) c.Assert(err, ErrorMatches, `slot "net" has malformed definition \(found int\)`) }
func (s *SnapTestSuite) TestWriteHardwareUdevEtc(c *C) { info, err := snap.InfoFromSnapYaml(hardwareYaml) c.Assert(err, IsNil) dirs.SnapUdevRulesDir = c.MkDir() writeGadgetHardwareUdevRules(info) c.Assert(osutil.FileExists(filepath.Join(dirs.SnapUdevRulesDir, "80-snappy_gadget-foo_device-hive-iot-hal.rules")), Equals, true) }
func (s *YamlSuite) TestSnapYamlMultipleArchitecturesParsing(c *C) { y := []byte(`name: binary version: 1.0 architectures: [i386, armhf] `) info, err := snap.InfoFromSnapYaml(y) c.Assert(err, IsNil) c.Assert(info.Architectures, DeepEquals, []string{"i386", "armhf"}) }
func (s *YamlSuite) TestUnmarshalCorruptedSlotWithNonStringLabel(c *C) { // NOTE: yaml content cannot use tabs, indent the section with spaces. _, err := snap.InfoFromSnapYaml([]byte(` name: snap slots: bool-file: label: 1.0 `)) c.Assert(err, ErrorMatches, `label of slot "bool-file" is not a string \(found float64\)`) }
func (s *YamlSuite) TestUnmarshalCorruptedSlotWithNonStringAttributes(c *C) { // NOTE: yaml content cannot use tabs, indent the section with spaces. _, err := snap.InfoFromSnapYaml([]byte(` name: snap slots: net: 1: ok `)) c.Assert(err, ErrorMatches, `slot "net" has attribute that is not a string \(found int\)`) }
func (s *YamlSuite) TestSnapYamlBadArchitectureParsing(c *C) { y := []byte(`name: binary version: 1.0 architectures: armhf: no `) _, err := snap.InfoFromSnapYaml(y) c.Assert(err, NotNil) }
func (s *InfoSnapYamlTestSuite) TestAddImplicitSlots(c *C) { osYaml := []byte("name: ubuntu-core\ntype: os\n") info, err := snap.InfoFromSnapYaml(osYaml) c.Assert(err, IsNil) snap.AddImplicitSlots(info) c.Assert(info.Slots["network"].Interface, Equals, "network") c.Assert(info.Slots["network"].Name, Equals, "network") c.Assert(info.Slots["network"].Snap, Equals, info) c.Assert(info.Slots, HasLen, 16) }
// updateSnap "updates" an existing snap from YAML. func (s *backendSuite) updateSnap(c *C, oldSnapInfo *snap.Info, devMode bool, snapYaml string) *snap.Info { newSnapInfo, err := snap.InfoFromSnapYaml([]byte(snapYaml)) c.Assert(err, IsNil) c.Assert(newSnapInfo.Name(), Equals, oldSnapInfo.Name()) s.removePlugsSlots(c, oldSnapInfo) s.addPlugsSlots(c, newSnapInfo) err = s.backend.Setup(newSnapInfo, devMode, s.repo) c.Assert(err, IsNil) return newSnapInfo }
func (s *SnapTestSuite) TestParseHardwareYaml(c *C) { info, err := snap.InfoFromSnapYaml(hardwareYaml) c.Assert(err, IsNil) c.Assert(info.Legacy.Gadget.Hardware.Assign[0].PartID, Equals, "device-hive-iot-hal") c.Assert(info.Legacy.Gadget.Hardware.Assign[0].Rules[0].Kernel, Equals, "ttyUSB0") c.Assert(info.Legacy.Gadget.Hardware.Assign[0].Rules[1].Subsystem, Equals, "tty") c.Assert(info.Legacy.Gadget.Hardware.Assign[0].Rules[1].WithDriver, Equals, "pl2303") c.Assert(info.Legacy.Gadget.Hardware.Assign[0].Rules[1].WithAttrs[0], Equals, "idVendor=0xf00f00") c.Assert(info.Legacy.Gadget.Hardware.Assign[0].Rules[1].WithAttrs[1], Equals, "idProduct=0xb00") }
func (s *SnapTestSuite) TestWriteHardwareUdevCleanup(c *C) { info, err := snap.InfoFromSnapYaml(hardwareYaml) c.Assert(err, IsNil) dirs.SnapUdevRulesDir = c.MkDir() udevRulesFile := filepath.Join(dirs.SnapUdevRulesDir, "80-snappy_gadget-foo_device-hive-iot-hal.rules") c.Assert(ioutil.WriteFile(udevRulesFile, nil, 0644), Equals, nil) cleanupGadgetHardwareUdevRules(info) c.Assert(osutil.FileExists(udevRulesFile), Equals, false) }
func (s *GadgetSuite) TestWriteApparmorAdditionalFile(c *C) { info, err := snap.InfoFromSnapYaml(hardwareYaml) c.Assert(err, IsNil) err = writeApparmorAdditionalFile(info) c.Assert(err, IsNil) content, err := ioutil.ReadFile(filepath.Join(dirs.SnapAppArmorDir, "device-hive-iot-hal.json.additional")) c.Assert(err, IsNil) c.Assert(string(content), Equals, apparmorAdditionalContent) }
func (s *YamlSuite) TestSnapYamlLicenseParsing(c *C) { y := []byte(` name: foo version: 1.0 license-agreement: explicit license-version: 12`) info, err := snap.InfoFromSnapYaml(y) c.Assert(err, IsNil) c.Assert(info.LicenseAgreement, Equals, "explicit") c.Assert(info.LicenseVersion, Equals, "12") }
func (s *YamlSuite) TestUnmarshalCorruptedSlotWithNonStringInterfaceName(c *C) { // NOTE: yaml content cannot use tabs, indent the section with spaces. _, err := snap.InfoFromSnapYaml([]byte(` name: snap slots: net: interface: 1.0 ipv6-aware: true `)) c.Assert(err, ErrorMatches, `interface name on slot "net" is not a string \(found float64\)`) }
func (s *YamlSuite) TestUnmarshalReservedSlotAttribute(c *C) { // NOTE: yaml content cannot use tabs, indent the section with spaces. _, err := snap.InfoFromSnapYaml([]byte(` name: snap slots: serial: interface: serial-port $baud-rate: [9600] `)) c.Assert(err, ErrorMatches, `slot "serial" uses reserved attribute "\$baud-rate"`) }