Skip to content

Commit 23f1ba3

Browse files
committed
Add unit tests for create-symlinks hook
Signed-off-by: Christopher Desiniotis <cdesiniotis@nvidia.com> Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent d0d85a8 commit 23f1ba3

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

cmd/nvidia-cdi-hook/create-symlinks/create-symlinks.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ func (m command) run(c *cli.Context, cfg *config) error {
107107
return nil
108108
}
109109

110+
// createLink creates a symbolic link in the specified container root.
111+
// This is equivalent to:
112+
//
113+
// chroot {{ .containerRoot }} ln -s {{ .target }} {{ .link }}
114+
//
115+
// If the specified link already exists and points to the same target, this
116+
// operation is a no-op. If the link points to a different target, an error is
117+
// returned.
118+
//
119+
// Note that if the link path resolves to an absolute path oudside of the
120+
// specified root, this is treated as an absolute path in this root.
110121
func (m command) createLink(containerRoot string, targetPath string, link string) error {
111122
linkPath := filepath.Join(containerRoot, link)
112123

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package symlinks
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
testlog "github.com/sirupsen/logrus/hooks/test"
9+
10+
"github.com/stretchr/testify/require"
11+
12+
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks"
13+
)
14+
15+
func TestCreateLinkRelativePath(t *testing.T) {
16+
tmpDir := t.TempDir()
17+
hostRoot := filepath.Join(tmpDir, "/host-root/")
18+
containerRoot := filepath.Join(tmpDir, "/container-root")
19+
20+
require.NoError(t, makeFs(hostRoot))
21+
require.NoError(t, makeFs(containerRoot, dirOrLink{path: "/lib/"}))
22+
23+
// nvidia-cdi-hook create-symlinks --link libfoo.so.1::/lib/libfoo.so
24+
err := getTestCommand().createLink(containerRoot, "libfoo.so.1", "/lib/libfoo.so")
25+
require.NoError(t, err)
26+
27+
target, err := symlinks.Resolve(filepath.Join(containerRoot, "/lib/libfoo.so"))
28+
require.NoError(t, err)
29+
require.Equal(t, "libfoo.so.1", target)
30+
}
31+
32+
func TestCreateLinkAbsolutePath(t *testing.T) {
33+
tmpDir := t.TempDir()
34+
hostRoot := filepath.Join(tmpDir, "/host-root/")
35+
containerRoot := filepath.Join(tmpDir, "/container-root")
36+
37+
require.NoError(t, makeFs(hostRoot))
38+
require.NoError(t, makeFs(containerRoot, dirOrLink{path: "/lib/"}))
39+
40+
// nvidia-cdi-hook create-symlinks --link /lib/libfoo.so.1::/lib/libfoo.so
41+
err := getTestCommand().createLink(containerRoot, "/lib/libfoo.so.1", "/lib/libfoo.so")
42+
require.NoError(t, err)
43+
44+
target, err := symlinks.Resolve(filepath.Join(containerRoot, "/lib/libfoo.so"))
45+
require.NoError(t, err)
46+
require.Equal(t, "/lib/libfoo.so.1", target)
47+
}
48+
49+
func TestCreateLinkAlreadyExists(t *testing.T) {
50+
tmpDir := t.TempDir()
51+
hostRoot := filepath.Join(tmpDir, "/host-root/")
52+
containerRoot := filepath.Join(tmpDir, "/container-root")
53+
54+
require.NoError(t, makeFs(hostRoot))
55+
require.NoError(t, makeFs(containerRoot, dirOrLink{path: "/lib/libfoo.so", target: "libfoo.so.1"}))
56+
57+
// nvidia-cdi-hook create-symlinks --link libfoo.so.1::/lib/libfoo.so
58+
err := getTestCommand().createLink(containerRoot, "libfoo.so.1", "/lib/libfoo.so")
59+
require.Error(t, err)
60+
target, err := symlinks.Resolve(filepath.Join(containerRoot, "lib/libfoo.so"))
61+
require.NoError(t, err)
62+
require.Equal(t, "libfoo.so.1", target)
63+
}
64+
65+
type dirOrLink struct {
66+
path string
67+
target string
68+
}
69+
70+
func makeFs(tmpdir string, fs ...dirOrLink) error {
71+
if err := os.MkdirAll(tmpdir, 0o755); err != nil {
72+
return err
73+
}
74+
for _, s := range fs {
75+
s.path = filepath.Join(tmpdir, s.path)
76+
if s.target == "" {
77+
_ = os.MkdirAll(s.path, 0o755)
78+
continue
79+
}
80+
if err := os.MkdirAll(filepath.Dir(s.path), 0o755); err != nil {
81+
return err
82+
}
83+
if err := os.Symlink(s.target, s.path); err != nil && !os.IsExist(err) {
84+
return err
85+
}
86+
}
87+
return nil
88+
}
89+
90+
// getTestCommand creates a command for running tests against.
91+
func getTestCommand() *command {
92+
logger, _ := testlog.NewNullLogger()
93+
return &command{
94+
logger: logger,
95+
}
96+
}

0 commit comments

Comments
 (0)