@@ -29,6 +29,8 @@ import (
2929// Integration tests for Docker runtime
3030var _ = Describe ("docker" , Ordered , ContinueOnFailure , func () {
3131 var runner Runner
32+ var hostDriverVersion string
33+ var hostDriverMajor string
3234
3335 // Install the NVIDIA Container Toolkit
3436 BeforeAll (func (ctx context.Context ) {
@@ -50,6 +52,15 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
5052 err = installer .Install ()
5153 Expect (err ).ToNot (HaveOccurred ())
5254 }
55+
56+ driverOutput , _ , err := runner .Run ("nvidia-smi -q | grep \" Driver Version\" " )
57+ Expect (err ).ToNot (HaveOccurred ())
58+ parts := strings .SplitN (driverOutput , ":" , 2 )
59+ Expect (parts ).To (HaveLen (2 ))
60+
61+ hostDriverVersion = strings .TrimSpace (parts [1 ])
62+ Expect (hostDriverVersion ).ToNot (BeEmpty ())
63+ hostDriverMajor = strings .SplitN (hostDriverVersion , "." , 2 )[0 ]
5364 })
5465
5566 // GPUs are accessible in a container: Running nvidia-smi -L inside the
@@ -184,16 +195,7 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
184195 compatDriverVersion := strings .TrimPrefix (filepath .Base (compatOutput ), "libcuda.so." )
185196 compatMajor := strings .SplitN (compatDriverVersion , "." , 2 )[0 ]
186197
187- driverOutput , _ , err := runner .Run ("nvidia-smi -q | grep \" Driver Version\" " )
188- Expect (err ).ToNot (HaveOccurred ())
189- parts := strings .SplitN (driverOutput , ":" , 2 )
190- Expect (parts ).To (HaveLen (2 ))
191-
192- hostDriverVersion := strings .TrimSpace (parts [1 ])
193- Expect (hostDriverVersion ).ToNot (BeEmpty ())
194- driverMajor := strings .SplitN (hostDriverVersion , "." , 2 )[0 ]
195-
196- if driverMajor >= compatMajor {
198+ if hostDriverMajor >= compatMajor {
197199 GinkgoLogr .Info ("CUDA Forward Compatibility tests require an older driver version" , "hostDriverVersion" , hostDriverVersion , "compatDriverVersion" , compatDriverVersion )
198200 Skip ("CUDA Forward Compatibility tests require an older driver version" )
199201 }
@@ -241,6 +243,8 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
241243 BeforeAll (func (ctx context.Context ) {
242244 _ , _ , err := runner .Run ("docker pull ubuntu" )
243245 Expect (err ).ToNot (HaveOccurred ())
246+ _ , _ , err = runner .Run ("docker pull busybox" )
247+ Expect (err ).ToNot (HaveOccurred ())
244248 })
245249
246250 It ("should include libcuda.so in the ldcache" , func (ctx context.Context ) {
@@ -257,6 +261,91 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
257261
258262 Expect (libs ).To (ContainElements ([]string {"libcuda.so" , "libcuda.so.1" }))
259263 })
264+
265+ It ("should include .so and SONAME symlinks" , func (ctx context.Context ) {
266+ symlinkOutput , _ , err := runner .Run ("docker run --rm -i --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=runtime.nvidia.com/gpu=all busybox ls -l /usr/lib/x86_64-linux-gnu/ | awk '{print $1, $9, $11}'" )
267+ Expect (err ).ToNot (HaveOccurred ())
268+ Expect (symlinkOutput ).ToNot (BeEmpty ())
269+
270+ // This produces output similar to:
271+ // We check this to ensure that we have valid driver library symlink
272+ // chains.
273+ // lrwxrwxrwx libcuda.so libcuda.so.1
274+ // lrwxrwxrwx libcuda.so.1 libcuda.so.570.133.20
275+ // -rw-r--r-- libcuda.so.570.133.20
276+ // lrwxrwxrwx libcudadebugger.so libcudadebugger.so.1
277+ // lrwxrwxrwx libcudadebugger.so.1 libcudadebugger.so.570.133.20
278+ // -rw-r--r-- libcudadebugger.so.570.133.20
279+ // lrwxrwxrwx libnvidia-ml.so libnvidia-ml.so.1
280+ // lrwxrwxrwx libnvidia-ml.so.1 libnvidia-ml.so.570.133.20
281+ // -rw-r--r-- libnvidia-ml.so.570.133.20
282+ // lrwxrwxrwx libnvidia-nvvm.so libnvidia-nvvm.so.4
283+ // lrwxrwxrwx libnvidia-nvvm.so.4 libnvidia-nvvm.so.570.133.20
284+ // -rw-r--r-- libnvidia-nvvm.so.570.133.20
285+ // lrwxrwxrwx libnvidia-opencl.so libnvidia-opencl.so.1
286+ // lrwxrwxrwx libnvidia-opencl.so.1 libnvidia-opencl.so.570.133.20
287+ // -rw-r--r-- libnvidia-opencl.so.570.133.20
288+ // -rw-r--r-- libnvidia-pkcs11-openssl3.so.570.133.20
289+ // -rw-r--r-- libnvidia-pkcs11.so.570.133.20
290+ // lrwxrwxrwx libnvidia-ptxjitcompiler.so libnvidia-ptxjitcompiler.so.1
291+ // lrwxrwxrwx libnvidia-ptxjitcompiler.so.1 libnvidia-ptxjitcompiler.so.570.133.20
292+ // -rw-r--r-- libnvidia-ptxjitcompiler.so.570.133.20
293+
294+ symlinkOutputLines := strings .Split (symlinkOutput , "\n " )
295+ symlinks := make (map [string ][]string )
296+ var soSymlink string
297+ for _ , line := range symlinkOutputLines {
298+ trimmed := strings .TrimSpace (line )
299+ if trimmed == "" {
300+ soSymlink = ""
301+ continue
302+ }
303+ // We only consider links and regular files.
304+ if trimmed [0 ] != 'l' && trimmed [0 ] != '-' {
305+ soSymlink = ""
306+ continue
307+ }
308+ fmt .Printf ("trimmed = %q\n " , trimmed )
309+ parts := strings .SplitN (trimmed , " " , 3 )
310+ permissionString := parts [0 ]
311+
312+ // If the line represents a symlink we may have to handle a new symlink chain.
313+ if strings .HasPrefix (permissionString , "l" ) && soSymlink == "" {
314+ if strings .HasSuffix (parts [1 ], ".so" ) {
315+ soSymlink = parts [1 ]
316+ }
317+ }
318+
319+ // Keep track of the symlink chain.
320+ symlinks [soSymlink ] = append (symlinks [soSymlink ], parts [1 :]... )
321+
322+ // We assume a regular file is the end of a symlink chain.
323+ if strings .HasPrefix (permissionString , "-" ) {
324+ soSymlink = ""
325+ }
326+
327+ }
328+
329+ // The symlink chains have the pattern:
330+ // [A.so, A.so.1, A.so.1, A.so.driverVersion, A.so.driverVersion]
331+ // A has the suffix .so.
332+ Expect (symlinks ).ToNot (BeEmpty ())
333+ for soSymlink , chain := range symlinks {
334+ if soSymlink == "" {
335+ continue
336+ }
337+ Expect (chain ).To (HaveLen (5 ))
338+ for _ , c := range chain {
339+ Expect (c ).To (HavePrefix (soSymlink ))
340+ }
341+ Expect (chain [0 ]).To (HaveSuffix (".so" ))
342+ Expect (chain [1 ]).To (Equal (chain [2 ]))
343+ Expect (chain [3 ]).To (Equal (chain [4 ]))
344+ Expect (chain [3 ]).To (HaveSuffix (hostDriverVersion ))
345+ Expect (chain [4 ]).To (HaveSuffix (hostDriverVersion ))
346+ }
347+ Expect (symlinks ).To (And (HaveKey ("libcuda.so" ), HaveKey ("libnvidia-ml.so" )))
348+ })
260349 })
261350
262351 When ("Running containers with shared mount propagation" , Ordered , func () {
0 commit comments