@@ -3,18 +3,17 @@ package symlinks
33import (
44 "os"
55 "path/filepath"
6+ "strings"
67 "testing"
78
89 testlog "github.com/sirupsen/logrus/hooks/test"
9-
1010 "github.com/stretchr/testify/require"
1111
1212 "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks"
1313)
1414
1515func TestDoesLinkExist (t * testing.T ) {
1616 tmpDir := t .TempDir ()
17-
1817 require .NoError (
1918 t ,
2019 makeFs (tmpDir ,
@@ -42,6 +41,120 @@ func TestDoesLinkExist(t *testing.T) {
4241 require .False (t , exists )
4342}
4443
44+ func TestCreateLink (t * testing.T ) {
45+ type link struct {
46+ path string
47+ target string
48+ }
49+ type expectedLink struct {
50+ link
51+ err error
52+ }
53+
54+ testCases := []struct {
55+ description string
56+ containerContents []dirOrLink
57+ link link
58+ expectedCreateError error
59+ expectedLinks []expectedLink
60+ }{
61+ {
62+ description : "link to / resolves to container root" ,
63+ containerContents : []dirOrLink {
64+ {path : "/lib/foo" , target : "/" },
65+ },
66+ link : link {
67+ path : "/lib/foo/libfoo.so" ,
68+ target : "libfoo.so.1" ,
69+ },
70+ expectedLinks : []expectedLink {
71+ {
72+ link : link {
73+ path : "{{ .containerRoot }}/libfoo.so" ,
74+ target : "libfoo.so.1" ,
75+ },
76+ },
77+ },
78+ },
79+ {
80+ description : "link to / resolves to container root; parent relative link" ,
81+ containerContents : []dirOrLink {
82+ {path : "/lib/foo" , target : "/" },
83+ },
84+ link : link {
85+ path : "/lib/foo/libfoo.so" ,
86+ target : "../libfoo.so.1" ,
87+ },
88+ expectedLinks : []expectedLink {
89+ {
90+ link : link {
91+ path : "{{ .containerRoot }}/libfoo.so" ,
92+ target : "../libfoo.so.1" ,
93+ },
94+ },
95+ },
96+ },
97+ {
98+ description : "link to / resolves to container root; absolute link" ,
99+ containerContents : []dirOrLink {
100+ {path : "/lib/foo" , target : "/" },
101+ },
102+ link : link {
103+ path : "/lib/foo/libfoo.so" ,
104+ target : "/a-path-in-container/foo/libfoo.so.1" ,
105+ },
106+ expectedLinks : []expectedLink {
107+ {
108+ link : link {
109+ path : "{{ .containerRoot }}/libfoo.so" ,
110+ target : "/a-path-in-container/foo/libfoo.so.1" ,
111+ },
112+ },
113+ {
114+ // We also check that the target is NOT created.
115+ link : link {
116+ path : "{{ .containerRoot }}/a-path-in-container/foo/libfoo.so.1" ,
117+ },
118+ err : os .ErrNotExist ,
119+ },
120+ },
121+ },
122+ }
123+
124+ for _ , tc := range testCases {
125+ t .Run (tc .description , func (t * testing.T ) {
126+ tmpDir := t .TempDir ()
127+ hostRoot := filepath .Join (tmpDir , "/host-root/" )
128+ containerRoot := filepath .Join (tmpDir , "/container-root" )
129+
130+ require .NoError (t , makeFs (hostRoot ))
131+ require .NoError (t , makeFs (containerRoot , tc .containerContents ... ))
132+
133+ // nvidia-cdi-hook create-symlinks --link linkSpec
134+ err := getTestCommand ().createLink (containerRoot , tc .link .target , tc .link .path )
135+ // TODO: We may be able to replace this with require.ErrorIs.
136+ if tc .expectedCreateError != nil {
137+ require .Error (t , err )
138+ } else {
139+ require .NoError (t , err )
140+ }
141+
142+ for _ , expectedLink := range tc .expectedLinks {
143+ path := strings .Replace (expectedLink .path , "{{ .containerRoot }}" , containerRoot , - 1 )
144+ path = strings .Replace (path , "{{ .hostRoot }}" , hostRoot , - 1 )
145+ if expectedLink .target != "" {
146+ target , err := symlinks .Resolve (path )
147+ require .ErrorIs (t , err , expectedLink .err )
148+ require .Equal (t , expectedLink .target , target )
149+ } else {
150+ _ , err := os .Stat (path )
151+ require .ErrorIs (t , err , expectedLink .err )
152+ }
153+ }
154+ })
155+ }
156+ }
157+
45158func TestCreateLinkRelativePath (t * testing.T ) {
46159 tmpDir := t .TempDir ()
47160 hostRoot := filepath .Join (tmpDir , "/host-root/" )
@@ -131,6 +244,8 @@ func TestCreateLinkOutOfBounds(t *testing.T) {
131244 // require.Error(t, err)
132245 _ , err = os .Lstat (filepath .Join (hostRoot , "libfoo.so" ))
133246 require .ErrorIs (t , err , os .ErrNotExist )
247+ _ , err = os .Lstat (filepath .Join (containerRoot , hostRoot , "libfoo.so" ))
248+ require .NoError (t , err )
134249}
135250
136251type dirOrLink struct {
0 commit comments