devices_windows_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package container // import "github.com/docker/docker/integration/container"
  2. import (
  3. "strings"
  4. "testing"
  5. containertypes "github.com/docker/docker/api/types/container"
  6. "github.com/docker/docker/integration/internal/container"
  7. "github.com/docker/docker/testutil"
  8. "gotest.tools/v3/assert"
  9. "gotest.tools/v3/skip"
  10. )
  11. // TestWindowsDevices that Windows Devices are correctly propagated
  12. // via HostConfig.Devices through to the implementation in hcsshim.
  13. func TestWindowsDevices(t *testing.T) {
  14. skip.If(t, testEnv.DaemonInfo.OSType != "windows")
  15. ctx := setupTest(t)
  16. apiClient := testEnv.APIClient()
  17. testData := []struct {
  18. doc string
  19. devices []string
  20. isolation containertypes.Isolation
  21. expectedStartFailure bool
  22. expectedStartFailureMessage string
  23. expectedExitCode int
  24. expectedStdout string
  25. expectedStderr string
  26. }{
  27. {
  28. doc: "process/no device mounted",
  29. isolation: containertypes.IsolationProcess,
  30. expectedExitCode: 1,
  31. },
  32. {
  33. doc: "process/class/5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
  34. devices: []string{"class/5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
  35. isolation: containertypes.IsolationProcess,
  36. expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
  37. },
  38. {
  39. doc: "process/class://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
  40. devices: []string{"class://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
  41. isolation: containertypes.IsolationProcess,
  42. expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
  43. },
  44. {
  45. doc: "process/vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
  46. devices: []string{"vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
  47. isolation: containertypes.IsolationProcess,
  48. expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
  49. },
  50. {
  51. doc: "hyperv/no device mounted",
  52. isolation: containertypes.IsolationHyperV,
  53. expectedExitCode: 1,
  54. },
  55. {
  56. doc: "hyperv/class/5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
  57. devices: []string{"class/5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
  58. isolation: containertypes.IsolationHyperV,
  59. expectedStartFailure: !testEnv.RuntimeIsWindowsContainerd(),
  60. expectedStartFailureMessage: "device assignment is not supported for HyperV containers",
  61. expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
  62. },
  63. {
  64. doc: "hyperv/class://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
  65. devices: []string{"class://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
  66. isolation: containertypes.IsolationHyperV,
  67. expectedStartFailure: !testEnv.RuntimeIsWindowsContainerd(),
  68. expectedStartFailureMessage: "device assignment is not supported for HyperV containers",
  69. expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
  70. },
  71. {
  72. doc: "hyperv/vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
  73. devices: []string{"vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
  74. isolation: containertypes.IsolationHyperV,
  75. expectedStartFailure: !testEnv.RuntimeIsWindowsContainerd(),
  76. expectedStartFailureMessage: "device assignment is not supported for HyperV containers",
  77. expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
  78. },
  79. }
  80. for _, d := range testData {
  81. d := d
  82. t.Run(d.doc, func(t *testing.T) {
  83. t.Parallel()
  84. ctx := testutil.StartSpan(ctx, t)
  85. deviceOptions := []func(*container.TestContainerConfig){container.WithIsolation(d.isolation)}
  86. for _, deviceName := range d.devices {
  87. deviceOptions = append(deviceOptions, container.WithWindowsDevice(deviceName))
  88. }
  89. id := container.Create(ctx, t, apiClient, deviceOptions...)
  90. // Hyper-V isolation is failing even with no actual devices added.
  91. // TODO: Once https://github.com/moby/moby/issues/43395 is resolved,
  92. // remove this skip.If and validate the expected behaviour under Hyper-V.
  93. skip.If(t, d.isolation == containertypes.IsolationHyperV && !d.expectedStartFailure, "FIXME. HyperV isolation setup is probably incorrect in the test")
  94. err := apiClient.ContainerStart(ctx, id, containertypes.StartOptions{})
  95. if d.expectedStartFailure {
  96. assert.ErrorContains(t, err, d.expectedStartFailureMessage)
  97. return
  98. }
  99. assert.NilError(t, err)
  100. // /Windows/System32/HostDriverStore is mounted from the host when class GUID 5B45201D-F2F2-4F3B-85BB-30FF1F953599
  101. // is mounted. See `C:\windows\System32\containers\devices.def` on a Windows host for (slightly more) details.
  102. res, err := container.Exec(ctx, apiClient, id, []string{
  103. "sh", "-c",
  104. "ls -d /Windows/System32/HostDriverStore/* | grep /Windows/System32/HostDriverStore/FileRepository",
  105. })
  106. assert.NilError(t, err)
  107. assert.Equal(t, d.expectedExitCode, res.ExitCode)
  108. if d.expectedExitCode == 0 {
  109. assert.Equal(t, d.expectedStdout, strings.TrimSpace(res.Stdout()))
  110. assert.Equal(t, d.expectedStderr, strings.TrimSpace(res.Stderr()))
  111. }
  112. })
  113. }
  114. }