Skip to content

Commit

Permalink
testutil: add a maxOpen argument to NewTransportBackedDevice
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisccoulson committed Dec 20, 2024
1 parent 53d6c6c commit ad95df4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
18 changes: 17 additions & 1 deletion testutil/tpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,14 @@ var (

wrapMssimTransport = WrapTransport

// ErrSkipNoTPM is expected to be returned from tpm2.TPMDevice implementations
// in order to cause a test to be skipped if no TPM connection is available.
ErrSkipNoTPM = errors.New("no TPM configured for the test")

// ErrNoTPMDevice can be returned from tpm2.TPMDevice implementations to indicate that
// no TPM is available, but this will generally cause a test to fail rather than
// be skipped.
ErrNoTPMDevice = errors.New("no TPM device available")
)

type tpmBackendFlag TPMBackendType
Expand Down Expand Up @@ -647,6 +654,7 @@ type TransportBackedDevice struct {
mu sync.Mutex
transport *Transport
closable bool
maxOpen int
opened int
}

Expand All @@ -665,16 +673,20 @@ type TransportBackedDevice struct {
// but calling Close on any returned transport will not actually close the
// underlying transport - it will mark that specific one as closed.
//
// The maxOpen argument can limit the number of open transports. If set to
// a value <= 0, then there is no limit.
//
// Consider that whilst [tpm2.TPMDevice] implementations can generally be
// used by more than one goroutine, each opened [tpm2.Transport] is only
// safe to use from a single goroutine, and this device returns multiple
// pointers to the same transport.
//
// Note that this device does not work with [OpenTPMDevice] or [OpenTPMDeviceT].
func NewTransportBackedDevice(transport *Transport, closable bool) *TransportBackedDevice {
func NewTransportBackedDevice(transport *Transport, closable bool, maxOpen int) *TransportBackedDevice {
return &TransportBackedDevice{
transport: transport,
closable: closable,
maxOpen: maxOpen,
}
}

Expand Down Expand Up @@ -722,6 +734,10 @@ func (d *TransportBackedDevice) Open() (tpm2.Transport, error) {
d.mu.Lock()
defer d.mu.Unlock()

if d.maxOpen > 0 && d.opened >= d.maxOpen {
return nil, ErrNoTPMDevice
}

d.opened += 1
return &duplicateTransport{
Transport: d.transport,
Expand Down
31 changes: 28 additions & 3 deletions testutil/tpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type tpmSuite struct {
var _ = Suite(&tpmSuite{})

func (s *tpmSuite) TestNewTransportBackedDeviceClosable(c *C) {
device := NewTransportBackedDevice(s.Transport, true)
device := NewTransportBackedDevice(s.Transport, true, -1)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 0)

transport, err := device.Open()
Expand All @@ -41,7 +41,7 @@ func (s *tpmSuite) TestNewTransportBackedDeviceClosable(c *C) {
}

func (s *tpmSuite) TestNewTransportBackedDeviceNotClosable(c *C) {
device := NewTransportBackedDevice(s.Transport, false)
device := NewTransportBackedDevice(s.Transport, false, -1)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 0)

transport, err := device.Open()
Expand All @@ -61,7 +61,7 @@ func (s *tpmSuite) TestNewTransportBackedDeviceNotClosable(c *C) {
}

func (s *tpmSuite) TestNewTransportBackedDeviceMultipleOpen(c *C) {
device := NewTransportBackedDevice(s.Transport, false)
device := NewTransportBackedDevice(s.Transport, false, 2)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 0)

transport1, err := device.Open()
Expand All @@ -80,3 +80,28 @@ func (s *tpmSuite) TestNewTransportBackedDeviceMultipleOpen(c *C) {
// The test fixture will fail if the underlying transport was closed
// unexpectedly
}

func (s *tpmSuite) TestNewTransportBackedDeviceMaxOpen(c *C) {
device := NewTransportBackedDevice(s.Transport, false, 2)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 0)

transport1, err := device.Open()
c.Assert(err, IsNil)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 1)

transport2, err := device.Open()
c.Assert(err, IsNil)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 2)

_, err = device.Open()
c.Check(err, Equals, ErrNoTPMDevice)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 2)

c.Check(transport1.Close(), IsNil)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 1)
c.Check(transport2.Close(), IsNil)
c.Check(device.NumberOpen(), internal_testutil.IntEqual, 0)

// The test fixture will fail if the underlying transport was closed
// unexpectedly
}

0 comments on commit ad95df4

Please sign in to comment.