Browse Source

Enabling Windows integration tests

Signed-off-by: Salahuddin Khan <salah@docker.com>
(cherry picked from commit 4c8b1fd5a2803e393ad1296692533b7b5c727918)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Salahuddin Khan 7 years ago
parent
commit
37cb9e7300

+ 353 - 265
hack/ci/windowsRS1.ps1

@@ -1,9 +1,19 @@
+# WARNING WARNING WARNING - DO NOT EDIT THIS FILE IN JENKINS DIRECTLY.
+# SUBMIT A PR TO https://github.com/jhowardmsft/docker-w2wCIScripts/blob/master/runCI/executeCI.ps1,
+# AND MAKE SURE https://github.com/jhowardmsft/docker-w2wCIScripts/blob/master/runCI/Invoke-DockerCI.ps1
+# ISN'T BROKEN!!!!!!! VALIDATE USING A TEST CONTEXT IN JENKINS. THEN COPY/PASTE INTO JENKINS PRODUCTION.
+#
 # Jenkins CI scripts for Windows to Windows CI (Powershell Version)
 # Jenkins CI scripts for Windows to Windows CI (Powershell Version)
 # By John Howard (@jhowardmsft) January 2016 - bash version; July 2016 Ported to PowerShell
 # By John Howard (@jhowardmsft) January 2016 - bash version; July 2016 Ported to PowerShell
 
 
 $ErrorActionPreference = 'Stop'
 $ErrorActionPreference = 'Stop'
 $StartTime=Get-Date
 $StartTime=Get-Date
-#$env:DOCKER_DUT_DEBUG="yes" # Comment out to not be in debug mode
+
+# Put up top to be blindingly obvious. The production jenkins.dockerproject.org Linux-container 
+# CI job is "Docker-PRs-LoW-RS3". Force into LCOW mode for this run, or not.
+if ($env:BUILD_TAG -match "-LoW") { $env:LCOW_MODE=1 }
+if ($env:BUILD_TAG -match "-WoW") { $env:LCOW_MODE="" }
+
 
 
 # -------------------------------------------------------------------------------------------
 # -------------------------------------------------------------------------------------------
 # When executed, we rely on four variables being set in the environment:
 # When executed, we rely on four variables being set in the environment:
@@ -17,7 +27,7 @@ $StartTime=Get-Date
 #
 #
 #    SOURCES_SUBDIR      is the top level directory under SOURCES_DRIVE where the
 #    SOURCES_SUBDIR      is the top level directory under SOURCES_DRIVE where the
 #                        sources are cloned to. There are no platform semantics in this
 #                        sources are cloned to. There are no platform semantics in this
-#                        as it does not include slashes.
+#                        as it does not include slashes. 
 #                        For example 'gopath'
 #                        For example 'gopath'
 #
 #
 #                        Based on the above examples, it would be expected that Jenkins
 #                        Based on the above examples, it would be expected that Jenkins
@@ -60,13 +70,19 @@ $StartTime=Get-Date
 #    SKIP_IMAGE_BUILD         if defined doesn't build the 'docker' image
 #    SKIP_IMAGE_BUILD         if defined doesn't build the 'docker' image
 #
 #
 #    INTEGRATION_IN_CONTAINER if defined, runs the integration tests from inside a container.
 #    INTEGRATION_IN_CONTAINER if defined, runs the integration tests from inside a container.
-#                             As of July 2016, there are known issues with this.
+#                             As of July 2016, there are known issues with this. 
 #
 #
 #    SKIP_ALL_CLEANUP         if defined, skips any cleanup at the start or end of the run
 #    SKIP_ALL_CLEANUP         if defined, skips any cleanup at the start or end of the run
 #
 #
 #    WINDOWS_BASE_IMAGE       if defined, uses that as the base image. Note that the
 #    WINDOWS_BASE_IMAGE       if defined, uses that as the base image. Note that the
 #                             docker integration tests are also coded to use the same
 #                             docker integration tests are also coded to use the same
 #                             environment variable, and if no set, defaults to microsoft/windowsservercore
 #                             environment variable, and if no set, defaults to microsoft/windowsservercore
+#
+#    LCOW_BASIC_MODE          if defined, does very basic LCOW verification. Ultimately we 
+#                             want to run the entire CI suite from docker, but that's a way off.
+#                            
+#    LCOW_MODE                if defined, runs the entire CI suite
+#                            
 # -------------------------------------------------------------------------------------------
 # -------------------------------------------------------------------------------------------
 #
 #
 # Jenkins Integration. Add a Windows Powershell build step as follows:
 # Jenkins Integration. Add a Windows Powershell build step as follows:
@@ -80,7 +96,7 @@ $StartTime=Get-Date
 #    try {
 #    try {
 #        Write-Host -ForegroundColor green "INFO: Downloading latest execution script..."
 #        Write-Host -ForegroundColor green "INFO: Downloading latest execution script..."
 #        $wc.Downloadfile($CISCRIPT_DEFAULT_LOCATION, $CISCRIPT_LOCAL_LOCATION)
 #        $wc.Downloadfile($CISCRIPT_DEFAULT_LOCATION, $CISCRIPT_LOCAL_LOCATION)
-#    }
+#    } 
 #    catch [System.Net.WebException]
 #    catch [System.Net.WebException]
 #    {
 #    {
 #        Throw ("Failed to download: $_")
 #        Throw ("Failed to download: $_")
@@ -88,9 +104,11 @@ $StartTime=Get-Date
 #    & $CISCRIPT_LOCAL_LOCATION
 #    & $CISCRIPT_LOCAL_LOCATION
 # -------------------------------------------------------------------------------------------
 # -------------------------------------------------------------------------------------------
 
 
-$SCRIPT_VER="10-May-2017 12:16 PDT"
+
+$SCRIPT_VER="28-Aug-2018 09:33 PDT" 
 $FinallyColour="Cyan"
 $FinallyColour="Cyan"
 
 
+#$env:DOCKER_DUT_DEBUG="yes" # Comment out to not be in debug mode
 #$env:SKIP_UNIT_TESTS="yes"
 #$env:SKIP_UNIT_TESTS="yes"
 #$env:SKIP_VALIDATION_TESTS="yes"
 #$env:SKIP_VALIDATION_TESTS="yes"
 #$env:SKIP_ZAP_DUT=""
 #$env:SKIP_ZAP_DUT=""
