@@ -24,11 +24,14 @@ import (
2424
2525 . "github.com/onsi/ginkgo/v2"
2626 . "github.com/onsi/gomega"
27+ . "github.com/onsi/gomega/gcustom"
2728)
2829
2930// Integration tests for Docker runtime
3031var _ = Describe ("docker" , Ordered , ContinueOnFailure , func () {
3132 var runner Runner
33+ var hostDriverVersion string
34+ var hostDriverMajor string
3235
3336 // Install the NVIDIA Container Toolkit
3437 BeforeAll (func (ctx context.Context ) {
@@ -50,6 +53,15 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
5053 err = installer .Install ()
5154 Expect (err ).ToNot (HaveOccurred ())
5255 }
56+
57+ driverOutput , _ , err := runner .Run ("nvidia-smi -q | grep \" Driver Version\" " )
58+ Expect (err ).ToNot (HaveOccurred ())
59+ parts := strings .SplitN (driverOutput , ":" , 2 )
60+ Expect (parts ).To (HaveLen (2 ))
61+
62+ hostDriverVersion = strings .TrimSpace (parts [1 ])
63+ Expect (hostDriverVersion ).ToNot (BeEmpty ())
64+ hostDriverMajor = strings .SplitN (hostDriverVersion , "." , 2 )[0 ]
5365 })
5466
5567 // GPUs are accessible in a container: Running nvidia-smi -L inside the
@@ -184,16 +196,7 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
184196 compatDriverVersion := strings .TrimPrefix (filepath .Base (compatOutput ), "libcuda.so." )
185197 compatMajor := strings .SplitN (compatDriverVersion , "." , 2 )[0 ]
186198
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 {
199+ if hostDriverMajor >= compatMajor {
197200 GinkgoLogr .Info ("CUDA Forward Compatibility tests require an older driver version" , "hostDriverVersion" , hostDriverVersion , "compatDriverVersion" , compatDriverVersion )
198201 Skip ("CUDA Forward Compatibility tests require an older driver version" )
199202 }
@@ -241,6 +244,8 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
241244 BeforeAll (func (ctx context.Context ) {
242245 _ , _ , err := runner .Run ("docker pull ubuntu" )
243246 Expect (err ).ToNot (HaveOccurred ())
247+ _ , _ , err = runner .Run ("docker pull busybox" )
248+ Expect (err ).ToNot (HaveOccurred ())
244249 })
245250
246251 It ("should include libcuda.so in the ldcache" , func (ctx context.Context ) {
@@ -257,6 +262,77 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
257262
258263 Expect (libs ).To (ContainElements ([]string {"libcuda.so" , "libcuda.so.1" }))
259264 })
265+
266+ It ("should include .so and SONAME symlinks" , func (ctx context.Context ) {
267+ symlinkOutput , _ , err := runner .Run ("docker run --rm -ti --runtime=nvidia --gpus all busybox ls -l /usr/lib/x86_64-linux-gnu/ | awk '{print $9, $11}'" )
268+ Expect (err ).ToNot (HaveOccurred ())
269+ Expect (symlinkOutput ).ToNot (BeEmpty ())
270+
271+ // This produces output similar to:
272+ // We check this to ensure that we have valid driver library symlink
273+ // chains.
274+ // libcuda.so libcuda.so.1
275+ // libcuda.so.1 libcuda.so.570.133.20
276+ // libcuda.so.570.133.20
277+ // libcudadebugger.so libcudadebugger.so.1
278+ // libcudadebugger.so.1 libcudadebugger.so.570.133.20
279+ // libcudadebugger.so.570.133.20
280+ // libnvidia-ml.so libnvidia-ml.so.1
281+ // libnvidia-ml.so.1 libnvidia-ml.so.570.133.20
282+ // libnvidia-ml.so.570.133.20
283+ // libnvidia-nvvm.so libnvidia-nvvm.so.4
284+ // libnvidia-nvvm.so.4 libnvidia-nvvm.so.570.133.20
285+ // libnvidia-nvvm.so.570.133.20
286+ // libnvidia-opencl.so libnvidia-opencl.so.1
287+ // libnvidia-opencl.so.1 libnvidia-opencl.so.570.133.20
288+ // libnvidia-opencl.so.570.133.20
289+ // libnvidia-pkcs11-openssl3.so.570.133.20
290+ // libnvidia-pkcs11.so.570.133.20
291+ // libnvidia-ptxjitcompiler.so libnvidia-ptxjitcompiler.so.1
292+ // libnvidia-ptxjitcompiler.so.1 libnvidia-ptxjitcompiler.so.570.133.20
293+ // libnvidia-ptxjitcompiler.so.570.133.20
294+
295+ symlinkOutputLines := strings .Split (symlinkOutput , "\n " )
296+ var symlinks []string
297+ var chain []string
298+ for _ , line := range symlinkOutputLines {
299+ if strings .TrimSpace (line ) == "" {
300+ continue
301+ }
302+ parts := strings .SplitN (line , " " , 2 )
303+ chain = append (chain , parts ... )
304+ if len (parts ) == 1 {
305+ Expect (line ).To (HaveSuffix (hostDriverMajor ))
306+ Expect (chain ).To (Or (HaveLen (5 ), HaveLen (1 )))
307+
308+ if len (chain ) == 1 {
309+ continue
310+ }
311+
312+ // The symlink chains have the pattern:
313+ // [A, A.1, A.1, A.driverVersion, A.driverVersion]
314+ // A has the suffix .so.
315+ Expect (chain [0 ]).To (HaveSuffix (".so" ))
316+ for i , c := range chain {
317+ if i == 0 {
318+ continue
319+ }
320+ Expect (c ).To (HavePrefix (chain [0 ]))
321+ if i == 2 || i == 4 {
322+ Expect (c ).To (Equal (chain [i - 1 ]))
323+ }
324+ if i == 3 {
325+ Expect (c ).To (HaveSuffix (hostDriverVersion ))
326+ }
327+ }
328+
329+ symlinks = append (symlinks , chain [0 ])
330+ chain = nil
331+ }
332+ }
333+ Expect (chain ).To (BeNil ())
334+ Expect (symlinks ).To (ContainElements ("libcuda.so" , "libnvidia-ml.so" ))
335+ })
260336 })
261337
262338 When ("Running containers with shared mount propagation" , Ordered , func () {
0 commit comments