Browse code

Enabling Windows integration tests

Signed-off-by: Salahuddin Khan <salah@docker.com>

Salahuddin Khan authored on 2018/08/03 05:24:51
Showing 18 changed files
... ...
@@ -1,9 +1,19 @@
1
+# WARNING WARNING WARNING - DO NOT EDIT THIS FILE IN JENKINS DIRECTLY.
2
+# SUBMIT A PR TO https://github.com/jhowardmsft/docker-w2wCIScripts/blob/master/runCI/executeCI.ps1,
3
+# AND MAKE SURE https://github.com/jhowardmsft/docker-w2wCIScripts/blob/master/runCI/Invoke-DockerCI.ps1
4
+# ISN'T BROKEN!!!!!!! VALIDATE USING A TEST CONTEXT IN JENKINS. THEN COPY/PASTE INTO JENKINS PRODUCTION.
5
+#
1 6
 # Jenkins CI scripts for Windows to Windows CI (Powershell Version)
2 7
 # By John Howard (@jhowardmsft) January 2016 - bash version; July 2016 Ported to PowerShell
3 8
 
4 9
 $ErrorActionPreference = 'Stop'
5 10
 $StartTime=Get-Date
6
-#$env:DOCKER_DUT_DEBUG="yes" # Comment out to not be in debug mode
11
+
12
+# Put up top to be blindingly obvious. The production jenkins.dockerproject.org Linux-container 
13
+# CI job is "Docker-PRs-LoW-RS3". Force into LCOW mode for this run, or not.
14
+if ($env:BUILD_TAG -match "-LoW") { $env:LCOW_MODE=1 }
15
+if ($env:BUILD_TAG -match "-WoW") { $env:LCOW_MODE="" }
16
+
7 17
 
8 18
 # -------------------------------------------------------------------------------------------
9 19
 # When executed, we rely on four variables being set in the environment:
... ...
@@ -17,7 +27,7 @@ $StartTime=Get-Date
17 17
 #
18 18
 #    SOURCES_SUBDIR      is the top level directory under SOURCES_DRIVE where the
19 19
 #                        sources are cloned to. There are no platform semantics in this
20
-#                        as it does not include slashes.
20
+#                        as it does not include slashes. 
21 21
 #                        For example 'gopath'
22 22
 #
23 23
 #                        Based on the above examples, it would be expected that Jenkins
... ...
@@ -60,13 +70,19 @@ $StartTime=Get-Date
60 60
 #    SKIP_IMAGE_BUILD         if defined doesn't build the 'docker' image
61 61
 #
62 62
 #    INTEGRATION_IN_CONTAINER if defined, runs the integration tests from inside a container.
63
-#                             As of July 2016, there are known issues with this.
63
+#                             As of July 2016, there are known issues with this. 
64 64
 #
65 65
 #    SKIP_ALL_CLEANUP         if defined, skips any cleanup at the start or end of the run
66 66
 #
67 67
 #    WINDOWS_BASE_IMAGE       if defined, uses that as the base image. Note that the
68 68
 #                             docker integration tests are also coded to use the same
69 69
 #                             environment variable, and if no set, defaults to microsoft/windowsservercore
70
+#
71
+#    LCOW_BASIC_MODE          if defined, does very basic LCOW verification. Ultimately we 
72
+#                             want to run the entire CI suite from docker, but that's a way off.
73
+#                            
74
+#    LCOW_MODE                if defined, runs the entire CI suite
75
+#                            
70 76
 # -------------------------------------------------------------------------------------------
71 77
 #
72 78
 # Jenkins Integration. Add a Windows Powershell build step as follows:
... ...
@@ -80,7 +96,7 @@ $StartTime=Get-Date
80 80
 #    try {
81 81
 #        Write-Host -ForegroundColor green "INFO: Downloading latest execution script..."
82 82
 #        $wc.Downloadfile($CISCRIPT_DEFAULT_LOCATION, $CISCRIPT_LOCAL_LOCATION)
83
-#    }
83
+#    } 
84 84
 #    catch [System.Net.WebException]
85 85
 #    {
86 86
 #        Throw ("Failed to download: $_")
... ...
@@ -88,9 +104,11 @@ $StartTime=Get-Date
88 88
 #    & $CISCRIPT_LOCAL_LOCATION
89 89
 # -------------------------------------------------------------------------------------------
90 90
 
91
-$SCRIPT_VER="10-May-2017 12:16 PDT"
91
+
92
+$SCRIPT_VER="28-Aug-2018 09:33 PDT" 
92 93
 $FinallyColour="Cyan"
93 94
 
95
+#$env:DOCKER_DUT_DEBUG="yes" # Comment out to not be in debug mode
94 96
 #$env:SKIP_UNIT_TESTS="yes"
95 97
 #$env:SKIP_VALIDATION_TESTS="yes"
96 98
 #$env:SKIP_ZAP_DUT=""
... ...
@@ -104,34 +122,35 @@ $FinallyColour="Cyan"
104 104
 