@@ -104,34 +122,35 @@ $FinallyColour="Cyan"
 
 
 Function Nuke-Everything {
 Function Nuke-Everything {
     $ErrorActionPreference = 'SilentlyContinue'
     $ErrorActionPreference = 'SilentlyContinue'
-    if ($env:SKIP_ALL_CLEANUP -ne $null) {
-        Write-Host -ForegroundColor Magenta "WARN: Skipping all cleanup"
-        return
-    }
 
 
     try {
     try {
-        Write-Host -ForegroundColor green "INFO: Nuke-Everything..."
-        $containerCount = ($(docker ps -aq | Measure-Object -line).Lines)
-        if (-not $LastExitCode -eq 0) {
-            Throw "ERROR: Failed to get container count from control daemon while nuking"
-        }
 
 
-        Write-Host -ForegroundColor green "INFO: Container count on control daemon to delete is $containerCount"
-        if ($(docker ps -aq | Measure-Object -line).Lines -gt 0) {
-            docker rm -f $(docker ps -aq)
-        }
-        $imageCount=($(docker images --format "{{.Repository}}:{{.ID}}" | `
-                        select-string -NotMatch "windowsservercore" | `
-                        select-string -NotMatch "nanoserver" | `
-                        select-string -NotMatch "docker" | `
-                        Measure-Object -line).Lines)
-        if ($imageCount -gt 0) {
-            Write-Host -Foregroundcolor green "INFO: Non-base image count on control daemon to delete is $imageCount"
-            docker rmi -f `
-                $(docker images --format "{{.Repository}}:{{.ID}}" | `
-                        select-string -NotMatch "windowsservercore" | `
-                        select-string -NotMatch "nanoserver" | `
-                        select-string -NotMatch "docker").ToString().Split(":")[1]
+        if ($env:SKIP_ALL_CLEANUP -eq $null) {
+            Write-Host -ForegroundColor green "INFO: Nuke-Everything..."
+            $containerCount = ($(docker ps -aq | Measure-Object -line).Lines) 
+            if (-not $LastExitCode -eq 0) {
+                Throw "ERROR: Failed to get container count from control daemon while nuking"
+            }
+
+            Write-Host -ForegroundColor green "INFO: Container count on control daemon to delete is $containerCount"
+            if ($(docker ps -aq | Measure-Object -line).Lines -gt 0) {
+                docker rm -f $(docker ps -aq)
+            }
+            $imageCount=($(docker images --format "{{.Repository}}:{{.ID}}" | `
+                            select-string -NotMatch "windowsservercore" | `
+                            select-string -NotMatch "nanoserver" | `
+                            select-string -NotMatch "docker" | `
+                            Measure-Object -line).Lines)
+            if ($imageCount -gt 0) {
+                Write-Host -Foregroundcolor green "INFO: Non-base image count on control daemon to delete is $imageCount"
+                docker rmi -f `
+                    $(docker images --format "{{.Repository}}:{{.ID}}" | `
+                            select-string -NotMatch "windowsservercore" | `
+                            select-string -NotMatch "nanoserver" | `
+                            select-string -NotMatch "docker").ToString().Split(":")[1]
+            }
+        } else {
+            Write-Host -ForegroundColor Magenta "WARN: Skipping cleanup of images and containers"
         }
         }
 
 
         # Kill any spurious daemons. The '-' is IMPORTANT otherwise will kill the control daemon!
         # Kill any spurious daemons. The '-' is IMPORTANT otherwise will kill the control daemon!
@@ -141,6 +160,18 @@ Function Nuke-Everything {
             Stop-Process -Id $p -Force -ErrorAction SilentlyContinue
             Stop-Process -Id $p -Force -ErrorAction SilentlyContinue
         }
         }
 
 
+        if ($pidFile -ne $Null) {
+            Write-Host "INFO: Tidying pidfile $pidfile"
+             if (Test-Path $pidFile) {
+                $p=Get-Content $pidFile -raw
+                if ($p -ne $null){
+                    Write-Host -ForegroundColor green "INFO: Stopping possible daemon pid $p"
+                    taskkill -f -t -pid $p
+                }
+                Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue
+            }
+        }
+
         Stop-Process -name "cc1" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
         Stop-Process -name "cc1" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
         Stop-Process -name "link" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
         Stop-Process -name "link" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
         Stop-Process -name "compile" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
         Stop-Process -name "compile" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
@@ -159,7 +190,7 @@ Function Nuke-Everything {
 
 
         # Delete the directory using our dangerous utility unless told not to
         # Delete the directory using our dangerous utility unless told not to
         if (Test-Path "$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR") {
         if (Test-Path "$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR") {
-            if ($env:SKIP_ZAP_DUT -eq $null) {
+            if (($env:SKIP_ZAP_DUT -ne $null) -or ($env:SKIP_ALL_CLEANUP -eq $null)) {
                 Write-Host -ForegroundColor Green "INFO: Nuking $env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR"
                 Write-Host -ForegroundColor Green "INFO: Nuking $env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR"
                 docker-ci-zap "-folder=$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR"
                 docker-ci-zap "-folder=$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR"
             } else {
             } else {
@@ -167,7 +198,7 @@ Function Nuke-Everything {
             }
             }
         }
         }
 
 
-        # RS1 Production Server workaround - Psched
+        # TODO: This should be able to be removed in August 2017 update. Only needed for RS1  Production Server workaround - Psched
         $reg = "HKLM:\System\CurrentControlSet\Services\Psched\Parameters\NdisAdapters"
         $reg = "HKLM:\System\CurrentControlSet\Services\Psched\Parameters\NdisAdapters"
         $count=(Get-ChildItem $reg | Measure-Object).Count
         $count=(Get-ChildItem $reg | Measure-Object).Count
         if ($count -gt 0) {
         if ($count -gt 0) {
@@ -180,7 +211,7 @@ Function Nuke-Everything {
             }
             }
         }
         }
 
 
-        # RS1 Production Server workaround - WFPLWFS
+        # TODO: This should be able to be removed in August 2017 update. Only needed for RS1
         $reg = "HKLM:\System\CurrentControlSet\Services\WFPLWFS\Parameters\NdisAdapters"
         $reg = "HKLM:\System\CurrentControlSet\Services\WFPLWFS\Parameters\NdisAdapters"
         $count=(Get-ChildItem $reg | Measure-Object).Count
         $count=(Get-ChildItem $reg | Measure-Object).Count
         if ($count -gt 0) {
         if ($count -gt 0) {
@@ -207,8 +238,8 @@ Try {
     $origGOPATH="$env:GOPATH"        # So we can restore it at the end
     $origGOPATH="$env:GOPATH"        # So we can restore it at the end
 
 
     # Turn off progress bars
     # Turn off progress bars
-    $origProgressPreference=$global:ProgressPreference
-    $global:ProgressPreference='SilentlyContinue'
+	$origProgressPreference=$global:ProgressPreference
+	$global:ProgressPreference='SilentlyContinue'
 
 
     # Git version
     # Git version
     Write-Host  -ForegroundColor Green "INFO: Running $(git version)"
     Write-Host  -ForegroundColor Green "INFO: Running $(git version)"
@@ -248,7 +279,6 @@ Try {
     # SOURCES_DRIVE\SOURCES_SUBDIR must be a directory and exist
     # SOURCES_DRIVE\SOURCES_SUBDIR must be a directory and exist
     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" }
     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" }
 
 
-
     # Create the TESTRUN_DRIVE\TESTRUN_SUBDIR if it does not already exist
     # Create the TESTRUN_DRIVE\TESTRUN_SUBDIR if it does not already exist
     New-Item -ItemType Directory -Force -Path "$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR" -ErrorAction SilentlyContinue | Out-Null
     New-Item -ItemType Directory -Force -Path "$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR" -ErrorAction SilentlyContinue | Out-Null
 
 
@@ -266,12 +296,12 @@ Try {
 
 
     # Make sure we are in repo
     # Make sure we are in repo
     if (-not (Test-Path -PathType Leaf -Path ".\Dockerfile.windows")) {
     if (-not (Test-Path -PathType Leaf -Path ".\Dockerfile.windows")) {
-        Throw "$(pwd) does not container Dockerfile.Windows!"
+        Throw "$(pwd) does not contain Dockerfile.windows!"
     }
     }
     Write-Host  -ForegroundColor Green "INFO: docker/docker repository was found"
     Write-Host  -ForegroundColor Green "INFO: docker/docker repository was found"
 
 
     # Make sure microsoft/windowsservercore:latest image is installed in the control daemon. On public CI machines, windowsservercore.tar and nanoserver.tar
     # Make sure microsoft/windowsservercore:latest image is installed in the control daemon. On public CI machines, windowsservercore.tar and nanoserver.tar
-    # are pre-baked and tagged appropriately in the c:\baseimages directory, and can be directly loaded.
+    # are pre-baked and tagged appropriately in the c:\baseimages directory, and can be directly loaded. 
     # Note - this script will only work on 10B (Oct 2016) or later machines! Not 9D or previous due to image tagging assumptions.
     # Note - this script will only work on 10B (Oct 2016) or later machines! Not 9D or previous due to image tagging assumptions.
     #
     #
     # 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
     # 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 {
         # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
         # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
         # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
         # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
         if (Test-Path $("$env:SOURCES_DRIVE`:\baseimages\"+$ControlDaemonBaseImage+".tar")) {
         if (Test-Path $("$env:SOURCES_DRIVE`:\baseimages\"+$ControlDaemonBaseImage+".tar")) {
-
-            # An optimization for CI servers to copy it to the D: drive which is an SSD.
-            if ($env:SOURCES_DRIVE -ne $env:TESTRUN_DRIVE) {
-                $readBaseFrom=$env:TESTRUN_DRIVE
-                if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages")) {
-                    New-Item "$env:TESTRUN_DRIVE`:\baseimages" -type directory | Out-Null
-                }
-                if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\windowsservercore.tar")) {
-                    if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar") {
-                        Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar to $env:TESTRUN_DRIVE`:\baseimages"
-                        Copy-Item "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar" "$env:TESTRUN_DRIVE`:\baseimages"
-                    }
-                }
-                if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\nanoserver.tar")) {
-                    if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar") {
-                        Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\nanoserver.tar to $env:TESTRUN_DRIVE`:\baseimages"
-                        Copy-Item "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar" "$env:TESTRUN_DRIVE`:\baseimages"
-                    }
-                }
-                $readBaseFrom=$env:TESTRUN_DRIVE
-            }
-
+		
+			# An optimization for CI servers to copy it to the D: drive which is an SSD.
+			if ($env:SOURCES_DRIVE -ne $env:TESTRUN_DRIVE) {
+				$readBaseFrom=$env:TESTRUN_DRIVE
+				if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages")) {
+					New-Item "$env:TESTRUN_DRIVE`:\baseimages" -type directory | Out-Null
+				}
+				if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\windowsservercore.tar")) {
+					if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar") {
+						Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar to $env:TESTRUN_DRIVE`:\baseimages"
+						Copy-Item "$env:SOURCES_DRIVE`:\baseimages\windowsservercore.tar" "$env:TESTRUN_DRIVE`:\baseimages"
+					}
+				}
+				if (!(Test-Path "$env:TESTRUN_DRIVE`:\baseimages\nanoserver.tar")) {
+					if (Test-Path "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar") {
+						Write-Host -ForegroundColor Green "INFO: Optimisation - copying $env:SOURCES_DRIVE`:\baseimages\nanoserver.tar to $env:TESTRUN_DRIVE`:\baseimages"
+						Copy-Item "$env:SOURCES_DRIVE`:\baseimages\nanoserver.tar" "$env:TESTRUN_DRIVE`:\baseimages"
+					}
+				}
+				$readBaseFrom=$env:TESTRUN_DRIVE
+			}
+		
             Write-Host  -ForegroundColor Green "INFO: Loading"$ControlDaemonBaseImage".tar from disk. This may take some time..."
             Write-Host  -ForegroundColor Green "INFO: Loading"$ControlDaemonBaseImage".tar from disk. This may take some time..."
             $ErrorActionPreference = "SilentlyContinue"
             $ErrorActionPreference = "SilentlyContinue"
             docker load -i $("$readBaseFrom`:\baseimages\"+$ControlDaemonBaseImage+".tar")
             docker load -i $("$readBaseFrom`:\baseimages\"+$ControlDaemonBaseImage+".tar")
@@ -346,14 +376,14 @@ Try {
     docker version
     docker version
     $ErrorActionPreference = "Stop"
     $ErrorActionPreference = "Stop"
     if (-not($LastExitCode -eq 0)) {
     if (-not($LastExitCode -eq 0)) {
-        Write-Host
+        Write-Host 
         Write-Host  -ForegroundColor Green "---------------------------------------------------------------------------"
         Write-Host  -ForegroundColor Green "---------------------------------------------------------------------------"
         Write-Host  -ForegroundColor Green " Failed to get a response from the control daemon. It may be down."
         Write-Host  -ForegroundColor Green " Failed to get a response from the control daemon. It may be down."
-        Write-Host  -ForegroundColor Green " Try re-running this CI job, or ask on #docker-dev or #docker-maintainers"
-        Write-Host  -ForegroundColor Green " to see if the the daemon is running. Also check the nssm configuration."
+        Write-Host  -ForegroundColor Green " Try re-running this CI job, or ask on #docker-maintainers on docker slack"
+        Write-Host  -ForegroundColor Green " to see if the the daemon is running. Also check the service configuration."
         Write-Host  -ForegroundColor Green " DOCKER_HOST is set to $DOCKER_HOST."
         Write-Host  -ForegroundColor Green " DOCKER_HOST is set to $DOCKER_HOST."
         Write-Host  -ForegroundColor Green "---------------------------------------------------------------------------"
         Write-Host  -ForegroundColor Green "---------------------------------------------------------------------------"
-        Write-Host
+        Write-Host 
         Throw "ERROR: The control daemon does not appear to be running."
         Throw "ERROR: The control daemon does not appear to be running."
     }
     }
     Write-Host
     Write-Host
@@ -382,7 +412,7 @@ Try {
     Nuke-Everything
     Nuke-Everything
     cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker"
     cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker"
 
 
-    # Redirect to a temporary location.
+    # Redirect to a temporary location. 
     $TEMPORIG=$env:TEMP
     $TEMPORIG=$env:TEMP
     $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH"
     $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH"
     $env:LOCALAPPDATA="$TEMP\localappdata"
     $env:LOCALAPPDATA="$TEMP\localappdata"
@@ -401,8 +431,23 @@ Try {
     Write-Host -ForegroundColor Green "INFO: Location for testing is $env:TEMP"
     Write-Host -ForegroundColor Green "INFO: Location for testing is $env:TEMP"
 
 
     # CI Integrity check - ensure Dockerfile.windows and Dockerfile go versions match
     # CI Integrity check - ensure Dockerfile.windows and Dockerfile go versions match
-    $goVersionDockerfileWindows=$(Get-Content ".\Dockerfile.windows" | Select-String "ENV GO_VERSION").ToString().Replace("ENV GO_VERSION=","").Replace("\","").Replace("``","").Trim()
-    $goVersionDockerfile=$(Get-Content ".\Dockerfile" | Select-String "ENV GO_VERSION").ToString().Split(" ")[2]
+    $goVersionDockerfileWindows=$(Get-Content ".\Dockerfile.windows" | Select-String "^ENV GO_VERSION").ToString().Replace("ENV GO_VERSION=","").Replace("\","").Replace("``","").Trim()
+    $goVersionDockerfile=$(Get-Content ".\Dockerfile" | Select-String "^ENV GO_VERSION")
+    
+    # As of go 1.11, Dockerfile changed to be in the format like "FROM golang:1.11.0 AS base".
+    # If a version number ends with .0 (as in 1.11.0, a convention used in golang docker
+    # image versions), it needs to be removed (i.e. "1.11.0" becomes "1.11").
+    if ($goVersionDockerfile -eq $Null) {
+        $goVersionDockerfile=$(Get-Content ".\Dockerfile" | Select-String "^FROM golang:")
+        if ($goVersionDockerfile -ne $Null) {
+            $goVersionDockerfile = $goVersionDockerfile.ToString().Split(" ")[1].Split(":")[1] -replace '\.0$',''
+        }
+    } else {
+        $goVersionDockerfile = $goVersionDockerfile.ToString().Split(" ")[2]
+    }
+    if ($goVersionDockerfile -eq $Null) {
+        Throw "ERROR: Failed to extract golang version from Dockerfile"
+    }
     Write-Host  -ForegroundColor Green "INFO: Validating GOLang consistency in Dockerfile.windows..."
     Write-Host  -ForegroundColor Green "INFO: Validating GOLang consistency in Dockerfile.windows..."
     if (-not ($goVersionDockerfile -eq $goVersionDockerfileWindows)) {
     if (-not ($goVersionDockerfile -eq $goVersionDockerfileWindows)) {
         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"
         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 {
         Write-Host -ForegroundColor Magenta "WARN: Skipping building the docker image"
         Write-Host -ForegroundColor Magenta "WARN: Skipping building the docker image"
     }
     }
 
 
-    # DON'T THINK THIS IS USED ANYMORE.... $v=$(Get-Content ".\VERSION" -raw).ToString().Replace("`n","").Trim()
+    # Following at the moment must be docker\docker as it's dictated by dockerfile.Windows
     $contPath="$COMMITHASH`:c`:\go\src\github.com\docker\docker\bundles"
     $contPath="$COMMITHASH`:c`:\go\src\github.com\docker\docker\bundles"
 
 
     # After https://github.com/docker/docker/pull/30290, .git was added to .dockerignore. Therefore
     # After https://github.com/docker/docker/pull/30290, .git was added to .dockerignore. Therefore
@@ -446,7 +491,7 @@ Try {
             git status --porcelain --untracked-files=no | Write-Warning
             git status --porcelain --untracked-files=no | Write-Warning
              Write-Host ""
              Write-Host ""
         }
         }
-        $Duration=$(Measure-Command {docker run --name $COMMITHASH -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -Binary | Out-Host })
+        $Duration=$(Measure-Command {docker run --name $COMMITHASH -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -Daemon -Client | Out-Host })
         $ErrorActionPreference = "Stop"
         $ErrorActionPreference = "Stop"
         if (-not($LastExitCode -eq 0)) {
         if (-not($LastExitCode -eq 0)) {
             Throw "ERROR: Failed to build binary"
             Throw "ERROR: Failed to build binary"
@@ -498,7 +543,7 @@ Try {
         # Extract the golang installer
         # Extract the golang installer
         Write-Host -ForegroundColor Green "INFO: Extracting go.zip to $env:TEMP\go"
         Write-Host -ForegroundColor Green "INFO: Extracting go.zip to $env:TEMP\go"
         $Duration=$(Measure-Command { Expand-Archive $env:TEMP\installer\go.zip $env:TEMP -Force | Out-Null})
         $Duration=$(Measure-Command { Expand-Archive $env:TEMP\installer\go.zip $env:TEMP -Force | Out-Null})
-        Write-Host  -ForegroundColor Green "INFO: Extraction ended at $(Get-Date). Duration`:$Duration"
+        Write-Host  -ForegroundColor Green "INFO: Extraction ended at $(Get-Date). Duration`:$Duration"    
     } else {
     } else {
         Write-Host -ForegroundColor Magenta "WARN: Skipping copying and extracting golang from the image"
         Write-Host -ForegroundColor Magenta "WARN: Skipping copying and extracting golang from the image"
     }
     }
@@ -514,7 +559,7 @@ Try {
     # Set the GOROOT to be our copy of go from the image
     # Set the GOROOT to be our copy of go from the image
     $env:GOROOT="$env:TEMP\go"
     $env:GOROOT="$env:TEMP\go"
     Write-Host -ForegroundColor Green "INFO: $(go version)"
     Write-Host -ForegroundColor Green "INFO: $(go version)"
-
+    
     # Work out the the -H parameter for the daemon under test (DASHH_DUT) and client under test (DASHH_CUT)
     # Work out the the -H parameter for the daemon under test (DASHH_DUT) and client under test (DASHH_CUT)
     #$DASHH_DUT="npipe:////./pipe/$COMMITHASH" # Can't do remote named pipe
     #$DASHH_DUT="npipe:////./pipe/$COMMITHASH" # Can't do remote named pipe
     #$ip = (resolve-dnsname $env:COMPUTERNAME -type A -NoHostsFile -LlmnrNetbiosOnly).IPAddress # Useful to tie down
     #$ip = (resolve-dnsname $env:COMPUTERNAME -type A -NoHostsFile -LlmnrNetbiosOnly).IPAddress # Useful to tie down
@@ -524,9 +569,12 @@ Try {
     # Arguments for the daemon under test
     # Arguments for the daemon under test
     $dutArgs=@()
     $dutArgs=@()
     $dutArgs += "-H $DASHH_DUT"
     $dutArgs += "-H $DASHH_DUT"
-    $dutArgs += "--graph $env:TEMP\daemon"
+    $dutArgs += "--data-root $env:TEMP\daemon"
     $dutArgs += "--pidfile $env:TEMP\docker.pid"
     $dutArgs += "--pidfile $env:TEMP\docker.pid"
 
 
+    # Save the PID file so we can nuke it if set
+    $pidFile="$env:TEMP\docker.pid"
+
     # Arguments: Are we starting the daemon under test in debug mode?
     # Arguments: Are we starting the daemon under test in debug mode?
     if (-not ("$env:DOCKER_DUT_DEBUG" -eq "")) {
     if (-not ("$env:DOCKER_DUT_DEBUG" -eq "")) {
         Write-Host -ForegroundColor Green "INFO: Running the daemon under test in debug mode"
         Write-Host -ForegroundColor Green "INFO: Running the daemon under test in debug mode"
@@ -541,25 +589,36 @@ Try {
 
 
     # Start the daemon under test, ensuring everything is redirected to folders under $TEMP.
     # Start the daemon under test, ensuring everything is redirected to folders under $TEMP.
     # Important - we launch the -$COMMITHASH version so that we can kill it without
     # Important - we launch the -$COMMITHASH version so that we can kill it without
-    # killing the control daemon.
+    # killing the control daemon. 
     Write-Host -ForegroundColor Green "INFO: Starting a daemon under test..."
     Write-Host -ForegroundColor Green "INFO: Starting a daemon under test..."
     Write-Host -ForegroundColor Green "INFO: Args: $dutArgs"
     Write-Host -ForegroundColor Green "INFO: Args: $dutArgs"
     New-Item -ItemType Directory $env:TEMP\daemon -ErrorAction SilentlyContinue  | Out-Null
     New-Item -ItemType Directory $env:TEMP\daemon -ErrorAction SilentlyContinue  | Out-Null
 
 
+    # In LCOW mode, for now we need to set an environment variable before starting the daemon under test
+    if (($env:LCOW_MODE -ne $Null) -or ($env:LCOW_BASIC_MODE -ne $Null)) {
+        $env:LCOW_SUPPORTED=1
+    }
+
     # Cannot fathom why, but always writes to stderr....
     # Cannot fathom why, but always writes to stderr....
     Start-Process "$env:TEMP\binary\dockerd-$COMMITHASH" `
     Start-Process "$env:TEMP\binary\dockerd-$COMMITHASH" `
                   -ArgumentList $dutArgs `
                   -ArgumentList $dutArgs `
                   -RedirectStandardOutput "$env:TEMP\dut.out" `
                   -RedirectStandardOutput "$env:TEMP\dut.out" `
-                  -RedirectStandardError "$env:TEMP\dut.err"
+                  -RedirectStandardError "$env:TEMP\dut.err" 
     Write-Host -ForegroundColor Green "INFO: Process started successfully."
     Write-Host -ForegroundColor Green "INFO: Process started successfully."
     $daemonStarted=1
     $daemonStarted=1
 
 
+    # In LCOW mode, turn off that variable
+    if (($env:LCOW_MODE -ne $Null) -or ($env:LCOW_BASIC_MODE -ne $Null)) {
+        $env:LCOW_SUPPORTED=""
+    }
+
+
     # Start tailing the daemon under test if the command is installed
     # Start tailing the daemon under test if the command is installed
-    if ((Get-Command "tail" -ErrorAction SilentlyContinue) -ne $null) {
+    if ((Get-Command "tail" -ErrorAction SilentlyContinue) -ne $null) { 
         $tail = start-process "tail" -ArgumentList "-f $env:TEMP\dut.out" -ErrorAction SilentlyContinue
         $tail = start-process "tail" -ArgumentList "-f $env:TEMP\dut.out" -ErrorAction SilentlyContinue
     }
     }
 
 
-    # Verify we can get the daemon under test to respond
+    # Verify we can get the daemon under test to respond 
     $tries=20
     $tries=20
     Write-Host -ForegroundColor Green "INFO: Waiting for the daemon under test to start..."
     Write-Host -ForegroundColor Green "INFO: Waiting for the daemon under test to start..."
     while ($true) {
     while ($true) {
@@ -582,7 +641,7 @@ Try {
 
 
     # Provide the docker version of the daemon under test for debugging purposes.
     # Provide the docker version of the daemon under test for debugging purposes.
     Write-Host -ForegroundColor Green "INFO: Docker version of the daemon under test"
     Write-Host -ForegroundColor Green "INFO: Docker version of the daemon under test"
-    Write-Host
+    Write-Host 
     $ErrorActionPreference = "SilentlyContinue"
     $ErrorActionPreference = "SilentlyContinue"
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" version
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" version
     $ErrorActionPreference = "Stop"
     $ErrorActionPreference = "Stop"
@@ -594,7 +653,7 @@ Try {
 
 
     # Same as above but docker info
     # Same as above but docker info
     Write-Host -ForegroundColor Green "INFO: Docker info of the daemon under test"
     Write-Host -ForegroundColor Green "INFO: Docker info of the daemon under test"
-    Write-Host
+    Write-Host 
     $ErrorActionPreference = "SilentlyContinue"
     $ErrorActionPreference = "SilentlyContinue"
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" info
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" info
     $ErrorActionPreference = "Stop"
     $ErrorActionPreference = "Stop"
@@ -606,7 +665,7 @@ Try {
 
 
     # Same as above but docker images
     # Same as above but docker images
     Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
     Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
-    Write-Host
+    Write-Host 
     $ErrorActionPreference = "SilentlyContinue"
     $ErrorActionPreference = "SilentlyContinue"
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
     & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
     $ErrorActionPreference = "Stop"
     $ErrorActionPreference = "Stop"
@@ -616,54 +675,59 @@ Try {
     }
     }
     Write-Host
     Write-Host
 
 
-    # Default to windowsservercore for the base image used for the tests. The "docker" image
-    # and the control daemon use microsoft/windowsservercore regardless. This is *JUST* for the tests.
-    if ($env:WINDOWS_BASE_IMAGE -eq $Null) {
-        $env:WINDOWS_BASE_IMAGE="microsoft/windowsservercore"
-    }
+    # Don't need Windows images when in LCOW mode.
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
 
 
-    # Lowercase and make sure it has a microsoft/ prefix
-    $env:WINDOWS_BASE_IMAGE = $env:WINDOWS_BASE_IMAGE.ToLower()
-    if ($($env:WINDOWS_BASE_IMAGE -Split "/")[0] -ne "microsoft") {
-        Throw "ERROR: WINDOWS_BASE_IMAGE should start microsoft/"
-    }
+        # Default to windowsservercore for the base image used for the tests. The "docker" image
+        # and the control daemon use microsoft/windowsservercore regardless. This is *JUST* for the tests.
+        if ($env:WINDOWS_BASE_IMAGE -eq $Null) {
+            $env:WINDOWS_BASE_IMAGE="microsoft/windowsservercore"
+        }
 
 
-    Write-Host -ForegroundColor Green "INFO: Base image for tests is $env:WINDOWS_BASE_IMAGE"
+        # Lowercase and make sure it has a microsoft/ prefix
+        $env:WINDOWS_BASE_IMAGE = $env:WINDOWS_BASE_IMAGE.ToLower()
+        if ($($env:WINDOWS_BASE_IMAGE -Split "/")[0] -ne "microsoft") {
+            Throw "ERROR: WINDOWS_BASE_IMAGE should start microsoft/"
+        }
 
 
-    $ErrorActionPreference = "SilentlyContinue"
-    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) {
-        # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
-        # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
-        if (Test-Path $("c:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")) {
-            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..."
-            $ErrorActionPreference = "SilentlyContinue"
-            & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" load -i $("$readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")
-            $ErrorActionPreference = "Stop"
-            if (-not $LastExitCode -eq 0) {
-                Throw $("ERROR: Failed to load $readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar into daemon under test")
+        Write-Host -ForegroundColor Green "INFO: Base image for tests is $env:WINDOWS_BASE_IMAGE"
+
+        $ErrorActionPreference = "SilentlyContinue"
+        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) {
+            # Try the internal azure CI image version or Microsoft internal corpnet where the base image is already pre-prepared on the disk,
+            # either through Invoke-DockerCI or, in the case of Azure CI servers, baked into the VHD at the same location.
+            if (Test-Path $("c:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")) {
+                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..."
+                $ErrorActionPreference = "SilentlyContinue"
+                & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" load -i $("$readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar")
+                $ErrorActionPreference = "Stop"
+                if (-not $LastExitCode -eq 0) {
+                    Throw $("ERROR: Failed to load $readBaseFrom`:\baseimages\"+$($env:WINDOWS_BASE_IMAGE -Split "/")[1]+".tar into daemon under test")
+                }
+                Write-Host -ForegroundColor Green "INFO: docker load of"$($env:WINDOWS_BASE_IMAGE -Split "/")[1]" into daemon under test completed successfully"
+            } else {
+                # We need to docker pull it instead. It will come in directly as microsoft/imagename:latest
+                Write-Host -ForegroundColor Green $("INFO: Pulling "+$env:WINDOWS_BASE_IMAGE+":latest from docker hub into daemon under test. This may take some time...")
+                $ErrorActionPreference = "SilentlyContinue"
+                & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" pull $($env:WINDOWS_BASE_IMAGE)
+                $ErrorActionPreference = "Stop"
+                if (-not $LastExitCode -eq 0) {
+                    Throw $("ERROR: Failed to docker pull "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test.")
+                }
+                Write-Host -ForegroundColor Green $("INFO: docker pull of "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test completed successfully")
             }
             }
-            Write-Host -ForegroundColor Green "INFO: docker load of"$($env:WINDOWS_BASE_IMAGE -Split "/")[1]" into daemon under test completed successfully"
         } else {
         } else {
-            # We need to docker pull it instead. It will come in directly as microsoft/imagename:latest
-            Write-Host -ForegroundColor Green $("INFO: Pulling "+$env:WINDOWS_BASE_IMAGE+":latest from docker hub into daemon under test. This may take some time...")
-            $ErrorActionPreference = "SilentlyContinue"
-            & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" pull $($env:WINDOWS_BASE_IMAGE)
-            $ErrorActionPreference = "Stop"
-            if (-not $LastExitCode -eq 0) {
-                Throw $("ERROR: Failed to docker pull "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test.")
-            }
-            Write-Host -ForegroundColor Green $("INFO: docker pull of "+$env:WINDOWS_BASE_IMAGE+":latest into daemon under test completed successfully")
+            Write-Host -ForegroundColor Green "INFO: Image"$($env:WINDOWS_BASE_IMAGE+":latest")"is already loaded in the daemon under test"
         }
         }
-    } else {
-        Write-Host -ForegroundColor Green "INFO: Image"$($env:WINDOWS_BASE_IMAGE+":latest")"is already loaded in the daemon under test"
+    
+    
+        # Inspect the pulled or loaded image to get the version directly
+        $ErrorActionPreference = "SilentlyContinue"
+        $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect  $($env:WINDOWS_BASE_IMAGE) --format "{{.OsVersion}}")
+        $ErrorActionPreference = "Stop"
+        Write-Host -ForegroundColor Green $("INFO: Version of "+$env:WINDOWS_BASE_IMAGE+":latest is '"+$dutimgVersion+"'")
     }
     }
 
 
-    # Inspect the pulled or loaded image to get the version directly
-    $ErrorActionPreference = "SilentlyContinue"
-    $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect  $($env:WINDOWS_BASE_IMAGE) --format "{{.OsVersion}}")
-    $ErrorActionPreference = "Stop"
-    Write-Host -ForegroundColor Green $("INFO: Version of "+$env:WINDOWS_BASE_IMAGE+":latest is '"+$dutimgVersion+"'")
-
     # Run the validation tests unless SKIP_VALIDATION_TESTS is defined.
     # Run the validation tests unless SKIP_VALIDATION_TESTS is defined.
     if ($env:SKIP_VALIDATION_TESTS -eq $null) {
     if ($env:SKIP_VALIDATION_TESTS -eq $null) {
         Write-Host -ForegroundColor Cyan "INFO: Running validation tests at $(Get-Date)..."
         Write-Host -ForegroundColor Cyan "INFO: Running validation tests at $(Get-Date)..."
@@ -678,162 +742,188 @@ Try {
         Write-Host -ForegroundColor Magenta "WARN: Skipping validation tests"
         Write-Host -ForegroundColor Magenta "WARN: Skipping validation tests"
     }
     }
 
 
+    # Note the unit tests won't work in LCOW mode as I turned off loading the base images above.
     # Run the unit tests inside a container unless SKIP_UNIT_TESTS is defined
     # Run the unit tests inside a container unless SKIP_UNIT_TESTS is defined
-    if ($env:SKIP_UNIT_TESTS -eq $null) {
-        Write-Host -ForegroundColor Cyan "INFO: Running unit tests at $(Get-Date)..."
-        $ErrorActionPreference = "SilentlyContinue"
-        $Duration=$(Measure-Command {docker run -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -TestUnit | Out-Host })
-        $ErrorActionPreference = "Stop"
-        if (-not($LastExitCode -eq 0)) {
-            Throw "ERROR: Unit tests failed"
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
+        if ($env:SKIP_UNIT_TESTS -eq $null) {
+            Write-Host -ForegroundColor Cyan "INFO: Running unit tests at $(Get-Date)..."
+            $ErrorActionPreference = "SilentlyContinue"
+            $Duration=$(Measure-Command {docker run -e DOCKER_GITCOMMIT=$COMMITHASH$CommitUnsupported docker hack\make.ps1 -TestUnit | Out-Host })
+            $ErrorActionPreference = "Stop"
+            if (-not($LastExitCode -eq 0)) {
+                Throw "ERROR: Unit tests failed"
+            }
+            Write-Host  -ForegroundColor Green "INFO: Unit tests ended at $(Get-Date). Duration`:$Duration"
+        } else {
+            Write-Host -ForegroundColor Magenta "WARN: Skipping unit tests"
         }
         }
-        Write-Host  -ForegroundColor Green "INFO: Unit tests ended at $(Get-Date). Duration`:$Duration"
-    } else {
-        Write-Host -ForegroundColor Magenta "WARN: Skipping unit tests"
     }
     }
 
 
-    # Add the busybox image. Needed for integration tests
-    if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
-        $ErrorActionPreference = "SilentlyContinue"
-        # Build it regardless while switching between nanoserver and windowsservercore
-        #$bbCount = $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images | Select-String "busybox" | Measure-Object -line).Lines
-        #$ErrorActionPreference = "Stop"
-        #if (-not($LastExitCode -eq 0)) {
-        #    Throw "ERROR: Could not determine if busybox image is present"
-        #}
-        #if ($bbCount -eq 0) {
-            Write-Host -ForegroundColor Green "INFO: Building busybox"
+    # Add the Windows busybox image. Needed for WCOW integration tests
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
+        if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
             $ErrorActionPreference = "SilentlyContinue"
             $ErrorActionPreference = "SilentlyContinue"
+            # Build it regardless while switching between nanoserver and windowsservercore
+            #$bbCount = $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images | Select-String "busybox" | Measure-Object -line).Lines
+            #$ErrorActionPreference = "Stop"
+            #if (-not($LastExitCode -eq 0)) {
+            #    Throw "ERROR: Could not determine if busybox image is present"
+            #}
+            #if ($bbCount -eq 0) {
+                Write-Host -ForegroundColor Green "INFO: Building busybox"
+                $ErrorActionPreference = "SilentlyContinue"
+    
+                # This is a temporary hack for nanoserver
+                if ($env:WINDOWS_BASE_IMAGE -ne "microsoft/windowsservercore") {
+                    Write-Host -ForegroundColor Red "HACK HACK HACK - Building 64-bit nanoserver busybox image"
+                    $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox64/master/Dockerfile | Out-Host)
+                } else {
+                    $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox/master/Dockerfile | Out-Host)
+                }
+                $ErrorActionPreference = "Stop"
+                if (-not($LastExitCode -eq 0)) {
+                    Throw "ERROR: Failed to build busybox image"
+                }
+            #}
 
 
-            # This is a temporary hack for nanoserver
-            if ($env:WINDOWS_BASE_IMAGE -ne "microsoft/windowsservercore") {
-                Write-Host -ForegroundColor Red "HACK HACK HACK - Building 64-bit nanoserver busybox image"
-                $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox64/master/Dockerfile | Out-Host)
-            } else {
-                $(& "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" build -t busybox https://raw.githubusercontent.com/jhowardmsft/busybox/master/Dockerfile | Out-Host)
+
+            Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
+            Write-Host 
+            $ErrorActionPreference = "SilentlyContinue"
+            & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
+            $ErrorActionPreference = "Stop"
+            if ($LastExitCode -ne 0) {
+                Throw "ERROR: The daemon under test does not appear to be running."
+                $DumpDaemonLog=1
+            }
+            Write-Host
+        }
+    }
+
+    # Run the WCOW integration tests unless SKIP_INTEGRATION_TESTS is defined
+    if (($env:LCOW_MODE -eq $Null) -and ($env:LCOW_BASIC_MODE -eq $Null)) {
+        if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
+            Write-Host -ForegroundColor Cyan "INFO: Running integration tests at $(Get-Date)..."
+            $ErrorActionPreference = "SilentlyContinue"
+    
+            # Location of the daemon under test.
+            $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
+    
+            #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
+            $c = "go test "
+            $c += "`"-check.v`" "
+            if ($env:INTEGRATION_TEST_NAME -ne $null) { # Makes is quicker for debugging to be able to run only a subset of the integration tests
+                $c += "`"-check.f`" "
+                $c += "`"$env:INTEGRATION_TEST_NAME`" "
+                Write-Host -ForegroundColor Magenta "WARN: Only running integration tests matching $env:INTEGRATION_TEST_NAME"
+            }
+            $c += "`"-tags`" " + "`"autogen`" "
+            $c += "`"-check.timeout`" " + "`"10m`" "
+            $c += "`"-test.timeout`" " + "`"200m`" "
+    
+            if ($env:INTEGRATION_IN_CONTAINER -ne $null) {
+                Write-Host -ForegroundColor Green "INFO: Integration tests being run inside a container"
+                # Note we talk back through the containers gateway address
+                # And the ridiculous lengths we have to go to to get the default gateway address... (GetNetIPConfiguration doesn't work in nanoserver)
+                # 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...
+                # Not the prettiest, but it works.
+                $c | Out-File -Force "$env:TEMP\binary\runIntegrationCLI.ps1"
+                $Duration= $(Measure-Command { & docker run `
+                                                        --rm `
+                                                        -e c=$c `
+                                                        --workdir "c`:\go\src\github.com\docker\docker\integration-cli" `
+                                                        -v "$env:TEMP\binary`:c:\target" `
+                                                        docker `
+                                                        "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
+            } else  {
+                Write-Host -ForegroundColor Green "INFO: Integration tests being run from the host:"
+                cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration-cli"
+                $env:DOCKER_HOST=$DASHH_CUT  
+                $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
+                Write-Host -ForegroundColor Green "INFO: $c"
+                Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
+                # Explicit to not use measure-command otherwise don't get output as it goes
+                $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
             }
             }
             $ErrorActionPreference = "Stop"
             $ErrorActionPreference = "Stop"
             if (-not($LastExitCode -eq 0)) {
             if (-not($LastExitCode -eq 0)) {
-                Throw "ERROR: Failed to build busybox image"
+                Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
             }
             }
-        #}
-
-
-        Write-Host -ForegroundColor Green "INFO: Docker images of the daemon under test"
-        Write-Host
-        $ErrorActionPreference = "SilentlyContinue"
-        & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" images
-        $ErrorActionPreference = "Stop"
-        if ($LastExitCode -ne 0) {
-            Throw "ERROR: The daemon under test does not appear to be running."
-            $DumpDaemonLog=1
+            Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
+        } else {
+            Write-Host -ForegroundColor Magenta "WARN: Skipping integration tests"
         }
         }
-        Write-Host
-    }
+    } else {
+        # The LCOW version of the tests here
+        if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
+            Write-Host -ForegroundColor Cyan "INFO: Running LCOW tests at $(Get-Date)..."
 
 
-    # Run the integration tests unless SKIP_INTEGRATION_TESTS is defined
-    if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
-        Write-Host -ForegroundColor Cyan "INFO: Running integration tests at $(Get-Date)..."
-        $ErrorActionPreference = "SilentlyContinue"
+            $ErrorActionPreference = "SilentlyContinue"
+    
+            # Location of the daemon under test.
+            $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
 
 
-        # Location of the daemon under test.
-        $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
-
-        #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
-        $c = "go test "
-        $c += "`"-tags`" " + "`"autogen`" "
-        $c += "./integration/..."
-
-        if ($env:INTEGRATION_IN_CONTAINER -ne $null) {
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run inside a container"
-            # Note we talk back through the containers gateway address
-            # And the ridiculous lengths we have to go to to get the default gateway address... (GetNetIPConfiguration doesn't work in nanoserver)
-            # 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...
-            # Not the prettiest, but it works.
-            $c | Out-File -Force "$env:TEMP\binary\runIntegration.ps1"
-            $Duration= $(Measure-Command { & docker run `
-                                                    --rm `
-                                                    -e c=$c `
-                                                    --workdir "c`:\go\src\github.com\docker\docker\" `
-                                                    -v "$env:TEMP\binary`:c:\target" `
-                                                    docker `
-                                                    "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
-        } else  {
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run from the host:"
-            #cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration"
-            $env:DOCKER_HOST=$DASHH_CUT
-            $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
-            Write-Host -ForegroundColor Green "INFO: $c"
+            # Make sure we are pointing at the DUT
+            $env:DOCKER_HOST=$DASHH_CUT  
             Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
             Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
-            # Explicit to not use measure-command otherwise don't get output as it goes
-            $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
-        }
-        $ErrorActionPreference = "Stop"
-        if (-not($LastExitCode -eq 0)) {
-            Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
-        }
-        Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
-    }else {
-        Write-Host -ForegroundColor Magenta "WARN: Skipping integration tests"
-    }
 
 
-    # Run the integration tests unless SKIP_INTEGRATION_TESTS is defined
-    if ($env:SKIP_INTEGRATION_TESTS -eq $null) {
-        Write-Host -ForegroundColor Cyan "INFO: Running integration cli tests at $(Get-Date)..."
-        $ErrorActionPreference = "SilentlyContinue"
+            # Force to use the test binaries, not the host ones.
+            $env:PATH="$env:TEMP\binary;$env:PATH;"  
+
+            if ($env:LCOW_BASIC_MODE -ne $null) {
+                $wc = New-Object net.webclient
+                try {
+                    Write-Host -ForegroundColor green "INFO: Downloading latest execution script..."
+                    $wc.Downloadfile("https://raw.githubusercontent.com/jhowardmsft/docker-w2wCIScripts/master/runCI/lcowbasicvalidation.ps1", "$env:TEMP\binary\lcowbasicvalidation.ps1")
+                } 
+                catch [System.Net.WebException]
+                {
+                    Throw ("Failed to download: $_")
+                }
 
 
-        # Location of the daemon under test.
-        $env:OrigDOCKER_HOST="$env:DOCKER_HOST"
+                # Explicit to not use measure-command otherwise don't get output as it goes
+                $ErrorActionPreference = "Stop"
+                $start=(Get-Date); Invoke-Expression "powershell $env:TEMP\binary\lcowbasicvalidation.ps1"; $lec=$lastExitCode; $Duration=New-Timespan -Start $start -End (Get-Date)
+                $Duration=New-Timespan -Start $start -End (Get-Date)
+                Write-Host  -ForegroundColor Green "INFO: LCOW tests ended at $(Get-Date). Duration`:$Duration"
+                if ($lec -ne 0) {
+                    Throw "LCOW validation tests failed"
+                }
+            } else {
+                #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
+                $c = "go test "
+                $c += "`"-check.v`" "
+                if ($env:INTEGRATION_TEST_NAME -ne $null) { # Makes is quicker for debugging to be able to run only a subset of the integration tests
+                    $c += "`"-check.f`" "
+                    $c += "`"$env:INTEGRATION_TEST_NAME`" "
+                    Write-Host -ForegroundColor Magenta "WARN: Only running LCOW integration tests matching $env:INTEGRATION_TEST_NAME"
+                }
+                $c += "`"-tags`" " + "`"autogen`" "
+                $c += "`"-check.timeout`" " + "`"10m`" "
+                $c += "`"-test.timeout`" " + "`"200m`" "
 
 
-        #https://blogs.technet.microsoft.com/heyscriptingguy/2011/09/20/solve-problems-with-external-command-lines-in-powershell/ is useful to see tokenising
-        $c = "go test "
-        $c += "`"-check.v`" "
-        if ($env:INTEGRATION_TEST_NAME -ne $null) { # Makes is quicker for debugging to be able to run only a subset of the integration tests
-            $c += "`"-check.f`" "
-            $c += "`"$env:INTEGRATION_TEST_NAME`" "
-            Write-Host -ForegroundColor Magenta "WARN: Only running integration tests matching $env:INTEGRATION_TEST_NAME"
-        }
-        $c += "`"-tags`" " + "`"autogen`" "
-        $c += "`"-check.timeout`" " + "`"10m`" "
-        $c += "`"-test.timeout`" " + "`"200m`" "
-
-        if ($env:INTEGRATION_IN_CONTAINER -ne $null) {
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run inside a container"
-            # Note we talk back through the containers gateway address
-            # And the ridiculous lengths we have to go to to get the default gateway address... (GetNetIPConfiguration doesn't work in nanoserver)
-            # 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...
-            # Not the prettiest, but it works.
-            $c | Out-File -Force "$env:TEMP\binary\runIntegrationCLI.ps1"
-            $Duration= $(Measure-Command { & docker run `
-                                                    --rm `
-                                                    -e c=$c `
-                                                    --workdir "c`:\go\src\github.com\docker\docker\integration-cli" `
-                                                    -v "$env:TEMP\binary`:c:\target" `
-                                                    docker `
-                                                    "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
-        } else  {
-            Write-Host -ForegroundColor Green "INFO: Integration tests being run from the host:"
-            cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration-cli"
-            $env:DOCKER_HOST=$DASHH_CUT
-            $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
-            Write-Host -ForegroundColor Green "INFO: $c"
-            Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
-            # Explicit to not use measure-command otherwise don't get output as it goes
-            $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
-        }
-        $ErrorActionPreference = "Stop"
-        if (-not($LastExitCode -eq 0)) {
-            Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
+                Write-Host -ForegroundColor Green "INFO: LCOW Integration tests being run from the host:"
+                cd "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\integration-cli"
+                Write-Host -ForegroundColor Green "INFO: $c"
+                Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
+                # Explicit to not use measure-command otherwise don't get output as it goes
+                $start=(Get-Date); Invoke-Expression $c; $Duration=New-Timespan -Start $start -End (Get-Date)
+
+            }
+            $ErrorActionPreference = "Stop"
+            if (-not($LastExitCode -eq 0)) {
+                Throw "ERROR: Integration tests failed at $(Get-Date). Duration`:$Duration"
+            }
+            Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
+        } else {
+            Write-Host -ForegroundColor Magenta "WARN: Skipping LCOW tests"
         }
         }
-        Write-Host  -ForegroundColor Green "INFO: Integration tests ended at $(Get-Date). Duration`:$Duration"
-    }else {
-        Write-Host -ForegroundColor Magenta "WARN: Skipping integration tests"
     }
     }
 
 
     # Docker info now to get counts (after or if jjh/containercounts is merged)
     # Docker info now to get counts (after or if jjh/containercounts is merged)
     if ($daemonStarted -eq 1) {
     if ($daemonStarted -eq 1) {
         Write-Host -ForegroundColor Green "INFO: Docker info of the daemon under test at end of run"
         Write-Host -ForegroundColor Green "INFO: Docker info of the daemon under test at end of run"
-        Write-Host
+        Write-Host 
         $ErrorActionPreference = "SilentlyContinue"
         $ErrorActionPreference = "SilentlyContinue"
         & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" info
         & "$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" info
         $ErrorActionPreference = "Stop"
         $ErrorActionPreference = "Stop"
@@ -845,16 +935,14 @@ Try {
     }
     }
 
 
     # Stop the daemon under test
     # Stop the daemon under test
-    if ($daemonStarted -eq 1) {
-        if (Test-Path "$env:TEMP\docker.pid") {
-            $p=Get-Content "$env:TEMP\docker.pid" -raw
-            if ($p -ne $null) {
-                Write-Host -ForegroundColor green "INFO: Stopping daemon under test"
-                taskkill -f -t -pid $p
-                Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue
-                #sleep 5
-            }
+    if (Test-Path "$env:TEMP\docker.pid") {
+        $p=Get-Content "$env:TEMP\docker.pid" -raw
+        if (($p -ne $null) -and ($daemonStarted -eq 1)) {
+            Write-Host -ForegroundColor green "INFO: Stopping daemon under test"
+            taskkill -f -t -pid $p
+            #sleep 5
         }
         }
+        Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue
     }
     }
 
 
     Write-Host -ForegroundColor Green "INFO: executeCI.ps1 Completed successfully at $(Get-Date)."
     Write-Host -ForegroundColor Green "INFO: executeCI.ps1 Completed successfully at $(Get-Date)."
@@ -862,18 +950,19 @@ Try {
 Catch [Exception] {
 Catch [Exception] {
     $FinallyColour="Red"
     $FinallyColour="Red"
     Write-Host -ForegroundColor Red ("`r`n`r`nERROR: Failed '$_' at $(Get-Date)")
     Write-Host -ForegroundColor Red ("`r`n`r`nERROR: Failed '$_' at $(Get-Date)")
+    Write-Host -ForegroundColor Red ($_.InvocationInfo.PositionMessage)
     Write-Host "`n`n"
     Write-Host "`n`n"
 
 
     # Exit to ensure Jenkins captures it. Don't do this in the ISE or interactive Powershell - they will catch the Throw onwards.
     # Exit to ensure Jenkins captures it. Don't do this in the ISE or interactive Powershell - they will catch the Throw onwards.
     if ( ([bool]([Environment]::GetCommandLineArgs() -Like '*-NonInteractive*')) -and `
     if ( ([bool]([Environment]::GetCommandLineArgs() -Like '*-NonInteractive*')) -and `
-        ([bool]([Environment]::GetCommandLineArgs() -NotLike "*Powershell_ISE.exe*"))) {
+         ([bool]([Environment]::GetCommandLineArgs() -NotLike "*Powershell_ISE.exe*"))) {
         exit 1
         exit 1
     }
     }
     Throw $_
     Throw $_
 }
 }
 Finally {
 Finally {
     $ErrorActionPreference="SilentlyContinue"
     $ErrorActionPreference="SilentlyContinue"
-    $global:ProgressPreference=$origProgressPreference
+	$global:ProgressPreference=$origProgressPreference
     Write-Host  -ForegroundColor Green "INFO: Tidying up at end of run"
     Write-Host  -ForegroundColor Green "INFO: Tidying up at end of run"
 
 
     # Restore the path
     # Restore the path
@@ -886,7 +975,7 @@ Finally {
     if ($origGOROOT -ne $null) { $env:GOROOT=$origGOROOT }
     if ($origGOROOT -ne $null) { $env:GOROOT=$origGOROOT }
     if ($origGOPATH -ne $null) { $env:GOPATH=$origGOPATH }
     if ($origGOPATH -ne $null) { $env:GOPATH=$origGOPATH }
 
 
-    # Dump the daemon log if asked to
+    # Dump the daemon log if asked to 
     if ($daemonStarted -eq 1) {
     if ($daemonStarted -eq 1) {
         if ($dumpDaemonLog -eq 1) {
         if ($dumpDaemonLog -eq 1) {
             Write-Host -ForegroundColor Cyan "----------- DAEMON LOG ------------"
             Write-Host -ForegroundColor Cyan "----------- DAEMON LOG ------------"
@@ -906,4 +995,3 @@ Finally {
     $Dur=New-TimeSpan -Start $StartTime -End $(Get-Date)
     $Dur=New-TimeSpan -Start $StartTime -End $(Get-Date)
     Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n"
     Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n"
 }
 }
-

+ 1 - 0
integration/build/build_squash_test.go

@@ -20,6 +20,7 @@ import (
 
 
 func TestBuildSquashParent(t *testing.T) {
 func TestBuildSquashParent(t *testing.T) {
 	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
 	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
+	skip.If(t, !testEnv.DaemonInfo.ExperimentalBuild)
 	skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon")
 	skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon")
 	d := daemon.New(t, daemon.WithExperimental)
 	d := daemon.New(t, daemon.WithExperimental)
 	d.StartWithBusybox(t)
 	d.StartWithBusybox(t)

+ 2 - 0
integration/build/build_test.go

@@ -189,6 +189,7 @@ func TestBuildMultiStageParentConfig(t *testing.T) {
 // Test cases in #36996
 // Test cases in #36996
 func TestBuildLabelWithTargets(t *testing.T) {
 func TestBuildLabelWithTargets(t *testing.T) {
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "test added after 1.38")
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "test added after 1.38")
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
 	bldName := "build-a"
 	bldName := "build-a"
 	testLabels := map[string]string{
 	testLabels := map[string]string{
 		"foo":  "bar",
 		"foo":  "bar",
@@ -443,6 +444,7 @@ RUN [ ! -f foo ]
 
 
 // #37581
 // #37581
 func TestBuildWithHugeFile(t *testing.T) {
 func TestBuildWithHugeFile(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	ctx := context.TODO()
 	ctx := context.TODO()
 	defer setupTest(t)()
 	defer setupTest(t)()
 
 

+ 101 - 0
integration/container/stop_linux_test.go

@@ -0,0 +1,101 @@
+package container // import "github.com/docker/docker/integration/container"
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/integration/internal/container"
+	"github.com/docker/docker/internal/test/request"
+	"gotest.tools/assert"
+	"gotest.tools/icmd"
+	"gotest.tools/poll"
+	"gotest.tools/skip"
+)
+
+// TestStopContainerWithTimeout checks that ContainerStop with
+// a timeout works as documented, i.e. in case of negative timeout
+// waiting is not limited (issue #35311).
+func TestStopContainerWithTimeout(t *testing.T) {
+	defer setupTest(t)()
+	client := request.NewAPIClient(t)
+	ctx := context.Background()
+
+	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
+	testData := []struct {
+		doc              string
+		timeout          int
+		expectedExitCode int
+	}{
+		// In case container is forcefully killed, 137 is returned,
+		// otherwise the exit code from the above script
+		{
+			"zero timeout: expect forceful container kill",
+			0, 137,
+		},
+		{
+			"too small timeout: expect forceful container kill",
+			1, 137,
+		},
+		{
+			"big enough timeout: expect graceful container stop",
+			3, 42,
+		},
+		{
+			"unlimited timeout: expect graceful container stop",
+			-1, 42,
+		},
+	}
+
+	for _, d := range testData {
+		d := d
+		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
+			t.Parallel()
+			id := container.Run(t, ctx, client, testCmd)
+
+			timeout := time.Duration(d.timeout) * time.Second
+			err := client.ContainerStop(ctx, id, &timeout)
+			assert.NilError(t, err)
+
+			poll.WaitOn(t, container.IsStopped(ctx, client, id),
+				poll.WithDelay(100*time.Millisecond))
+
+			inspect, err := client.ContainerInspect(ctx, id)
+			assert.NilError(t, err)
+			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
+		})
+	}
+}
+
+func TestDeleteDevicemapper(t *testing.T) {
+	skip.If(t, testEnv.DaemonInfo.Driver != "devicemapper")
+	skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run")
+
+	defer setupTest(t)()
+	client := request.NewAPIClient(t)
+	ctx := context.Background()
+
+	id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo"))
+
+	poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
+
+	inspect, err := client.ContainerInspect(ctx, id)
+	assert.NilError(t, err)
+
+	deviceID := inspect.GraphDriver.Data["DeviceId"]
+
+	// Find pool name from device name
+	deviceName := inspect.GraphDriver.Data["DeviceName"]
+	devicePrefix := deviceName[:strings.LastIndex(deviceName, "-")]
+	devicePool := fmt.Sprintf("/dev/mapper/%s-pool", devicePrefix)
+
+	result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
+	result.Assert(t, icmd.Success)
+
+	err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
+	assert.NilError(t, err)
+}

+ 0 - 89
integration/container/stop_test.go

@@ -2,19 +2,13 @@ package container // import "github.com/docker/docker/integration/container"
 
 
 import (
 import (
 	"context"
 	"context"
-	"fmt"
-	"strconv"
-	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
-	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/integration/internal/container"
 	"github.com/docker/docker/integration/internal/container"
 	"github.com/docker/docker/internal/test/request"
 	"github.com/docker/docker/internal/test/request"
 	"gotest.tools/assert"
 	"gotest.tools/assert"
-	"gotest.tools/icmd"
 	"gotest.tools/poll"
 	"gotest.tools/poll"
-	"gotest.tools/skip"
 )
 )
 
 
 func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
 func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
@@ -42,86 +36,3 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
 		poll.WaitOn(t, container.IsStopped(ctx, client, name), poll.WithDelay(100*time.Millisecond))
 		poll.WaitOn(t, container.IsStopped(ctx, client, name), poll.WithDelay(100*time.Millisecond))
 	}
 	}
 }
 }
-
-// TestStopContainerWithTimeout checks that ContainerStop with
-// a timeout works as documented, i.e. in case of negative timeout
-// waiting is not limited (issue #35311).
-func TestStopContainerWithTimeout(t *testing.T) {
-	defer setupTest(t)()
-	client := request.NewAPIClient(t)
-	ctx := context.Background()
-
-	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
-	testData := []struct {
-		doc              string
-		timeout          int
-		expectedExitCode int
-	}{
-		// In case container is forcefully killed, 137 is returned,
-		// otherwise the exit code from the above script
-		{
-			"zero timeout: expect forceful container kill",
-			0, 137,
-		},
-		{
-			"too small timeout: expect forceful container kill",
-			1, 137,
-		},
-		{
-			"big enough timeout: expect graceful container stop",
-			3, 42,
-		},
-		{
-			"unlimited timeout: expect graceful container stop",
-			-1, 42,
-		},
-	}
-
-	for _, d := range testData {
-		d := d
-		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
-			t.Parallel()
-			id := container.Run(t, ctx, client, testCmd)
-
-			timeout := time.Duration(d.timeout) * time.Second
-			err := client.ContainerStop(ctx, id, &timeout)
-			assert.NilError(t, err)
-
-			poll.WaitOn(t, container.IsStopped(ctx, client, id),
-				poll.WithDelay(100*time.Millisecond))
-
-			inspect, err := client.ContainerInspect(ctx, id)
-			assert.NilError(t, err)
-			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
-		})
-	}
-}
-
-func TestDeleteDevicemapper(t *testing.T) {
-	skip.If(t, testEnv.DaemonInfo.Driver != "devicemapper")
-	skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run")
-
-	defer setupTest(t)()
-	client := request.NewAPIClient(t)
-	ctx := context.Background()
-
-	id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo"))
-
-	poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
-
-	inspect, err := client.ContainerInspect(ctx, id)
-	assert.NilError(t, err)
-
-	deviceID := inspect.GraphDriver.Data["DeviceId"]
-
-	// Find pool name from device name
-	deviceName := inspect.GraphDriver.Data["DeviceName"]
-	devicePrefix := deviceName[:strings.LastIndex(deviceName, "-")]
-	devicePool := fmt.Sprintf("/dev/mapper/%s-pool", devicePrefix)
-
-	result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
-	result.Assert(t, icmd.Success)
-
-	err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
-	assert.NilError(t, err)
-}

+ 69 - 0
integration/container/stop_windows_test.go

@@ -0,0 +1,69 @@
+package container // import "github.com/docker/docker/integration/container"
+
+import (
+	"context"
+	"strconv"
+	"testing"
+	"time"
+
+	"github.com/docker/docker/integration/internal/container"
+	"github.com/docker/docker/internal/test/request"
+	"gotest.tools/assert"
+	"gotest.tools/poll"
+	"gotest.tools/skip"
+)
+
+// TestStopContainerWithTimeout checks that ContainerStop with
+// a timeout works as documented, i.e. in case of negative timeout
+// waiting is not limited (issue #35311).
+func TestStopContainerWithTimeout(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
+	defer setupTest(t)()
+	client := request.NewAPIClient(t)
+	ctx := context.Background()
+
+	testCmd := container.WithCmd("sh", "-c", "sleep 2 && exit 42")
+	testData := []struct {
+		doc              string
+		timeout          int
+		expectedExitCode int
+	}{
+		// In case container is forcefully killed, 137 is returned,
+		// otherwise the exit code from the above script
+		{
+			"zero timeout: expect forceful container kill",
+			1, 0x40010004,
+		},
+		{
+			"too small timeout: expect forceful container kill",
+			2, 0x40010004,
+		},
+		{
+			"big enough timeout: expect graceful container stop",
+			120, 42,
+		},
+		{
+			"unlimited timeout: expect graceful container stop",
+			-1, 42,
+		},
+	}
+
+	for _, d := range testData {
+		d := d
+		t.Run(strconv.Itoa(d.timeout), func(t *testing.T) {
+			t.Parallel()
+			id := container.Run(t, ctx, client, testCmd)
+
+			timeout := time.Duration(d.timeout) * time.Second
+			err := client.ContainerStop(ctx, id, &timeout)
+			assert.NilError(t, err)
+
+			poll.WaitOn(t, container.IsStopped(ctx, client, id),
+				poll.WithDelay(100*time.Millisecond))
+
+			inspect, err := client.ContainerInspect(ctx, id)
+			assert.NilError(t, err)
+			assert.Equal(t, inspect.State.ExitCode, d.expectedExitCode)
+		})
+	}
+}

+ 1 - 1
integration/image/import_test.go

@@ -11,7 +11,7 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/internal/test/request"
 	"github.com/docker/docker/internal/test/request"
 	"github.com/docker/docker/internal/testutil"
 	"github.com/docker/docker/internal/testutil"
-	"github.com/gotestyourself/gotestyourself/skip"
+	"gotest.tools/skip"
 )
 )
 
 
 // Ensure we don't regress on CVE-2017-14992.
 // Ensure we don't regress on CVE-2017-14992.

+ 2 - 0
integration/image/tag_test.go

@@ -9,6 +9,7 @@ import (
 	"github.com/docker/docker/internal/testutil"
 	"github.com/docker/docker/internal/testutil"
 	"gotest.tools/assert"
 	"gotest.tools/assert"
 	is "gotest.tools/assert/cmp"
 	is "gotest.tools/assert/cmp"
+	"gotest.tools/skip"
 )
 )
 
 
 // tagging a named image in a new unprefixed repo should work
 // tagging a named image in a new unprefixed repo should work
@@ -95,6 +96,7 @@ func TestTagExistedNameWithoutForce(t *testing.T) {
 // ensure tagging using official names works
 // ensure tagging using official names works
 // ensure all tags result in the same name
 // ensure all tags result in the same name
 func TestTagOfficialNames(t *testing.T) {
 func TestTagOfficialNames(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	defer setupTest(t)()
 	defer setupTest(t)()
 	client := request.NewAPIClient(t)
 	client := request.NewAPIClient(t)
 	ctx := context.Background()
 	ctx := context.Background()

+ 0 - 26
integration/internal/requirement/requirement.go

@@ -5,9 +5,6 @@ import (
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
-
-	"github.com/docker/docker/pkg/parsers/kernel"
-	"gotest.tools/icmd"
 )
 )
 
 
 // HasHubConnectivity checks to see if https://hub.docker.com is
 // HasHubConnectivity checks to see if https://hub.docker.com is
@@ -28,26 +25,3 @@ func HasHubConnectivity(t *testing.T) bool {
 	}
 	}
 	return err == nil
 	return err == nil
 }
 }
-
-func overlayFSSupported() bool {
-	result := icmd.RunCommand("/bin/sh", "-c", "cat /proc/filesystems")
-	if result.Error != nil {
-		return false
-	}
-	return strings.Contains(result.Combined(), "overlay\n")
-}
-
-// Overlay2Supported returns true if the current system supports overlay2 as graphdriver
-func Overlay2Supported(kernelVersion string) bool {
-	if !overlayFSSupported() {
-		return false
-	}
-
-	daemonV, err := kernel.ParseRelease(kernelVersion)
-	if err != nil {
-		return false
-	}
-	requiredV := kernel.VersionInfo{Kernel: 4}
-	return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
-
-}

+ 31 - 0
integration/internal/requirement/requirement_linux.go

@@ -0,0 +1,31 @@
+package requirement // import "github.com/docker/docker/integration/internal/requirement"
+
+import (
+	"strings"
+
+	"github.com/docker/docker/pkg/parsers/kernel"
+	"gotest.tools/icmd"
+)
+
+func overlayFSSupported() bool {
+	result := icmd.RunCommand("/bin/sh", "-c", "cat /proc/filesystems")
+	if result.Error != nil {
+		return false
+	}
+	return strings.Contains(result.Combined(), "overlay\n")
+}
+
+// Overlay2Supported returns true if the current system supports overlay2 as graphdriver
+func Overlay2Supported(kernelVersion string) bool {
+	if !overlayFSSupported() {
+		return false
+	}
+
+	daemonV, err := kernel.ParseRelease(kernelVersion)
+	if err != nil {
+		return false
+	}
+	requiredV := kernel.VersionInfo{Kernel: 4}
+	return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
+
+}

+ 12 - 0
integration/internal/requirement/requirement_windows.go

@@ -0,0 +1,12 @@
+// +build windows
+
+package requirement // import "github.com/docker/docker/integration/internal/requirement"
+
+func overlayFSSupported() bool {
+	return false
+}
+
+// Overlay2Supported returns true if the current system supports overlay2 as graphdriver
+func Overlay2Supported(kernelVersion string) bool {
+	return false
+}

+ 1 - 0
integration/network/delete_test.go

@@ -44,6 +44,7 @@ func createAmbiguousNetworks(t *testing.T) (string, string, string) {
 	return testNet, idPrefixNet, fullIDNet
 	return testNet, idPrefixNet, fullIDNet
 }
 }
 
 
+// TestNetworkCreateDelete tests creation and deletion of a network.
 func TestNetworkCreateDelete(t *testing.T) {
 func TestNetworkCreateDelete(t *testing.T) {
 	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
 	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
 	defer setupTest(t)()
 	defer setupTest(t)()

+ 49 - 0
integration/network/helpers_windows.go

@@ -0,0 +1,49 @@
+package network
+
+import (
+	"context"
+	"fmt"
+	"os"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
+	"gotest.tools/assert/cmp"
+)
+
+// IsNetworkAvailable provides a comparison to check if a docker network is available
+func IsNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison {
+	return func() cmp.Result {
+		networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
+		if err != nil {
+			return cmp.ResultFromError(err)
+		}
+		for _, network := range networks {
+			if network.Name == name {
+				return cmp.ResultSuccess
+			}
+		}
+		return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name))
+	}
+}
+
+// IsNetworkNotAvailable provides a comparison to check if a docker network is not available
+func IsNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison {
+	return func() cmp.Result {
+		networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
+		if err != nil {
+			return cmp.ResultFromError(err)
+		}
+		for _, network := range networks {
+			if network.Name == name {
+				return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name))
+			}
+		}
+		return cmp.ResultSuccess
+	}
+}
+
+// IsUserNamespace returns whether the user namespace remapping is enabled
+func IsUserNamespace() bool {
+	root := os.Getenv("DOCKER_REMAP_ROOT")
+	return root != ""
+}

+ 0 - 2
integration/network/macvlan/macvlan_test.go

@@ -19,7 +19,6 @@ import (
 
 
 func TestDockerNetworkMacvlanPersistance(t *testing.T) {
 func TestDockerNetworkMacvlanPersistance(t *testing.T) {
 	// verify the driver automatically provisions the 802.1q link (dm-dummy0.60)
 	// verify the driver automatically provisions the 802.1q link (dm-dummy0.60)
-	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan")
 	skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan")
 
 
@@ -44,7 +43,6 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) {
 }
 }
 
 
 func TestDockerNetworkMacvlan(t *testing.T) {
 func TestDockerNetworkMacvlan(t *testing.T) {
-	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan")
 	skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan")
 
 

+ 6 - 0
integration/network/service_test.go

@@ -26,6 +26,7 @@ func delInterface(t *testing.T, ifName string) {
 }
 }
 
 
 func TestDaemonRestartWithLiveRestore(t *testing.T) {
 func TestDaemonRestartWithLiveRestore(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	d := daemon.New(t)
 	d := daemon.New(t)
@@ -46,6 +47,7 @@ func TestDaemonRestartWithLiveRestore(t *testing.T) {
 }
 }
 
 
 func TestDaemonDefaultNetworkPools(t *testing.T) {
 func TestDaemonDefaultNetworkPools(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	// Remove docker0 bridge and the start daemon defining the predefined address pools
 	// Remove docker0 bridge and the start daemon defining the predefined address pools
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
@@ -87,6 +89,7 @@ func TestDaemonDefaultNetworkPools(t *testing.T) {
 }
 }
 
 
 func TestDaemonRestartWithExistingNetwork(t *testing.T) {
 func TestDaemonRestartWithExistingNetwork(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	defaultNetworkBridge := "docker0"
 	defaultNetworkBridge := "docker0"
@@ -119,6 +122,7 @@ func TestDaemonRestartWithExistingNetwork(t *testing.T) {
 }
 }
 
 
 func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
 func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	defaultNetworkBridge := "docker0"
 	defaultNetworkBridge := "docker0"
@@ -167,6 +171,7 @@ func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
 }
 }
 
 
 func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
 func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, testEnv.IsRemoteDaemon())
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
 	defaultNetworkBridge := "docker0"
 	defaultNetworkBridge := "docker0"
@@ -317,6 +322,7 @@ func noServices(client client.ServiceAPIClient) func(log poll.LogT) poll.Result
 }
 }
 
 
 func TestServiceWithDefaultAddressPoolInit(t *testing.T) {
 func TestServiceWithDefaultAddressPoolInit(t *testing.T) {
+	skip.If(t, testEnv.OSType == "windows")
 	defer setupTest(t)()
 	defer setupTest(t)()
 	var ops = []func(*daemon.Daemon){}
 	var ops = []func(*daemon.Daemon){}
 	ipAddr := []string{"20.20.0.0/16"}
 	ipAddr := []string{"20.20.0.0/16"}

+ 0 - 0
integration/plugin/logging/logging_test.go → integration/plugin/logging/logging_linux_test.go


+ 2 - 0
integration/system/info_test.go

@@ -9,6 +9,7 @@ import (
 	"github.com/docker/docker/internal/test/request"
 	"github.com/docker/docker/internal/test/request"
 	"gotest.tools/assert"
 	"gotest.tools/assert"
 	is "gotest.tools/assert/cmp"
 	is "gotest.tools/assert/cmp"
+	"gotest.tools/skip"
 )
 )
 
 
 func TestInfoAPI(t *testing.T) {
 func TestInfoAPI(t *testing.T) {
@@ -43,6 +44,7 @@ func TestInfoAPI(t *testing.T) {
 }
 }
 
 
 func TestInfoAPIWarnings(t *testing.T) {
 func TestInfoAPIWarnings(t *testing.T) {
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
 	d := daemon.New(t)
 	d := daemon.New(t)
 
 
 	client, err := d.NewClient()
 	client, err := d.NewClient()