github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/overlord/snapstate/backend/locking_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 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 backend_test
    21  
    22  import (
    23  	"errors"
    24  
    25  	. "gopkg.in/check.v1"
    26  
    27  	"github.com/snapcore/snapd/cmd/snaplock"
    28  	"github.com/snapcore/snapd/cmd/snaplock/runinhibit"
    29  	"github.com/snapcore/snapd/dirs"
    30  	"github.com/snapcore/snapd/osutil"
    31  	"github.com/snapcore/snapd/overlord/snapstate/backend"
    32  	"github.com/snapcore/snapd/snap/snaptest"
    33  )
    34  
    35  type lockingSuite struct {
    36  	be backend.Backend
    37  }
    38  
    39  var _ = Suite(&lockingSuite{})
    40  
    41  func (s *lockingSuite) SetUpTest(c *C) {
    42  	dirs.SetRootDir(c.MkDir())
    43  }
    44  
    45  func (s *lockingSuite) TestRunInhibitSnapForUnlinkPositiveDescision(c *C) {
    46  	const yaml = `name: snap-name
    47  version: 1
    48  `
    49  	info := snaptest.MockInfo(c, yaml, nil)
    50  	lock, err := s.be.RunInhibitSnapForUnlink(info, "hint", func() error {
    51  		// This decision function returns nil so the lock is established and
    52  		// the inhibition hint is set.
    53  		return nil
    54  	})
    55  	c.Assert(err, IsNil)
    56  	c.Assert(lock, NotNil)
    57  	lock.Close()
    58  	hint, err := runinhibit.IsLocked(info.InstanceName())
    59  	c.Assert(err, IsNil)
    60  	c.Check(string(hint), Equals, "hint")
    61  }
    62  
    63  func (s *lockingSuite) TestRunInhibitSnapForUnlinkNegativeDecision(c *C) {
    64  	const yaml = `name: snap-name
    65  version: 1
    66  `
    67  	info := snaptest.MockInfo(c, yaml, nil)
    68  	lock, err := s.be.RunInhibitSnapForUnlink(info, "hint", func() error {
    69  		// This decision function returns an error so the lock is not
    70  		// established and the inhibition hint is not set.
    71  		return errors.New("propagated")
    72  	})
    73  	c.Assert(err, ErrorMatches, "propagated")
    74  	c.Assert(lock, IsNil)
    75  	hint, err := runinhibit.IsLocked(info.InstanceName())
    76  	c.Assert(err, IsNil)
    77  	c.Check(string(hint), Equals, "")
    78  }
    79  
    80  func (s *lockingSuite) TestWithSnapLock(c *C) {
    81  	const yaml = `name: snap-name
    82  version: 1
    83  `
    84  	info := snaptest.MockInfo(c, yaml, nil)
    85  
    86  	lock, err := snaplock.OpenLock(info.InstanceName())
    87  	c.Assert(err, IsNil)
    88  	defer lock.Close()
    89  	c.Assert(lock.TryLock(), IsNil) // Lock is not held
    90  	lock.Unlock()
    91  
    92  	err = backend.WithSnapLock(info, func() error {
    93  		c.Assert(lock.TryLock(), Equals, osutil.ErrAlreadyLocked) // Lock is held
    94  		return errors.New("error-is-propagated")
    95  	})
    96  	c.Check(err, ErrorMatches, "error-is-propagated")
    97  
    98  	c.Assert(lock.TryLock(), IsNil) // Lock is not held
    99  }