105 105
 Function Nuke-Everything {
106 106
     $ErrorActionPreference = 'SilentlyContinue'
107
-    if ($env:SKIP_ALL_CLEANUP -ne $null) {
108
-        Write-Host -ForegroundColor Magenta "WARN: Skipping all cleanup"
109
-        return
110
-    }
111 107
 
112 108
     try {
113
-        Write-Host -ForegroundColor green "INFO: Nuke-Everything..."
114
-        $containerCount = ($(docker ps -aq | Measure-Object -line).Lines)
115
-        if (-not $LastExitCode -eq 0) {
116
-            Throw "ERROR: Failed to get container count from control daemon while nuking"
117
-        }
118 109
 
119
-        Write-Host -ForegroundColor green "INFO: Container count on control daemon to delete is $containerCount"
120
-        if ($(docker ps -aq | Measure-Object -line).Lines -gt 0) {
121
-            docker rm -f $(docker ps -aq)
122
-        }
123
-        $imageCount=($(docker images --format "{{.Repository}}:{{.ID}}" | `
124
-                        select-string -NotMatch "windowsservercore" | `
125
-                        select-string -NotMatch "nanoserver" | `
126
-                        select-string -NotMatch "docker" | `
127
-                        Measure-Object -line).Lines)
128
-        if ($imageCount -gt 0) {
129
-            Write-Host -Foregroundcolor green "INFO: Non-base image count on control daemon to delete is $imageCount"
130
-            docker rmi -f `
131
-                $(docker images --format "{{.Repository}}:{{.ID}}" | `
132
-                        select-string -NotMatch "windowsservercore" | `
133
-                        select-string -NotMatch "nanoserver" | `
134
-                        select-string -NotMatch "docker").ToString().Split(":")[1]
110
+        if ($env:SKIP_ALL_CLEANUP -eq $null) {
111
+            Write-Host -ForegroundColor green "INFO: Nuke-Everything..."
112
+            $containerCount = ($(docker ps -aq | Measure-Object -line).Lines) 
113
+            if (-not $LastExitCode -eq 0) {
114
+                Throw "ERROR: Failed to get container count from control daemon while nuking"
115
+            }
116
+
117
+            Write-Host -ForegroundColor green "INFO: Container count on control daemon to delete is $containerCount"
118
+            if ($(docker ps -aq | Measure-Object -line).Lines -gt 0) {
119
+                docker rm -f $(docker ps -aq)
120
+            }
121
+            $imageCount=($(docker images --format "{{.Repository}}:{{.ID}}" | `
122
+                            select-string -NotMatch "windowsservercore" | `
123
+                            select-string -NotMatch "nanoserver" | `
124
+                            select-string -NotMatch "docker" | `
125
+                            Measure-Object -line).Lines)
126
+            if ($imageCount -gt 0) {
127
+                Write-Host -Foregroundcolor green "INFO: Non-base image count on control daemon to delete is $imageCount"
128
+                docker rmi -f `
129
+                    $(docker images --format "{{.Repository}}:{{.ID}}" | `
130
+                            select-string -NotMatch "windowsservercore" | `
131
+                            select-string -NotMatch "nanoserver" | `
132
+                            select-string -NotMatch "docker").ToString().Split(":")[1]
133
+            }
134
+        } else {
135
+            Write-Host -ForegroundColor Magenta "WARN: Skipping cleanup of images and containers"
135 136
         }
136 137
 
137 138
         # Kill any spurious daemons. The '-' is IMPORTANT otherwise will kill the control daemon!
... ...
@@ -141,6 +160,18 @@ Function Nuke-Everything {
141 141
             Stop-Process -Id $p -Force -ErrorAction SilentlyContinue
142 142
         }
143 143
 
144
+        if ($pidFile -ne $Null) {
145
+            Write-Host "INFO: Tidying pidfile $pidfile"
146
+             if (Test-Path $pidFile) {
147
+                $p=Get-Content $pidFile -raw
148
+                if ($p -ne $null){
149
+                    Write-Host -ForegroundColor green "INFO: Stopping possible daemon pid $p"
150
+                    taskkill -f -t -pid $p
151
+                }
152
+                Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue
153
+            }
154
+        }
155
+
144 156
         Stop-Process -name "cc1" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
145 157
         Stop-Process -name "link" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
146 158
         Stop-Process -name "compile" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
... ...
@@ -159,7 +190,7 @@ Function Nuke-Everything {
159 159
 
160 160
         # Delete the directory using our dangerous utility unless told not to
161 161
         if (Test-Path "$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR") {
162
-            if ($env:SKIP_ZAP_DUT -eq $null) {
162
+            if (($env:SKIP_ZAP_DUT -ne $null) -or ($env:SKIP_ALL_CLEANUP -eq $null)) {
163 163
                 Write-Host -ForegroundColor Green "INFO: Nuking $env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR"
164 164
                 docker-ci-zap "-folder=$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR"
165 165
             } else {
... ...
@@ -167,7 +198,7 @@ Function Nuke-Everything {
167 167
             }
168 168
         }
169 169
 
170
-        # RS1 Production Server workaround - Psched
170
+        # TODO: This should be able to be removed in August 2017 update. Only needed for RS1  Production Server workaround - Psched
171 171
         $reg = "HKLM:\System\CurrentControlSet\Services\Psched\Parameters\NdisAdapters"
172 172
         $count=(Get-ChildItem $reg | Measure-Object).Count
173 173
         if ($count -gt 0) {
... ...
@@ -180,7 +211,7 @@ Function Nuke-Everything {
180 180
             }
181 181
         }
182 182
 
183
-        # RS1 Production Server workaround - WFPLWFS
183
+        # TODO: This should be able to be removed in August 2017 update. Only needed for RS1
184 184
         $reg = "HKLM:\System\CurrentControlSet\Services\WFPLWFS\Parameters\NdisAdapters"
185 185
         $count=(Get-ChildItem $reg | Measure-Object).Count
186 186
         if ($count -gt 0) {
... ...
@@ -207,8 +238,8 @@ Try {
207 207
     $origGOPATH="$env:GOPATH"        # So we can restore it at the end
208 208
 
209 209
     # Turn off progress bars
210
-    $origProgressPreference=$global:ProgressPreference
211
-    $global:ProgressPreference='SilentlyContinue'
210
+	$origProgressPreference=$global:ProgressPreference
211
+	$global:ProgressPreference='SilentlyContinue'
212 212
 
213 213
     # Git version
214 214
     Write-Host  -ForegroundColor Green "INFO: Running $(git version)"
... ...
@@ -248,7 +279,6 @@ Try {
248 248
     # SOURCES_DRIVE\SOURCES_SUBDIR must be a directory and exist
249 249
     if (-not (Test-Path -PathType Container "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR")) { Throw "ERROR: $env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR must be an existing directory" }
250 250
 
251
-
252 251
     # Create the TESTRUN_DRIVE\TESTRUN_SUBDIR if it does not already exist
253 252
     New-Item -ItemType Directory -Force -Path "$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR" -ErrorAction SilentlyContinue | Out-Null
254 253
 
... ...
@@ -266,12 +296,12 @@ Try {
266 266
 
267 267
     # Make sure we are in repo
268 268
     if (-not (Test-Path -PathType Leaf -Path ".\Dockerfile.windows")) {
269
-        Throw "$(pwd) does not container Dockerfile.Windows!"
269
+        Throw "$(pwd) does not contain Dockerfile.windows!"
270 270
     }
271 271
     Write-Host  -ForegroundColor Green "INFO: docker/docker repository was found"
272 272
 
273 273
     # Make sure microsoft/windowsservercore:latest image is installed in the control daemon. On public CI machines, windowsservercore.tar and nanoserver.tar
274
-    # are pre-baked and tagged appropriately in the c:\baseimages directory, and can be directly loaded.
274
+    # are pre-baked and tagged appropriately in the c:\baseimages directory, and can be directly loaded. 
275 275
     # Note - this script will only work on 10B (Oct 2016) or later machines! Not 9D or previous due to image tagging assumptions.
276 276
     #
277 277
     # On machines not on Microsoft corpnet, or those which have not been pre-baked, we have to docker pull the image in which case it will
... ...
@@ -288,28 +318,28 @@ Try {
288 288
         # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
289 289
         # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
290 290
         if (Test-Path $("$env:SOURCES_DRIVE`:\baseimages\"+$ControlDaemonBaseImage+".tar")) {
291
-
292
-            # An optimization for CI servers to copy it to the D: drive which is an SSD.
293
-            if ($env:SOURCES_DRIVE -ne $env:TESTRUN_DRIVE) {
294
-                $readBaseFrom=$env:TESTRUN_DRIVE
295
-                if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages")) {
296
-                    New-Item "$env:TESTRUN_DRIVE`:\baseimages" -type directory | Out-Null
297
-                }
298
-                if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\windowsservercore.tar")) {
299
-                    if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar") {
300
-                        Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar to $env:TESTRUN_DRIVE`:\baseimages"
301
-                        Copy-Item "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar" "$env:TESTRUN_DRIVE`:\baseimages"
302
-                    }
303
-                }
304
-                if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\nanoserver.tar")) {
305
-                    if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar") {
306
-                        Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\nanoserver.tar to $env:TESTRUN_DRIVE`:\baseimages"
307
-                        Copy-Item "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar" "$env:TESTRUN_DRIVE`:\baseimages"
308
-                    }
309
-                }
310
-                $readBaseFrom=$env:TESTRUN_DRIVE
311
-            }
312
-
291
+		
292
+			# An optimization for CI servers to copy it to the D: drive which is an SSD.
293
+			if ($env:SOURCES_DRIVE -ne $env:TESTRUN_DRIVE) {
294
+				$readBaseFrom=$env:TESTRUN_DRIVE
295
+				if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages")) {
296
+					New-Item "$env:TESTRUN_DRIVE`:\baseimages" -type directory | Out-Null
297
+				}
298
+				if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\windowsservercore.tar")) {
299
+					if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar") {
300
+						Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar to $env:TESTRUN_DRIVE`:\baseimages"
301
+						Copy-Item "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar" "$env:TESTRUN_DRIVE`:\baseimages"
302
+					}
303
+				}
304
+				if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\nanoserver.tar")) {
305
+					if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar") {
306
+						Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\nanoserver.tar to $env:TESTRUN_DRIVE`:\baseimages"
307
+						Copy-Item "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar" "$env:TESTRUN_DRIVE`:\baseimages"
308
+					}
309
+				}
310
+				$readBaseFrom=$env:TESTRUN_DRIVE
311
+			}
312
+		
313 313
             Write-Host  -ForegroundColor Green "INFO: Loading"$ControlDaemonBaseImage".tar from disk. This may take some time..."
314 314
             $ErrorActionPreference = "SilentlyContinue"
315 315
             docker load -i $("$readBaseFrom`:\baseimages\"+$ControlDaemonBaseImage+".tar")
... ...
@@ -346,14 +376,14 @@ Try {
346 346
     docker version
347 347
     $ErrorActionPreference = "Stop"
348 348
     if (-not($LastExitCode -eq 0)) {
349
-        Write-Host
349
+        Write-Host 
350 350
         Write-Host  -ForegroundColor Green "---------------------------------------------------------------------------"
351 351
         Write-Host  -ForegroundColor Green " Failed to get a response from the control daemon. It may be down."
352
-        Write-Host  -ForegroundColor Green " Try re-running this CI job, or ask on #docker-dev or #docker-maintainers"
353
-        Write-Host  -ForegroundColor Green " to see if the the daemon is running. Also check the nssm configuration."
352
+        Write-Host  -ForegroundColor Green " Try re-running this CI job, or ask on #docker-maintainers on docker slack"
353
+        Write-Host  -ForegroundColor Green " to see if the the daemon is running. Also check the service configuration."
354 354
         Write-Host  -ForegroundColor Green " DOCKER_HOST is set to $DOCKER_HOST."
355 355
         Write-Host  -ForegroundColor Green "---------------------------------------------------------------------------"
356
-        Write-Host
356
+        Write-Host 
357 357
         Throw "ERROR: The control daemon does not appear to be running."
358 358
     }
359 359
     Write-Host
... ...
@@ -382,7 +412,7 @@ Try {
382 382
     Nuke-Everything
383 383
     cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker"
384 384
 
385
-    # Redirect to a temporary location.
385
+    # Redirect to a temporary location. 
386 386
     $TEMPORIG=$env:TEMP
387 387
     $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH"
388 388
     $env:LOCALAPPDATA="$TEMP\localappdata"
... ...
@@ -401,8 +431,23 @@ Try {
401 401
     Write-Host -ForegroundColor Green "INFO: Location for testing is $env:TEMP"
402 402
 
403 403
     # CI Integrity check - ensure Dockerfile.windows and Dockerfile go versions match
404
-    $goVersionDockerfileWindows=$(Get-Content ".\Dockerfile.windows" | Select-String "ENV GO_VERSION").ToString().Replace("ENV GO_VERSION=","").Replace("\","").Replace("``","").Trim()
405
-    $goVersionDockerfile=$(Get-Content ".\Dockerfile" | Select-String "ENV GO_VERSION").ToString().Split(" ")[2]
404
+    $goVersionDockerfileWindows=$(Get-Content ".\Dockerfile.windows" | Select-String "^ENV GO_VERSION").ToString().Replace("ENV GO_VERSION=","").Replace("\","").Replace("``","").Trim()
405
+    $goVersionDockerfile=$(Get-Content ".\Dockerfile" | Select-String "^ENV GO_VERSION")
406
+    
407
+    # As of go 1.11, Dockerfile changed to be in the format like "FROM golang:1.11.0 AS base".
408
+    # If a version number ends with .0 (as in 1.11.0, a convention used in golang docker
409
+    # image versions), it needs to be removed (i.e. "1.11.0" becomes "1.11").
410
+    if ($goVersionDockerfile -eq $Null) {
411
+        $goVersionDockerfile=$(Get-Content ".\Dockerfile" | Select-String "^FROM golang:")
412
+        if ($goVersionDockerfile -ne $Null) {
413
+            $goVersionDockerfile = $goVersionDockerfile.ToString().Split(" ")[1].Split(":")[1] -replace '\.0$',''
414
+        }
415
+    } else {
416
+        $goVersionDockerfile = $goVersionDockerfile.ToString().Split(" ")[2]
417
+    }
418
+    if ($goVersionDockerfile -eq $Null) {
419
+        Throw "ERROR: Failed to extract golang version from Dockerfile"
420
+    }
406 421
     Write-Host  -ForegroundColor Green "INFO: Validating GOLang consistency in Dockerfile.windows..."
407 422
     if (-not ($goVersionDockerfile -eq $goVersionDockerfileWindows)) {
408 423
         Throw "ERROR: Mismatched GO versions between Dockerfile and Dockerfile.windows. Update your PR to ensure that both files are updated and in sync. $goVersionDockerfile $goVersionDockerfileWindows"
... ...
@@ -423,7 +468,7 @@ Try {
423 423
         Write-Host -ForegroundColor Magenta "WARN: Skipping building the docker image"
424 424
     }
425 425
 
426
-    # DON'T THINK THIS IS USED ANYMORE.... $v=$(Get-Content ".\VERSION" -raw).ToString().Replace("`n","").Trim()
426
+    # Following at the moment must be docker\docker as it's dictated by dockerfile.Windows
427 427
     $contPath="$COMMITHASH`:c`:\go\src\github.com\docker\docker\bundles"
428 428
 
429 429
     # After https://github.com/docker/docker/pull/30290, .git was added to .dockerignore. Therefore
... ...
@@ -446,7 +491,7 @@ Try {
446 446
             git status --porcelain --untracked-files=no | Write-Warning
447 447
              Write-Host ""
448 448
         }
449
-        $Duration=$(Measure-Command {docker run --name $COMMITHASH -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -Binary | Out-Host })
449
+        $Duration=$(Measure-Command {docker run --name $COMMITHASH -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -Daemon -Client | Out-Host })
450 450
         $ErrorActionPreference = "Stop"
451 451
         if (-not($LastExitCode -eq 0)) {
452 452
             Throw "ERROR: Failed to build binary"
... ...
@@ -498,7 +543,7 @@ Try {
498 498
         # Extract the golang installer
499 499
         Write-Host -ForegroundColor Green "INFO: Extracting go.zip to $env:TEMP\go"
500 500
         $Duration=$(Measure-Command { Expand-Archive $env:TEMP\installer\go.zip $env:TEMP -Force | Out-Null})
501
-        Write-Host  -ForegroundColor Green "INFO: Extraction ended at $(Get-Date). Duration`:$Duration"
501
+        Write-Host  -ForegroundColor Green "INFO: Extraction ended at $(Get-Date). Duration`:$Duration"    
502 502
     } else {
503 503
         Write-Host -ForegroundColor Magenta "WARN: Skipping copying and extracting golang from the image"
504 504
     }
... ...
@@ -514,7 +559,7 @@ Try {
514 514
     # Set the GOROOT to be our copy of go from the image
515 515
     $env:GOROOT="$env:TEMP\go"
516 516
     Write-Host -ForegroundColor Green "INFO: $(go version)"
517
-
517
+    
518 518
     # Work out the the -H parameter for the daemon under test (DASHH_DUT) and client under test (DASHH_CUT)
519 519
     #$DASHH_DUT="npipe:////./pipe/$COMMITHASH" # Can't do remote named pipe
520 520
     #$ip = (resolve-dnsname $env:COMPUTERNAME -type A -NoHostsFile -LlmnrNetbiosOnly).IPAddress # Useful to tie down
... ...
@@ -524,9 +569,12 @@ Try {
524 524
     # Arguments for the daemon under test
525 525
     $dutArgs=@()
526 526
     $dutArgs += "-H $DASHH_DUT"
527
-    $dutArgs += "--graph $env:TEMP\daemon"
527
+    $dutArgs += "--data-root $env:TEMP\daemon"
528 528
     $dutArgs += "--pidfile $env:TEMP\docker.pid"
529 529
 
530
+    # Save the PID file so we can nuke it if set
531
+    $pidFile="$env:TEMP\docker.pid"
532
+
530 533
     # Arguments: Are we starting the daemon under test in debug mode?
531 534
     if (-not ("$env:DOCKER_DUT_DEBUG" -eq "")) {
532 535
         Write-Host -ForegroundColor Green "INFO: Running the daemon under test in debug mode"
... ...
@@ -541,25 +589,36 @@ Try {
541 541
 
542 542
     # Start the daemon under test, ensuring everything is redirected to folders under $TEMP.
543 543
     # Important - we launch the -$COMMITHASH version so that we can kill it without
544
-    # killing the control daemon.
544
+    # killing the control daemon. 
545 545
     Write-Host -ForegroundColor Green "INFO: Starting a daemon under test..."
546 546
     Write-Host -ForegroundColor Green "INFO: Args: $dutArgs"
547 547
     New-Item -ItemType Directory $env:TEMP\daemon -ErrorAction SilentlyContinue  | Out-Null
548 548
 
549
+    # In LCOW mode, for now we need to set an environment variable before starting the daemon under test
550
+    if (($env:LCOW_MODE -ne $Null) -or ($env:LCOW_BASIC_MODE -ne $Null)) {
551
+        $env:LCOW_SUPPORTED=1
552
+    }
553
+
549 554
     # Cannot fathom why, but always writes to stderr....
550 555
     Start-Process "$env:TEMP\binary\dockerd-$COMMITHASH" `
551 556
                   -ArgumentList $dutArgs `
552 557
                   -RedirectStandardOutput "$env:TEMP\dut.out" `
553
-                  -RedirectStandardError "$env:TEMP\dut.err"
558
+                  -RedirectStandardError "$env:TEMP\dut.err" 
554 559
     Write-Host -ForegroundColor Green "INFO: Process started successfully."
555 560
     $daemonStarted=1
556 561
 
562
+    # In LCOW mode, turn off that variable
563
+    if (($env:LCOW_MODE -ne $Null) -or ($env:LCOW_BASIC_MODE -ne $Null)) {
564
+        $env:LCOW_SUPPORTED=""
565
+    }
566
+
567
+
557 568
     # Start tailing the daemon under test if the command is installed
558
-    if ((Get-Command "tail" -ErrorAction SilentlyContinue) -ne $null) {
569
+    if ((Get-Command "tail" -ErrorAction SilentlyContinue) -ne $null) { 
559 570
         $tail = start-process "tail" -ArgumentList "-f $env:TEMP\dut.out" -ErrorAction SilentlyContinue
560 571
     }
561 572
 
562
-    # Verify we can get the daemon under test to respond
573
+    # Verify we can get the daemon under test to respond 
563 574
     $tries=20
564 575
     Write-Host -ForegroundColor Green "INFO: Waiting for the daemon under test to start..."
565 576
     while ($true) {
... ...
@@ -582,7 +641,7 @@ Try {
582 582
 
583 583
     # Provide the docker version of the daemon under test for debugging purposes.
584 584
     Write-Host -ForegroundColor Green "INFO: Docker version of the daemon under test"
585
-    Write-Host
585
+    Write-Host 
586 586
     $ErrorActionPreference = "SilentlyContinue"
587 587
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" version
588 588
     $ErrorActionPreference = "Stop"
... ...
@@ -594,7 +653,7 @@ Try {
594 594
 
595 595
     # Same as above but docker info
596 596
     Write-Host -ForegroundColor Green "INFO: Docker info of the daemon under test"
597
-    Write-Host
597
+    Write-Host 
598 598
     $ErrorActionPreference = "SilentlyContinue"
599 599
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" info
600 600
     $ErrorActionPreference = "Stop"
... ...
@@ -606,7 +665,7 @@ Try {
606 606
 
607 607
     # Same as above but docker images
608 608
     Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
609
-    Write-Host
609
+    Write-Host 
610 610
     $ErrorActionPreference = "SilentlyContinue"
611 611
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
612 612
     $ErrorActionPreference = "Stop"
... ...
@@ -616,54 +675,59 @@ Try {
616 616
     }
617 617
     Write-Host
618 618
 
619
-    # Default to windowsservercore for the base image used for the tests. The "docker" image
620
-    # and the control daemon use microsoft/windowsservercore regardless. This is *JUST* for the tests.
621
-    if ($env:WINDOWS_BASE_IMAGE -eq $Null) {
622
-        $env:WINDOWS_BASE_IMAGE="microsoft/windowsservercore"
623
-    }
619
+    # Don't need Windows images when in LCOW mode.
620
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
624 621
 
625
-    # Lowercase and make sure it has a microsoft/ prefix
626
-    $env:WINDOWS_BASE_IMAGE = $env:WINDOWS_BASE_IMAGE.ToLower()
627
-    if ($($env:WINDOWS_BASE_IMAGE -Split "/")[0] -ne "microsoft") {
628
-        Throw "ERROR: WINDOWS_BASE_IMAGE should start microsoft/"
629
-    }
622
+        # Default to windowsservercore for the base image used for the tests. The "docker" image
623
+        # and the control daemon use microsoft/windowsservercore regardless. This is *JUST* for the tests.
624
+        if ($env:WINDOWS_BASE_IMAGE -eq $Null) {
625
+            $env:WINDOWS_BASE_IMAGE="microsoft/windowsservercore"
626
+        }
630 627
 
631
-    Write-Host -ForegroundColor Green "INFO: Base image for tests is $env:WINDOWS_BASE_IMAGE"
628
+        # Lowercase and make sure it has a microsoft/ prefix
629
+        $env:WINDOWS_BASE_IMAGE = $env:WINDOWS_BASE_IMAGE.ToLower()
630
+        if ($($env:WINDOWS_BASE_IMAGE -Split "/")[0] -ne "microsoft") {
631
+            Throw "ERROR: WINDOWS_BASE_IMAGE should start microsoft/"
632
+        }
632 633
 
633
-    $ErrorActionPreference = "SilentlyContinue"
634
-    if ($((& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images --format "{{.Repository}}:{{.Tag}}" | Select-String $($env:WINDOWS_BASE_IMAGE+":latest") | Measure-Object -Line).Lines) -eq 0) {
635
-        # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
636
-        # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
637
-        if (Test-Path $("c:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")) {
638
-            Write-Host  -ForegroundColor Green "INFO: Loading"$($env:WINDOWS_BASE_IMAGE -Split "/")[1]".tar from disk into the daemon under test. This may take some time..."
639
-            $ErrorActionPreference = "SilentlyContinue"
640
-            & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" load -i $("$readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")
641
-            $ErrorActionPreference = "Stop"
642
-            if (-not $LastExitCode -eq 0) {
643
-                Throw $("ERROR: Failed to load $readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar into daemon under test")
634
+        Write-Host -ForegroundColor Green "INFO: Base image for tests is $env:WINDOWS_BASE_IMAGE"
635
+
636
+        $ErrorActionPreference = "SilentlyContinue"
637
+        if ($((& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images --format "{{.Repository}}:{{.Tag}}" | Select-String $($env:WINDOWS_BASE_IMAGE+":latest") | Measure-Object -Line).Lines) -eq 0) {
638
+            # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
639
+            # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
640
+            if (Test-Path $("c:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")) {
641
+                Write-Host  -ForegroundColor Green "INFO: Loading"$($env:WINDOWS_BASE_IMAGE -Split "/")[1]".tar from disk into the daemon under test. This may take some time..."
642
+                $ErrorActionPreference = "SilentlyContinue"
643
+                & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" load -i $("$readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")
644
+                $ErrorActionPreference = "Stop"
645
+                if (-not $LastExitCode -eq 0) {
646
+                    Throw $("ERROR: Failed to load $readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar into daemon under test")
647
+                }
648
+                Write-Host -ForegroundColor Green "INFO: docker load of"$($env:WINDOWS_BASE_IMAGE -Split "/")[1]" into daemon under test completed successfully"
649
+            } else {
650
+                # We need to docker pull it instead. It will come in directly as microsoft/imagename:latest
651
+                Write-Host -ForegroundColor Green $("INFO: Pulling "+$env:WINDOWS_BASE_IMAGE+":latest from docker hub into daemon under test. This may take some time...")
652
+                $ErrorActionPreference = "SilentlyContinue"
653
+                & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" pull $($env:WINDOWS_BASE_IMAGE)
654
+                $ErrorActionPreference = "Stop"
655
+                if (-not $LastExitCode -eq 0) {
656
+                    Throw $("ERROR: Failed to docker pull "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test.")
657
+                }
658
+                Write-Host -ForegroundColor Green $("INFO: docker pull of "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test completed successfully")
644 659
             }
645
-            Write-Host -ForegroundColor Green "INFO: docker load of"$($env:WINDOWS_BASE_IMAGE -Split "/")[1]" into daemon under test completed successfully"
646 660
         } else {
647
-            # We need to docker pull it instead. It will come in directly as microsoft/imagename:latest
648
-            Write-Host -ForegroundColor Green $("INFO: Pulling "+$env:WINDOWS_BASE_IMAGE+":latest from docker hub into daemon under test. This may take some time...")
649
-            $ErrorActionPreference = "SilentlyContinue"
650
-            & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" pull $($env:WINDOWS_BASE_IMAGE)
651
-            $ErrorActionPreference = "Stop"
652
-            if (-not $LastExitCode -eq 0) {
653
-                Throw $("ERROR: Failed to docker pull "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test.")
654
-            }
655
-            Write-Host -ForegroundColor Green $("INFO: docker pull of "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test completed successfully")
661
+            Write-Host -ForegroundColor Green "INFO: Image"$($env:WINDOWS_BASE_IMAGE+":latest")"is already loaded in the daemon under test"
656 662
         }
657
-    } else {
658
-        Write-Host -ForegroundColor Green "INFO: Image"$($env:WINDOWS_BASE_IMAGE+":latest")"is already loaded in the daemon under test"
663
+    
664
+    
665
+        # Inspect the pulled or loaded image to get the version directly
666
+        $ErrorActionPreference = "SilentlyContinue"
667
+        $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect  $($env:WINDOWS_BASE_IMAGE) --format "{{.OsVersion}}")
668
+        $ErrorActionPreference = "Stop"
669
+        Write-Host -ForegroundColor Green $("INFO: Version of "+$env:WINDOWS_BASE_IMAGE+":latest is '"+$dutimgVersion+"'")
659 670
     }
660 671
 
661
-    # Inspect the pulled or loaded image to get the version directly
662
-    $ErrorActionPreference = "SilentlyContinue"
663
-    $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect  $($env:WINDOWS_BASE_IMAGE) --format "{{.OsVersion}}")
664
-    $ErrorActionPreference = "Stop"
665
-    Write-Host -ForegroundColor Green $("INFO: Version of "+$env:WINDOWS_BASE_IMAGE+":latest is '"+$dutimgVersion+"'")
666
-
667 672
     # Run the validation tests unless SKIP_VALIDATION_TESTS is defined.
668 673
     if ($env:SKIP_VALIDATION_TESTS -eq $null) {
669 674
         Write-Host -ForegroundColor Cyan "INFO: Running validation tests at $(Get-Date)..."
... ...
@@ -678,162 +742,188 @@ Try {
678 678
         Write-Host -ForegroundColor Magenta "WARN: Skipping validation tests"
679 679
     }
680 680
 
681
+    # Note the unit tests won't work in LCOW mode as I turned off loading the base images above.
681 682
     # Run the unit tests inside a container unless SKIP_UNIT_TESTS is defined
682
-    if ($env:SKIP_UNIT_TESTS -eq $null) {
683
-        Write-Host -ForegroundColor Cyan "INFO: Running unit tests at $(Get-Date)..."
684
-        $ErrorActionPreference = "SilentlyContinue"
685
-        $Duration=$(Measure-Command {docker run -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -TestUnit | Out-Host })
686
-        $ErrorActionPreference = "Stop"
687
-        if (-not($LastExitCode -eq 0)) {
688
-            Throw "ERROR: Unit tests failed"
683
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
684
+        if ($env:SKIP_UNIT_TESTS -eq $null) {
685
+            Write-Host -ForegroundColor Cyan "INFO: Running unit tests at $(Get-Date)..."
686
+            $ErrorActionPreference = "SilentlyContinue"
687
+            $Duration=$(Measure-Command {docker run -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -TestUnit | Out-Host })
688
+            $ErrorActionPreference = "Stop"
689
+            if (-not($LastExitCode -eq 0)) {
690
+                Throw "ERROR: Unit tests failed"
691
+            }
692
+            Write-Host  -ForegroundColor Green "INFO: Unit tests ended at $(Get-Date). Duration`:$Duration"
693
+        } else {
694
+            Write-Host -ForegroundColor Magenta "WARN: Skipping unit tests"
689 695
         }
690
-        Write-Host  -ForegroundColor Green "INFO: Unit tests ended at $(Get-Date). Duration`:$Duration"
691
-    } else {
692
-        Write-Host -ForegroundColor Magenta "WARN: Skipping unit tests"
693 696
     }
694 697
 
695
-    # Add the busybox image. Needed for integration tests
696
-    if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
697
-        $ErrorActionPreference = "SilentlyContinue"
698
-        # Build it regardless while switching between nanoserver and windowsservercore
699
-        #$bbCount = $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images | Select-String "busybox" | Measure-Object -line).Lines
700
-        #$ErrorActionPreference = "Stop"
701
-        #if (-not($LastExitCode -eq 0)) {
702
-        #    Throw "ERROR: Could not determine if busybox image is present"
703
-        #}
704
-        #if ($bbCount -eq 0) {
705
-            Write-Host -ForegroundColor Green "INFO: Building busybox"
698
+    # Add the Windows busybox image. Needed for WCOW integration tests
699
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
700
+        if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
706 701
             $ErrorActionPreference = "SilentlyContinue"
702
+            # Build it regardless while switching between nanoserver and windowsservercore
703
+            #$bbCount = $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images | Select-String "busybox" | Measure-Object -line).Lines
704
+            #$ErrorActionPreference = "Stop"
705
+            #if (-not($LastExitCode -eq 0)) {
706
+            #    Throw "ERROR: Could not determine if busybox image is present"
707
+            #}
708
+            #if ($bbCount -eq 0) {
709
+                Write-Host -ForegroundColor Green "INFO: Building busybox"
710
+                $ErrorActionPreference = "SilentlyContinue"
711
+    
712
+                # This is a temporary hack for nanoserver
713
+                if ($env:WINDOWS_BASE_IMAGE -ne "microsoft/windowsservercore") {
714
+                    Write-Host -ForegroundColor Red "HACK HACK HACK - Building 64-bit nanoserver busybox image"
715
+                    $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox64/master/Dockerfile | Out-Host)
716
+                } else {
717
+                    $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox/master/Dockerfile | Out-Host)
718
+                }
719
+                $ErrorActionPreference = "Stop"
720
+                if (-not($LastExitCode -eq 0)) {
721
+                    Throw "ERROR: Failed to build busybox image"
722
+                }
723
+            #}
707 724
 
708
-            # This is a temporary hack for nanoserver
709
-            if ($env:WINDOWS_BASE_IMAGE -ne "microsoft/windowsservercore") {
710
-                Write-Host -ForegroundColor Red "HACK HACK HACK - Building 64-bit nanoserver busybox image"
711
-                $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox64/master/Dockerfile | Out-Host)
712
-            } else {
713
-                $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox/master/Dockerfile | Out-Host)
725
+
726
+            Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
727
+            Write-Host 
728
+            $ErrorActionPreference = "SilentlyContinue"
729
+            & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
730
+            $ErrorActionPreference = "Stop"
731
+            if ($LastExitCode -ne 0) {
732
+                Throw "ERROR: The daemon under test does not appear to be running."
733
+                $DumpDaemonLog=1
734
+            }
735
+            Write-Host
736
+        }
737
+    }
738
+
739
+    # Run the WCOW integration tests unless SKIP_INTEGRATION_TESTS is defined
740
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
741
+        if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
742
+            Write-Host -ForegroundColor Cyan "INFO: Running integration tests at $(Get-Date)..."
743
+            $ErrorActionPreference = "SilentlyContinue"
744
+    
745
+            # Location of the daemon under test.
746
+            $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
747
+    
748
+            #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
749
+            $c = "go test "
750
+            $c += "`"-check.v`" "
751
+            if ($env:INTEGRATION_TEST_NAME -ne $null) { # Makes is quicker for debugging to be able to run only a subset of the integration tests
752
+                $c += "`"-check.f`" "
753
+                $c += "`"$env:INTEGRATION_TEST_NAME`" "
754
+                Write-Host -ForegroundColor Magenta "WARN: Only running integration tests matching $env:INTEGRATION_TEST_NAME"
755
+            }
756
+            $c += "`"-tags`" " + "`"autogen`" "
757
+            $c += "`"-check.timeout`" " + "`"10m`" "
758
+            $c += "`"-test.timeout`" " + "`"200m`" "
759
+    
760
+            if ($env:INTEGRATION_IN_CONTAINER -ne $null) {
761
+                Write-Host -ForegroundColor Green "INFO: Integration tests being run inside a container"
762
+                # Note we talk back through the containers gateway address
763
+                # And the ridiculous lengths we have to go to to get the default gateway address... (GetNetIPConfiguration doesn't work in nanoserver)
764
+                # I just could not get the escaping to work in a single command, so output $c to a file and run that in the container instead...
765
+                # Not the prettiest, but it works.
766
+                $c | Out-File -Force "$env:TEMP\binary\runIntegrationCLI.ps1"
767
+                $Duration= $(Measure-Command { & docker run `
768
+                                                        --rm `
769
+                                                        -e c=$c `
770
+                                                        --workdir "c`:\go\src\github.com\docker\docker\integration-cli" `
771
+                                                        -v "$env:TEMP\binary`:c:\target" `
772
+                                                        docker `
773
+                                                        "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
774
+            } else  {
775
+                Write-Host -ForegroundColor Green "INFO: Integration tests being run from the host:"
776
+                cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration-cli"
777
+                $env:DOCKER_HOST=$DASHH_CUT  
778
+                $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
779
+                Write-Host -ForegroundColor Green "INFO: $c"
780
+                Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
781
+                # Explicit to not use measure-command otherwise don't get output as it goes
782
+                $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
714 783
             }
715 784
             $ErrorActionPreference = "Stop"
716 785
             if (-not($LastExitCode -eq 0)) {
717
-                Throw "ERROR: Failed to build busybox image"
786
+                Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
718 787
             }
719
-        #}
720
-
721
-
722
-        Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
723
-        Write-Host
724
-        $ErrorActionPreference = "SilentlyContinue"
725
-        & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
726
-        $ErrorActionPreference = "Stop"
727
-        if ($LastExitCode -ne 0) {
728
-            Throw "ERROR: The daemon under test does not appear to be running."
729
-            $DumpDaemonLog=1
788
+            Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
789
+        } else {
790
+            Write-Host -ForegroundColor Magenta "WARN: Skipping integration tests"
730 791
         }
731
-        Write-Host
732
-    }
792
+    } else {
793
+        # The LCOW version of the tests here
794
+        if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
795
+            Write-Host -ForegroundColor Cyan "INFO: Running LCOW tests at $(Get-Date)..."
733 796
 
734
-    # Run the integration tests unless SKIP_INTEGRATION_TESTS is defined
735
-    if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
736
-        Write-Host -ForegroundColor Cyan "INFO: Running integration tests at $(Get-Date)..."
737
-        $ErrorActionPreference = "SilentlyContinue"
797
+            $ErrorActionPreference = "SilentlyContinue"
798
+    
799
+            # Location of the daemon under test.
800
+            $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
738 801
 
739
-        # Location of the daemon under test.
740
-        $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
741
-
742
-        #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
743
-        $c = "go test "
744
-        $c += "`"-tags`" " + "`"autogen`" "
745
-        $c += "./integration/..."
746
-
747
-        if ($env:INTEGRATION_IN_CONTAINER -ne $null) {
748
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run inside a container"
749
-            # Note we talk back through the containers gateway address
750
-            # And the ridiculous lengths we have to go to to get the default gateway address... (GetNetIPConfiguration doesn't work in nanoserver)
751
-            # I just could not get the escaping to work in a single command, so output $c to a file and run that in the container instead...
752
-            # Not the prettiest, but it works.
753
-            $c | Out-File -Force "$env:TEMP\binary\runIntegration.ps1"
754
-            $Duration= $(Measure-Command { & docker run `
755
-                                                    --rm `
756
-                                                    -e c=$c `
757
-                                                    --workdir "c`:\go\src\github.com\docker\docker\" `
758
-                                                    -v "$env:TEMP\binary`:c:\target" `
759
-                                                    docker `
760
-                                                    "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
761
-        } else  {
762
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run from the host:"
763
-            #cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration"
764
-            $env:DOCKER_HOST=$DASHH_CUT
765
-            $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
766
-            Write-Host -ForegroundColor Green "INFO: $c"
802
+            # Make sure we are pointing at the DUT
803
+            $env:DOCKER_HOST=$DASHH_CUT  
767 804
             Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
768
-            # Explicit to not use measure-command otherwise don't get output as it goes
769
-            $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
770
-        }
771
-        $ErrorActionPreference = "Stop"
772
-        if (-not($LastExitCode -eq 0)) {
773
-            Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
774
-        }
775
-        Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
776
-    }else {
777
-        Write-Host -ForegroundColor Magenta "WARN: Skipping integration tests"
778
-    }
779 805
 
780
-    # Run the integration tests unless SKIP_INTEGRATION_TESTS is defined
781
-    if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
782
-        Write-Host -ForegroundColor Cyan "INFO: Running integration cli tests at $(Get-Date)..."
783
-        $ErrorActionPreference = "SilentlyContinue"
806
+            # Force to use the test binaries, not the host ones.
807
+            $env:PATH="$env:TEMP\binary;$env:PATH;"  
808
+
809
+            if ($env:LCOW_BASIC_MODE -ne $null) {
810
+                $wc = New-Object net.webclient
811
+                try {
812
+                    Write-Host -ForegroundColor green "INFO: Downloading latest execution script..."
813
+                    $wc.Downloadfile("https://raw.githubusercontent.com/jhowardmsft/docker-w2wCIScripts/master/runCI/lcowbasicvalidation.ps1", "$env:TEMP\binary\lcowbasicvalidation.ps1")
814
+                } 
815
+                catch [System.Net.WebException]
816
+                {
817
+                    Throw ("Failed to download: $_")
818
+                }
784 819
 
785
-        # Location of the daemon under test.
786
-        $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
820
+                # Explicit to not use measure-command otherwise don't get output as it goes
821
+                $ErrorActionPreference = "Stop"
822
+                $start=(Get-Date); Invoke-Expression "powershell $env:TEMP\binary\lcowbasicvalidation.ps1"; $lec=$lastExitCode; $Duration=New-Timespan -Start $start -End (Get-Date)
823
+                $Duration=New-Timespan -Start $start -End (Get-Date)
824
+                Write-Host  -ForegroundColor Green "INFO: LCOW tests ended at $(Get-Date). Duration`:$Duration"
825
+                if ($lec -ne 0) {
826
+                    Throw "LCOW validation tests failed"
827
+                }
828
+            } else {
829
+                #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
830
+                $c = "go test "
831
+                $c += "`"-check.v`" "
832
+                if ($env:INTEGRATION_TEST_NAME -ne $null) { # Makes is quicker for debugging to be able to run only a subset of the integration tests
833
+                    $c += "`"-check.f`" "
834
+                    $c += "`"$env:INTEGRATION_TEST_NAME`" "
835
+                    Write-Host -ForegroundColor Magenta "WARN: Only running LCOW integration tests matching $env:INTEGRATION_TEST_NAME"
836
+                }
837
+                $c += "`"-tags`" " + "`"autogen`" "
838
+                $c += "`"-check.timeout`" " + "`"10m`" "
839
+                $c += "`"-test.timeout`" " + "`"200m`" "
787 840
 
788
-        #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
789
-        $c = "go test "
790
-        $c += "`"-check.v`" "
791
-        if ($env:INTEGRATION_TEST_NAME -ne $null) { # Makes is quicker for debugging to be able to run only a subset of the integration tests
792
-            $c += "`"-check.f`" "
793
-            $c += "`"$env:INTEGRATION_TEST_NAME`" "
794
-            Write-Host -ForegroundColor Magenta "WARN: Only running integration tests matching $env:INTEGRATION_TEST_NAME"
795
-        }
796
-        $c += "`"-tags`" " + "`"autogen`" "
797
-        $c += "`"-check.timeout`" " + "`"10m`" "
798
-        $c += "`"-test.timeout`" " + "`"200m`" "
799
-
800
-        if ($env:INTEGRATION_IN_CONTAINER -ne $null) {
801
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run inside a container"
802
-            # Note we talk back through the containers gateway address
803
-            # And the ridiculous lengths we have to go to to get the default gateway address... (GetNetIPConfiguration doesn't work in nanoserver)
804
-            # I just could not get the escaping to work in a single command, so output $c to a file and run that in the container instead...
805
-            # Not the prettiest, but it works.
806
-            $c | Out-File -Force "$env:TEMP\binary\runIntegrationCLI.ps1"
807
-            $Duration= $(Measure-Command { & docker run `
808
-                                                    --rm `
809
-                                                    -e c=$c `
810
-                                                    --workdir "c`:\go\src\github.com\docker\docker\integration-cli" `
811
-                                                    -v "$env:TEMP\binary`:c:\target" `
812
-                                                    docker `
813
-                                                    "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
814
-        } else  {
815
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run from the host:"
816
-            cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration-cli"
817
-            $env:DOCKER_HOST=$DASHH_CUT
818
-            $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
819
-            Write-Host -ForegroundColor Green "INFO: $c"
820
-            Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
821
-            # Explicit to not use measure-command otherwise don't get output as it goes
822
-            $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
823
-        }
824
-        $ErrorActionPreference = "Stop"
825
-        if (-not($LastExitCode -eq 0)) {
826
-            Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
841
+                Write-Host -ForegroundColor Green "INFO: LCOW Integration tests being run from the host:"
842
+                cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration-cli"
843
+                Write-Host -ForegroundColor Green "INFO: $c"
844
+                Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
845
+                # Explicit to not use measure-command otherwise don't get output as it goes
846
+                $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
847
+
848
+            }
849
+            $ErrorActionPreference = "Stop"
850
+            if (-not($LastExitCode -eq 0)) {
851
+                Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
852
+            }
853
+            Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
854
+        } else {
855
+            Write-Host -ForegroundColor Magenta "WARN: Skipping LCOW tests"
827 856
         }
828
-        Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
829
-    }else {
830
-        Write-Host -ForegroundColor Magenta "WARN: Skipping integration tests"
831 857
     }
832 858
 
833 859
     # Docker info now to get counts (after or if jjh/containercounts is merged)
834 860
     if ($daemonStarted -eq 1) {
835 861
         Write-Host -ForegroundColor Green "INFO: Docker info of the daemon under test at end of run"
836
-        Write-Host
862
+        Write-Host 
837 863
         $ErrorActionPreference = "SilentlyContinue"
838 864
         & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" info
839 865
         $ErrorActionPreference = "Stop"
... ...
@@ -845,16 +935,14 @@ Try {
845 845
     }
846 846
 
847 847
     # Stop the daemon under test
848
-    if ($daemonStarted -eq 1) {
849
-        if (Test-Path "$env:TEMP\docker.pid") {
850
-            $p=Get-Content "$env:TEMP\docker.pid" -raw
851
-            if ($p -ne $null) {
852
-                Write-Host -ForegroundColor green "INFO: Stopping daemon under test"
853
-                taskkill -f -t -pid $p
854
-                Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue
855
-                #sleep 5
856
-            }
848
+    if (Test-Path "$env:TEMP\docker.pid") {
849
+        $p=Get-Content "$env:TEMP\docker.pid" -raw
850
+        if (($p -ne $null) -and ($daemonStarted -eq 1)) {
851
+            Write-Host -ForegroundColor green "INFO: Stopping daemon under test"
852
+            taskkill -f -t -pid $p
853
+            #sleep 5
857 854
         }
855
+        Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue
858 856
     }
859 857
 
860 858
     Write-Host -ForegroundColor Green "INFO: executeCI.ps1 Completed successfully at $(Get-Date)."
... ...
@@ -862,18 +950,19 @@ Try {
862 862
 Catch [Exception] {
863 863
     $FinallyColour="Red"
864 864
     Write-Host -ForegroundColor Red ("`r`n`r`nERROR: Failed '$_' at $(Get-Date)")
865
+    Write-Host -ForegroundColor Red ($_.InvocationInfo.PositionMessage)
865 866
     Write-Host "`n`n"
866 867
 
867 868
     # Exit to ensure Jenkins captures it. Don't do this in the ISE or interactive Powershell - they will catch the Throw onwards.
868 869
     if ( ([bool]([Environment]::GetCommandLineArgs() -Like '*-NonInteractive*')) -and `
869
-        ([bool]([Environment]::GetCommandLineArgs() -NotLike "*Powershell_ISE.exe*"))) {
870
+         ([bool]([Environment]::GetCommandLineArgs() -NotLike "*Powershell_ISE.exe*"))) {
870 871
         exit 1
871 872
     }
872 873
     Throw $_
873 874
 }
874 875
 Finally {
875 876
     $ErrorActionPreference="SilentlyContinue"
876
-    $global:ProgressPreference=$origProgressPreference
877
+	$global:ProgressPreference=$origProgressPreference
877 878
     Write-Host  -ForegroundColor Green "INFO: Tidying up at end of run"
878 879
 
879 880
     # Restore the path
... ...
@@ -886,7 +975,7 @@ Finally {
886 886
     if ($origGOROOT -ne $null) { $env:GOROOT=$origGOROOT }
887 887
     if ($origGOPATH -ne $null) { $env:GOPATH=$origGOPATH }
888 888
 
889
-    # Dump the daemon log if asked to
889
+    # Dump the daemon log if asked to 
890 890
     if ($daemonStarted -eq 1) {
891 891
         if ($dumpDaemonLog -eq 1) {
892 892
             Write-Host -ForegroundColor Cyan "----------- DAEMON LOG ------------"
... ...
@@ -906,4 +995,3 @@ Finally {
906 906
     $Dur=New-TimeSpan -Start $StartTime -End $(Get-Date)
907 907
     Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n"
908 908
 }
909
-
... ...
@@ -20,6 +20,7 @@ import (
20 20
 
21 21
 func TestBuildSquashParent(t *testing.T) {
22 22
 	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
23
+	skip.If(t, !testEnv.DaemonInfo.ExperimentalBuild)
23 24
 	skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon")
24 25
 	d := daemon.New(t, daemon.WithExperimental)
25 26
 	d.StartWithBusybox(t)
... ...
@@ -189,6 +189,7 @@ func TestBuildMultiStageParentConfig(t *testing.T) {
189 189
 // Test cases in #36996
190 190
 func TestBuildLabelWithTargets(t *testing.T) {
191 191
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "test added after 1.38")
192
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
192 193
 	bldName := "build-a"
193 194
 	testLabels := map[string]string{
194 195
 		"foo":  "bar",
... ...
@@ -443,6 +444,7 @@ RUN [ ! -f foo ]
443 443
 
444 444
 // #37581
445 445
 func TestBuildWithHugeFile(t *testing.T) {
446
+	skip.If(t, testEnv.OSType == "windows")
446 447
 	ctx := context.TODO()
447 448
 	defer setupTest(t)()
448 449
 
449 450
new file mode 100644
... ...
@@ -0,0 +1,101 @@
0
+package container // import "github.com/docker/docker/integration/container"
1
+
2
+import (
3
+	"context"
4
+	"fmt"
5
+	"strconv"
6
+	"strings"
7
+	"testing"
8
+	"time"
9
+
10
+	"github.com/docker/docker/api/types"
11
+	"github.com/docker/docker/integration/internal/container"
12
+	"github.com/docker/docker/internal/test/request"
13
+	"gotest.tools/assert"
14
+	"gotest.tools/icmd"
15
+	"gotest.tools/poll"
16
+	"gotest.tools/skip"
17
+)
18
+
19
+// TestStopContainerWithTimeout checks that ContainerStop with
20
+// a timeout works as documented, i.e. in case of negative timeout
21
+// waiting is not limited (issue #35311).
22
+func TestStopContainerWithTimeout(t *testing.T) {
23
+	defer setupTest(t)()
24
+	client := request.NewAPIClient(t)
25
+	ctx := context.Background()
26
+
27
+	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
28
+	testData := []struct {
29
+		doc              string
30
+		timeout          int
31
+		expectedExitCode int
32
+	}{
33
+		// In case container is forcefully killed, 137 is returned,
34
+		// otherwise the exit code from the above script
35
+		{
36
+			"zero timeout: expect forceful container kill",
37
+			0, 137,
38
+		},
39
+		{
40
+			"too small timeout: expect forceful container kill",
41
+			1, 137,
42
+		},
43
+		{
44
+			"big enough timeout: expect graceful container stop",
45
+			3, 42,
46
+		},
47
+		{
48
+			"unlimited timeout: expect graceful container stop",
49
+			-1, 42,
50
+		},
51
+	}
52
+
53
+	for _, d := range testData {
54
+		d := d
55
+		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
56
+			t.Parallel()
57
+			id := container.Run(t, ctx, client, testCmd)
58
+
59
+			timeout := time.Duration(d.timeout) * time.Second
60
+			err := client.ContainerStop(ctx, id, &timeout)
61
+			assert.NilError(t, err)
62
+
63
+			poll.WaitOn(t, container.IsStopped(ctx, client, id),
64
+				poll.WithDelay(100*time.Millisecond))
65
+
66
+			inspect, err := client.ContainerInspect(ctx, id)
67
+			assert.NilError(t, err)
68
+			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
69
+		})
70
+	}
71
+}
72
+
73
+func TestDeleteDevicemapper(t *testing.T) {
74
+	skip.If(t, testEnv.DaemonInfo.Driver != "devicemapper")
75
+	skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run")
76
+
77
+	defer setupTest(t)()
78
+	client := request.NewAPIClient(t)
79
+	ctx := context.Background()
80
+
81
+	id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo"))
82
+
83
+	poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
84
+
85
+	inspect, err := client.ContainerInspect(ctx, id)
86
+	assert.NilError(t, err)
87
+
88
+	deviceID := inspect.GraphDriver.Data["DeviceId"]
89
+
90
+	// Find pool name from device name
91
+	deviceName := inspect.GraphDriver.Data["DeviceName"]
92
+	devicePrefix := deviceName[:strings.LastIndex(deviceName, "-")]
93
+	devicePool := fmt.Sprintf("/dev/mapper/%s-pool", devicePrefix)
94
+
95
+	result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
96
+	result.Assert(t, icmd.Success)
97
+
98
+	err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
99
+	assert.NilError(t, err)
100
+}
... ...
@@ -2,19 +2,13 @@ package container // import "github.com/docker/docker/integration/container"
2 2
 
3 3
 import (
4 4
 	"context"
5
-	"fmt"
6
-	"strconv"
7
-	"strings"
8 5
 	"testing"
9 6
 	"time"
10 7
 
11
-	"github.com/docker/docker/api/types"
12 8
 	"github.com/docker/docker/integration/internal/container"
13 9
 	"github.com/docker/docker/internal/test/request"
14 10
 	"gotest.tools/assert"
15
-	"gotest.tools/icmd"
16 11
 	"gotest.tools/poll"
17
-	"gotest.tools/skip"
18 12
 )
19 13
 
20 14
 func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
... ...
@@ -42,86 +36,3 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
42 42
 		poll.WaitOn(t, container.IsStopped(ctx, client, name), poll.WithDelay(100*time.Millisecond))
43 43
 	}
44 44
 }
45
-
46
-// TestStopContainerWithTimeout checks that ContainerStop with
47
-// a timeout works as documented, i.e. in case of negative timeout
48
-// waiting is not limited (issue #35311).
49
-func TestStopContainerWithTimeout(t *testing.T) {
50
-	defer setupTest(t)()
51
-	client := request.NewAPIClient(t)
52
-	ctx := context.Background()
53
-
54
-	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
55
-	testData := []struct {
56
-		doc              string
57
-		timeout          int
58
-		expectedExitCode int
59
-	}{
60
-		// In case container is forcefully killed, 137 is returned,
61
-		// otherwise the exit code from the above script
62
-		{
63
-			"zero timeout: expect forceful container kill",
64
-			0, 137,
65
-		},
66
-		{
67
-			"too small timeout: expect forceful container kill",
68
-			1, 137,
69
-		},
70
-		{
71
-			"big enough timeout: expect graceful container stop",
72
-			3, 42,
73
-		},
74
-		{
75
-			"unlimited timeout: expect graceful container stop",
76
-			-1, 42,
77
-		},
78
-	}
79
-
80
-	for _, d := range testData {
81
-		d := d
82
-		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
83
-			t.Parallel()
84
-			id := container.Run(t, ctx, client, testCmd)
85
-
86
-			timeout := time.Duration(d.timeout) * time.Second
87
-			err := client.ContainerStop(ctx, id, &timeout)
88
-			assert.NilError(t, err)
89
-
90
-			poll.WaitOn(t, container.IsStopped(ctx, client, id),
91
-				poll.WithDelay(100*time.Millisecond))
92
-
93
-			inspect, err := client.ContainerInspect(ctx, id)
94
-			assert.NilError(t, err)
95
-			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
96
-		})
97
-	}
98
-}
99
-
100
-func TestDeleteDevicemapper(t *testing.T) {
101
-	skip.If(t, testEnv.DaemonInfo.Driver != "devicemapper")
102
-	skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run")
103
-
104
-	defer setupTest(t)()
105
-	client := request.NewAPIClient(t)
106
-	ctx := context.Background()
107
-
108
-	id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo"))
109
-
110
-	poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
111
-
112
-	inspect, err := client.ContainerInspect(ctx, id)
113
-	assert.NilError(t, err)
114
-
115
-	deviceID := inspect.GraphDriver.Data["DeviceId"]
116
-
117
-	// Find pool name from device name
118
-	deviceName := inspect.GraphDriver.Data["DeviceName"]
119
-	devicePrefix := deviceName[:strings.LastIndex(deviceName, "-")]
120
-	devicePool := fmt.Sprintf("/dev/mapper/%s-pool", devicePrefix)
121
-
122
-	result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
123
-	result.Assert(t, icmd.Success)
124
-
125
-	err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
126
-	assert.NilError(t, err)
127
-}
128 45
new file mode 100644
... ...
@@ -0,0 +1,69 @@
0
+package container // import "github.com/docker/docker/integration/container"
1
+
2
+import (
3
+	"context"
4
+	"strconv"
5
+	"testing"
6
+	"time"
7
+
8
+	"github.com/docker/docker/integration/internal/container"
9
+	"github.com/docker/docker/internal/test/request"
10
+	"gotest.tools/assert"
11
+	"gotest.tools/poll"
12
+	"gotest.tools/skip"
13
+)
14
+
15
+// TestStopContainerWithTimeout checks that ContainerStop with
16
+// a timeout works as documented, i.e. in case of negative timeout
17
+// waiting is not limited (issue #35311).
18
+func TestStopContainerWithTimeout(t *testing.T) {
19
+	skip.If(t, testEnv.OSType == "windows")
20
+	defer setupTest(t)()
21
+	client := request.NewAPIClient(t)
22
+	ctx := context.Background()
23
+
24
+	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
25
+	testData := []struct {
26
+		doc              string
27
+		timeout          int
28
+		expectedExitCode int
29
+	}{
30
+		// In case container is forcefully killed, 137 is returned,
31
+		// otherwise the exit code from the above script
32
+		{
33
+			"zero timeout: expect forceful container kill",
34
+			1, 0x40010004,
35
+		},
36
+		{
37
+			"too small timeout: expect forceful container kill",
38
+			2, 0x40010004,
39
+		},
40
+		{
41
+			"big enough timeout: expect graceful container stop",
42
+			120, 42,
43
+		},
44
+		{
45
+			"unlimited timeout: expect graceful container stop",
46
+			-1, 42,
47
+		},
48
+	}
49
+
50
+	for _, d := range testData {
51
+		d := d
52
+		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
53
+			t.Parallel()
54
+			id := container.Run(t, ctx, client, testCmd)
55
+
56
+			timeout := time.Duration(d.timeout) * time.Second
57
+			err := client.ContainerStop(ctx, id, &timeout)
58
+			assert.NilError(t, err)
59
+
60
+			poll.WaitOn(t, container.IsStopped(ctx, client, id),
61
+				poll.WithDelay(100*time.Millisecond))
62
+
63
+			inspect, err := client.ContainerInspect(ctx, id)
64
+			assert.NilError(t, err)
65
+			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
66
+		})
67
+	}
68
+}
... ...
@@ -11,7 +11,7 @@ import (
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/internal/test/request"
13 13
 	"github.com/docker/docker/internal/testutil"
14
-	"github.com/gotestyourself/gotestyourself/skip"
14
+	"gotest.tools/skip"
15 15
 )
16 16
 
17 17
 // Ensure we don't regress on CVE-2017-14992.
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"github.com/docker/docker/internal/testutil"
10 10
 	"gotest.tools/assert"
11 11
 	is "gotest.tools/assert/cmp"
12
+	"gotest.tools/skip"
12 13
 )
13 14
 
14 15
 // tagging a named image in a new unprefixed repo should work
... ...
@@ -95,6 +96,7 @@ func TestTagExistedNameWithoutForce(t *testing.T) {
95 95
 // ensure tagging using official names works
96 96
 // ensure all tags result in the same name
97 97
 func TestTagOfficialNames(t *testing.T) {
98
+	skip.If(t, testEnv.OSType == "windows")
98 99
 	defer setupTest(t)()
99 100
 	client := request.NewAPIClient(t)
100 101
 	ctx := context.Background()
... ...
@@ -5,9 +5,6 @@ import (
5 5
 	"strings"
6 6
 	"testing"
7 7
 	"time"
8
-
9
-	"github.com/docker/docker/pkg/parsers/kernel"
10
-	"gotest.tools/icmd"
11 8
 )
12 9
 
13 10
 // HasHubConnectivity checks to see if https://hub.docker.com is
... ...
@@ -28,26 +25,3 @@ func HasHubConnectivity(t *testing.T) bool {
28 28
 	}
29 29
 	return err == nil
30 30
 }
31
-
32
-func overlayFSSupported() bool {
33
-	result := icmd.RunCommand("/bin/sh", "-c", "cat /proc/filesystems")
34
-	if result.Error != nil {
35
-		return false
36
-	}
37
-	return strings.Contains(result.Combined(), "overlay\n")
38
-}
39
-
40
-// Overlay2Supported returns true if the current system supports overlay2 as graphdriver
41
-func Overlay2Supported(kernelVersion string) bool {
42
-	if !overlayFSSupported() {
43
-		return false
44
-	}
45
-
46
-	daemonV, err := kernel.ParseRelease(kernelVersion)
47
-	if err != nil {
48
-		return false
49
-	}
50
-	requiredV := kernel.VersionInfo{Kernel: 4}
51
-	return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
52
-
53
-}
54 31
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+package requirement // import "github.com/docker/docker/integration/internal/requirement"
1
+
2
+import (
3
+	"strings"
4
+
5
+	"github.com/docker/docker/pkg/parsers/kernel"
6
+	"gotest.tools/icmd"
7
+)
8
+
9
+func overlayFSSupported() bool {
10
+	result := icmd.RunCommand("/bin/sh", "-c", "cat /proc/filesystems")
11
+	if result.Error != nil {
12
+		return false
13
+	}
14
+	return strings.Contains(result.Combined(), "overlay\n")
15
+}
16
+
17
+// Overlay2Supported returns true if the current system supports overlay2 as graphdriver
18
+func Overlay2Supported(kernelVersion string) bool {
19
+	if !overlayFSSupported() {
20
+		return false
21
+	}
22
+
23
+	daemonV, err := kernel.ParseRelease(kernelVersion)
24
+	if err != nil {
25
+		return false
26
+	}
27
+	requiredV := kernel.VersionInfo{Kernel: 4}
28
+	return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
29
+
30
+}
0 31
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+// +build windows
1
+
2
+package requirement // import "github.com/docker/docker/integration/internal/requirement"
3
+
4
+func overlayFSSupported() bool {
5
+	return false
6
+}
7
+
8
+// Overlay2Supported returns true if the current system supports overlay2 as graphdriver
9
+func Overlay2Supported(kernelVersion string) bool {
10
+	return false
11
+}
... ...
@@ -44,6 +44,7 @@ func createAmbiguousNetworks(t *testing.T) (string, string, string) {
44 44
 	return testNet, idPrefixNet, fullIDNet
45 45
 }
46 46
 
47
+// TestNetworkCreateDelete tests creation and deletion of a network.
47 48
 func TestNetworkCreateDelete(t *testing.T) {
48 49
 	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
49 50
 	defer setupTest(t)()
50 51
new file mode 100644
... ...
@@ -0,0 +1,49 @@
0
+package network
1
+
2
+import (
3
+	"context"
4
+	"fmt"
5
+	"os"
6
+
7
+	"github.com/docker/docker/api/types"
8
+	"github.com/docker/docker/client"
9
+	"gotest.tools/assert/cmp"
10
+)
11
+
12
+// IsNetworkAvailable provides a comparison to check if a docker network is available
13
+func IsNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison {
14
+	return func() cmp.Result {
15
+		networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
16
+		if err != nil {
17
+			return cmp.ResultFromError(err)
18
+		}
19
+		for _, network := range networks {
20
+			if network.Name == name {
21
+				return cmp.ResultSuccess
22
+			}
23
+		}
24
+		return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name))
25
+	}
26
+}
27
+
28
+// IsNetworkNotAvailable provides a comparison to check if a docker network is not available
29
+func IsNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison {
30
+	return func() cmp.Result {
31
+		networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
32
+		if err != nil {
33
+			return cmp.ResultFromError(err)
34
+		}
35
+		for _, network := range networks {
36
+			if network.Name == name {
37
+				return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name))
38
+			}
39
+		}
40
+		return cmp.ResultSuccess
41
+	}
42
+}
43
+
44
+// IsUserNamespace returns whether the user namespace remapping is enabled
45
+func IsUserNamespace() bool {
46
+	root := os.Getenv("DOCKER_REMAP_ROOT")
47
+	return root != ""
48
+}
... ...
@@ -19,7 +19,6 @@ import (
19 19
 
20 20
 func TestDockerNetworkMacvlanPersistance(t *testing.T) {
21 21
 	// verify the driver automatically provisions the 802.1q link (dm-dummy0.60)
22
-	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
23 22
 	skip.If(t, testEnv.IsRemoteDaemon())
24 23
 	skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan")
25 24
 
... ...
@@ -44,7 +43,6 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) {
44 44
 }
45 45
 
46 46
 func TestDockerNetworkMacvlan(t *testing.T) {
47
-	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
48 47
 	skip.If(t, testEnv.IsRemoteDaemon())
49 48
 	skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan")
50 49
 
... ...
@@ -26,6 +26,7 @@ func delInterface(t *testing.T, ifName string) {
26 26
 }
27 27
 
28 28
 func TestDaemonRestartWithLiveRestore(t *testing.T) {
29
+	skip.If(t, testEnv.OSType == "windows")
29 30
 	skip.If(t, testEnv.IsRemoteDaemon())
30 31
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
31 32
 	d := daemon.New(t)
... ...
@@ -46,6 +47,7 @@ func TestDaemonRestartWithLiveRestore(t *testing.T) {
46 46
 }
47 47
 
48 48
 func TestDaemonDefaultNetworkPools(t *testing.T) {
49
+	skip.If(t, testEnv.OSType == "windows")
49 50
 	// Remove docker0 bridge and the start daemon defining the predefined address pools
50 51
 	skip.If(t, testEnv.IsRemoteDaemon())
51 52
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
... ...
@@ -87,6 +89,7 @@ func TestDaemonDefaultNetworkPools(t *testing.T) {
87 87
 }
88 88
 
89 89
 func TestDaemonRestartWithExistingNetwork(t *testing.T) {
90
+	skip.If(t, testEnv.OSType == "windows")
90 91
 	skip.If(t, testEnv.IsRemoteDaemon())
91 92
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
92 93
 	defaultNetworkBridge := "docker0"
... ...
@@ -119,6 +122,7 @@ func TestDaemonRestartWithExistingNetwork(t *testing.T) {
119 119
 }
120 120
 
121 121
 func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
122
+	skip.If(t, testEnv.OSType == "windows")
122 123
 	skip.If(t, testEnv.IsRemoteDaemon())
123 124
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
124 125
 	defaultNetworkBridge := "docker0"
... ...
@@ -167,6 +171,7 @@ func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
167 167
 }
168 168
 
169 169
 func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
170
+	skip.If(t, testEnv.OSType == "windows")
170 171
 	skip.If(t, testEnv.IsRemoteDaemon())
171 172
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
172 173
 	defaultNetworkBridge := "docker0"
... ...
@@ -317,6 +322,7 @@ func noServices(client client.ServiceAPIClient) func(log poll.LogT) poll.Result
317 317
 }
318 318
 
319 319
 func TestServiceWithDefaultAddressPoolInit(t *testing.T) {
320
+	skip.If(t, testEnv.OSType == "windows")
320 321
 	defer setupTest(t)()
321 322
 	var ops = []func(*daemon.Daemon){}
322 323
 	ipAddr := []string{"20.20.0.0/16"}
323 324
new file mode 100644
... ...
@@ -0,0 +1,79 @@
0
+package logging
1
+
2
+import (
3
+	"bufio"
4
+	"context"
5
+	"os"
6
+	"strings"
7
+	"testing"
8
+	"time"
9
+
10
+	"github.com/docker/docker/api/types"
11
+	"github.com/docker/docker/integration/internal/container"
12
+	"github.com/docker/docker/internal/test/daemon"
13
+	"gotest.tools/assert"
14
+	"gotest.tools/skip"
15
+)
16
+
17
+func TestContinueAfterPluginCrash(t *testing.T) {
18
+	skip.If(t, testEnv.IsRemoteDaemon(), "test requires daemon on the same host")
19
+	t.Parallel()
20
+
21
+	d := daemon.New(t)
22
+	d.StartWithBusybox(t, "--iptables=false", "--init")
23
+	defer d.Stop(t)
24
+
25
+	client := d.NewClientT(t)
26
+	createPlugin(t, client, "test", "close_on_start", asLogDriver)
27
+
28
+	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
29
+	assert.Assert(t, client.PluginEnable(ctx, "test", types.PluginEnableOptions{Timeout: 30}))
30
+	cancel()
31
+	defer client.PluginRemove(context.Background(), "test", types.PluginRemoveOptions{Force: true})
32
+
33
+	ctx, cancel = context.WithTimeout(context.Background(), 60*time.Second)
34
+
35
+	id := container.Run(t, ctx, client,
36
+		container.WithAutoRemove,
37
+		container.WithLogDriver("test"),
38
+		container.WithCmd(
39
+			"/bin/sh", "-c", "while true; do sleep 1; echo hello; done",
40
+		),
41
+	)
42
+	cancel()
43
+	defer client.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{Force: true})
44
+
45
+	// Attach to the container to make sure it's written a few times to stdout
46
+	attach, err := client.ContainerAttach(context.Background(), id, types.ContainerAttachOptions{Stream: true, Stdout: true})
47
+	assert.Assert(t, err)
48
+
49
+	chErr := make(chan error)
50
+	go func() {
51
+		defer close(chErr)
52
+		rdr := bufio.NewReader(attach.Reader)
53
+		for i := 0; i < 5; i++ {
54
+			_, _, err := rdr.ReadLine()
55
+			if err != nil {
56
+				chErr <- err
57
+				return
58
+			}
59
+		}
60
+	}()
61
+
62
+	select {
63
+	case err := <-chErr:
64
+		assert.Assert(t, err)
65
+	case <-time.After(60 * time.Second):
66
+		t.Fatal("timeout waiting for container i/o")
67
+	}
68
+
69
+	// check daemon logs for "broken pipe"
70
+	// TODO(@cpuguy83): This is horribly hacky but is the only way to really test this case right now.
71
+	// It would be nice if there was a way to know that a broken pipe has occurred without looking through the logs.
72
+	log, err := os.Open(d.LogFileName())
73
+	assert.Assert(t, err)
74
+	scanner := bufio.NewScanner(log)
75
+	for scanner.Scan() {
76
+		assert.Assert(t, !strings.Contains(scanner.Text(), "broken pipe"))
77
+	}
78
+}
0 79
deleted file mode 100644
... ...
@@ -1,79 +0,0 @@
1
-package logging
2
-
3
-import (
4
-	"bufio"
5
-	"context"
6
-	"os"
7
-	"strings"
8
-	"testing"
9
-	"time"
10
-
11
-	"github.com/docker/docker/api/types"
12
-	"github.com/docker/docker/integration/internal/container"
13
-	"github.com/docker/docker/internal/test/daemon"
14
-	"gotest.tools/assert"
15
-	"gotest.tools/skip"
16
-)
17
-
18
-func TestContinueAfterPluginCrash(t *testing.T) {
19
-	skip.If(t, testEnv.IsRemoteDaemon(), "test requires daemon on the same host")
20
-	t.Parallel()
21
-
22
-	d := daemon.New(t)
23
-	d.StartWithBusybox(t, "--iptables=false", "--init")
24
-	defer d.Stop(t)
25
-
26
-	client := d.NewClientT(t)
27
-	createPlugin(t, client, "test", "close_on_start", asLogDriver)
28
-
29
-	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
30
-	assert.Assert(t, client.PluginEnable(ctx, "test", types.PluginEnableOptions{Timeout: 30}))
31
-	cancel()
32
-	defer client.PluginRemove(context.Background(), "test", types.PluginRemoveOptions{Force: true})
33
-
34
-	ctx, cancel = context.WithTimeout(context.Background(), 60*time.Second)
35
-
36
-	id := container.Run(t, ctx, client,
37
-		container.WithAutoRemove,
38
-		container.WithLogDriver("test"),
39
-		container.WithCmd(
40
-			"/bin/sh", "-c", "while true; do sleep 1; echo hello; done",
41
-		),
42
-	)
43
-	cancel()
44
-	defer client.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{Force: true})
45
-
46
-	// Attach to the container to make sure it's written a few times to stdout
47
-	attach, err := client.ContainerAttach(context.Background(), id, types.ContainerAttachOptions{Stream: true, Stdout: true})
48
-	assert.Assert(t, err)
49
-
50
-	chErr := make(chan error)
51
-	go func() {
52
-		defer close(chErr)
53
-		rdr := bufio.NewReader(attach.Reader)
54
-		for i := 0; i < 5; i++ {
55
-			_, _, err := rdr.ReadLine()
56
-			if err != nil {
57
-				chErr <- err
58
-				return
59
-			}
60
-		}
61
-	}()
62
-
63
-	select {
64
-	case err := <-chErr:
65
-		assert.Assert(t, err)
66
-	case <-time.After(60 * time.Second):
67
-		t.Fatal("timeout waiting for container i/o")
68
-	}
69
-
70
-	// check daemon logs for "broken pipe"
71
-	// TODO(@cpuguy83): This is horribly hacky but is the only way to really test this case right now.
72
-	// It would be nice if there was a way to know that a broken pipe has occurred without looking through the logs.
73
-	log, err := os.Open(d.LogFileName())
74
-	assert.Assert(t, err)
75
-	scanner := bufio.NewScanner(log)
76
-	for scanner.Scan() {
77
-		assert.Assert(t, !strings.Contains(scanner.Text(), "broken pipe"))
78
-	}
79
-}
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"github.com/docker/docker/internal/test/request"
10 10
 	"gotest.tools/assert"
11 11
 	is "gotest.tools/assert/cmp"
12
+	"gotest.tools/skip"
12 13
 )
13 14
 
14 15
 func TestInfoAPI(t *testing.T) {
... ...
@@ -43,6 +44,7 @@ func TestInfoAPI(t *testing.T) {
43 43
 }
44 44
 
45 45
 func TestInfoAPIWarnings(t *testing.T) {
46
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
46 47
 	d := daemon.New(t)
47 48
 
48 49
 	client, err := d.NewClient()