nvidia-container-toolkit/internal/nvsandboxutils/lib_test.go
Sananya Majumder 978d439cf8 nvsandboxutils: Add internal bindings
This change adds the internal bindings for Sandboxutils, some of which
have been automatically generated with the help of c-for-go. The format
followed is similar to what is used in go-nvml. These would need to be
regenerated when the header file is modified and new APIs are added.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
Signed-off-by: Huy Nguyen <huyn@nvidia.com>
Signed-off-by: Sananya Majumder <sananyam@nvidia.com>
2024-09-24 10:05:05 -07:00

246 lines
5.5 KiB
Go

/**
# Copyright 2024 NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
**/
package nvsandboxutils
import (
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
func newTestLibrary(dl dynamicLibrary) *library {
return &library{dl: dl}
}
func TestLookupFromDefault(t *testing.T) {
errClose := errors.New("close error")
errOpen := errors.New("open error")
errLookup := errors.New("lookup error")
testCases := []struct {
description string
dl dynamicLibrary
skipLoadLibrary bool
expectedLoadError error
expectedLookupErrror error
expectedCloseError error
}{
{
description: "library not loaded yields error",
dl: &dynamicLibraryMock{},
skipLoadLibrary: true,
expectedLookupErrror: errLibraryNotLoaded,
},
{
description: "open error is returned",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return errOpen
},
},
expectedLoadError: errOpen,
expectedLookupErrror: errLibraryNotLoaded,
},
{
description: "lookup error is returned",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
LookupFunc: func(s string) error {
return fmt.Errorf("%w: %s", errLookup, s)
},
CloseFunc: func() error {
return nil
},
},
expectedLookupErrror: errLookup,
},
{
description: "lookup succeeds",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
LookupFunc: func(s string) error {
return nil
},
CloseFunc: func() error {
return nil
},
},
},
{
description: "lookup succeeds",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
LookupFunc: func(s string) error {
return nil
},
CloseFunc: func() error {
return nil
},
},
},
{
description: "close error is returned",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
LookupFunc: func(s string) error {
return nil
},
CloseFunc: func() error {
return errClose
},
},
expectedCloseError: errClose,
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
l := newTestLibrary(tc.dl)
if !tc.skipLoadLibrary {
require.ErrorIs(t, l.load(), tc.expectedLoadError)
}
require.ErrorIs(t, l.LookupSymbol("symbol"), tc.expectedLookupErrror)
require.ErrorIs(t, l.close(), tc.expectedCloseError)
if tc.expectedCloseError == nil {
require.Equal(t, 0, int(l.refcount))
} else {
require.Equal(t, 1, int(l.refcount))
}
})
}
}
func TestLoadAndCloseNesting(t *testing.T) {
dl := &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
CloseFunc: func() error {
return nil
},
}
l := newTestLibrary(dl)
// When calling close before opening the library nothing happens.
require.Equal(t, 0, len(dl.calls.Close))
require.Nil(t, l.close())
require.Equal(t, 0, len(dl.calls.Close))
// When calling load twice, the library was only opened once
require.Equal(t, 0, len(dl.calls.Open))
require.Nil(t, l.load())
require.Equal(t, 1, len(dl.calls.Open))
require.Nil(t, l.load())
require.Equal(t, 1, len(dl.calls.Open))
// Only after calling close twice, was the library closed
require.Equal(t, 0, len(dl.calls.Close))
require.Nil(t, l.close())
require.Equal(t, 0, len(dl.calls.Close))
require.Nil(t, l.close())
require.Equal(t, 1, len(dl.calls.Close))
// Calling close again doesn't attempt to close the library again
require.Nil(t, l.close())
require.Equal(t, 1, len(dl.calls.Close))
}
func TestLoadAndCloseWithErrors(t *testing.T) {
testCases := []struct {
description string
dl dynamicLibrary
expectedLoadRefcount refcount
expectedCloseRefcount refcount
}{
{
description: "regular flow",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
CloseFunc: func() error {
return nil
},
},
expectedLoadRefcount: 1,
expectedCloseRefcount: 0,
},
{
description: "open error",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return errors.New("")
},
CloseFunc: func() error {
return nil
},
},
expectedLoadRefcount: 0,
expectedCloseRefcount: 0,
},
{
description: "close error",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return nil
},
CloseFunc: func() error {
return errors.New("")
},
},
expectedLoadRefcount: 1,
expectedCloseRefcount: 1,
},
{
description: "open and close error",
dl: &dynamicLibraryMock{
OpenFunc: func() error {
return errors.New("")
},
CloseFunc: func() error {
return errors.New("")
},
},
expectedLoadRefcount: 0,
expectedCloseRefcount: 0,
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
l := newTestLibrary(tc.dl)
_ = l.load()
require.Equal(t, tc.expectedLoadRefcount, l.refcount)
_ = l.close()
require.Equal(t, tc.expectedCloseRefcount, l.refcount)
})
}
}