xunit-extensions icon indicating copy to clipboard operation
xunit-extensions copied to clipboard

Docker skip doesn't work on Windows

Open jzabroski opened this issue 6 years ago • 11 comments

Hey @natemcmaster

Found Arnot's Xunit.SkippableFact library on nuget as well as your lib. Was hoping your docker skipper was generic, but it's not...

jzabroski avatar Feb 19 '19 23:02 jzabroski

I'd welcome a PR to fix this.

natemcmaster avatar Feb 19 '19 23:02 natemcmaster

Sure. Just one question - in reading about this - it seems like there is no good way to detect docker is not running vs. not installed. The simplest thing to test seems to be for a named pipe starting with the word docker. Thoughts?

https://forums.docker.com/t/feature-detect-docker-for-windows/21622/3

[System.IO.Directory]::GetFiles("\\.\\pipe\\") | Select-String -pattern "docker"
\\.\\pipe\\PSHost.131176286632409278.26752.DefaultAppDomain.com.docker.service
\\.\\pipe\\dockerBackend
\\.\\pipe\\dockerLogs
\\.\\pipe\\PSHost.131178195006249300.8044.DefaultAppDomain.Docker for Windows
\\.\\pipe\\dockerDataBase
\\.\\pipe\\dockerMobyLinuxVM-com1
\\.\\pipe\\docker_engine

jzabroski avatar Feb 19 '19 23:02 jzabroski

I can probably throw in support for Mac OS as well - but no guarantee it worked. When my Mac Book 2010 Mid model failed last year I gave up on the religion.

jzabroski avatar Feb 19 '19 23:02 jzabroski

To be clear, SkipIfNotDockerAttribute is meant to skip tests when not running inside a container. It's not meant to skip tests running on a host if Docker is not installed. If there is a reliable way to detect that with Windows Containers, let me know.

natemcmaster avatar Feb 20 '19 19:02 natemcmaster

Yes, that's clear. Not that you need to care, but I'm new to using Docker... so stumbling through this. You can see my Docker journal I've put together in the last ~5 days since I decided to pivot from learning more about Machine Learning and just focus on practical SDLC stuff like Docker. - At the time I wrote that suggestion, I was unfamiliar with exactly how Docker for Windows even works, since most of the stuff I have read is very Linux-specific with cgroups, etc.

Below is a script from StackOverflow which seems more robust than the above script which just mainly sees if there is any docker installed. It checks for cexecsvc.

function Test-IsInsideContainer {
  $foundService = Get-Service -Name cexecsvc -ErrorAction SilentlyContinue
  if( $foundService -eq $null ) {
    $false
  }
  else {
    $true
  }
}

Translating this to C#, might just be able to call System.ServiceProcess.ServiceController.GetServices(), which is available in Core.

jzabroski avatar Feb 20 '19 19:02 jzabroski

@natemcmaster The downside would be any patch would take a dependency on System.ServiceProcess.ServiceController nuget package. In this sense, I can see why Arnott chose to implement Skip.If checks internal to the test - it pushes the actual check to the consuming client writing the test, rather than introduce a dependency to all users.

The downside to his approach is its less tool-able/query-able.

Thoughts?

jzabroski avatar Feb 20 '19 19:02 jzabroski

I'm fine adding a new dependency if it's the only good way to detect if a process is running inside a Windows container

natemcmaster avatar Feb 24 '19 20:02 natemcmaster

One other idea. I discovered that my ~\.dotnet folder contains ".dotnetuserlevelcache" files, and it seems like they're per-.NET Core environment. I'm not sure what's writing these files, but it seems like somewhere there is infrastructure that knows whether something is a docker container. Check this out and tell me if you have similar stuff hanging out on your system:

PS C:\WINDOWS\system32> get-childitem ~\.dotnet


    Directory: C:\Users\john.zabroski\.dotnet


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         3/1/2019  11:28 AM                pids
-a----       10/25/2017   3:56 PM              5 2.0.2_IsDockerContainer.dotnetUserLevelCache
-a----       10/25/2017   3:56 PM             64 2.0.2_MachineId.dotnetUserLevelCache
-a----       11/28/2017  11:58 AM              5 2.0.3_IsDockerContainer.dotnetUserLevelCache
-a----       11/28/2017  11:58 AM             64 2.0.3_MachineId.dotnetUserLevelCache
-a----         3/9/2018   6:24 PM              5 2.1.100_IsDockerContainer.dotnetUserLevelCache
-a----         3/9/2018   6:24 PM             64 2.1.100_MachineId.dotnetUserLevelCache
-a----        3/16/2018   1:44 PM              5 2.1.101_IsDockerContainer.dotnetUserLevelCache
-a----        3/16/2018   1:44 PM             64 2.1.101_MachineId.dotnetUserLevelCache
-a----        3/23/2018   2:22 PM              5 2.1.103_IsDockerContainer.dotnetUserLevelCache
-a----        3/23/2018   2:22 PM             64 2.1.103_MachineId.dotnetUserLevelCache
-a----         4/9/2018   8:26 PM              5 2.1.104_IsDockerContainer.dotnetUserLevelCache
-a----         4/9/2018   8:26 PM             64 2.1.104_MachineId.dotnetUserLevelCache
-a----         5/8/2018   6:47 PM              5 2.1.200_IsDockerContainer.dotnetUserLevelCache
-a----         5/8/2018   6:47 PM             64 2.1.200_MachineId.dotnetUserLevelCache
-a----        8/10/2018   2:49 PM              0 2.1.202.dotnetFirstUseSentinel
-a----        7/20/2018   2:24 PM              5 2.1.202_IsDockerContainer.dotnetUserLevelCache
-a----        7/20/2018   2:24 PM             64 2.1.202_MachineId.dotnetUserLevelCache
-a----       12/29/2017   3:35 PM              5 2.1.2_IsDockerContainer.dotnetUserLevelCache
-a----       12/29/2017   3:35 PM             64 2.1.2_MachineId.dotnetUserLevelCache
-a----        8/30/2018   1:23 PM              0 2.1.400.aspNetCertificateSentinel
-a----        8/30/2018   1:23 PM              0 2.1.400.dotnetFirstUseSentinel
-a----        8/30/2018   1:23 PM              0 2.1.400.toolpath.sentinel
-a----        8/14/2018   6:47 PM              5 2.1.400_IsDockerContainer.dotnetUserLevelCache
-a----        8/14/2018   6:47 PM             64 2.1.400_MachineId.dotnetUserLevelCache
-a----         9/7/2018   5:01 PM              5 2.1.401_IsDockerContainer.dotnetUserLevelCache
-a----         9/7/2018   5:01 PM             64 2.1.401_MachineId.dotnetUserLevelCache
-a----        9/20/2018   9:19 AM              5 2.1.402_IsDockerContainer.dotnetUserLevelCache
-a----        9/20/2018   9:19 AM             64 2.1.402_MachineId.dotnetUserLevelCache
-a----       10/15/2018  11:44 AM              5 2.1.403_IsDockerContainer.dotnetUserLevelCache
-a----       10/15/2018  11:45 AM             64 2.1.403_MachineId.dotnetUserLevelCache
-a----        1/29/2018  11:25 AM              5 2.1.4_IsDockerContainer.dotnetUserLevelCache
-a----        1/29/2018  11:25 AM             64 2.1.4_MachineId.dotnetUserLevelCache
-a----        12/3/2018  12:45 PM              0 2.1.500.aspNetCertificateSentinel
-a----        12/3/2018  12:45 PM              0 2.1.500.dotnetFirstUseSentinel
-a----        12/3/2018  12:45 PM              0 2.1.500.toolpath.sentinel
-a----       11/16/2018   1:43 PM              5 2.1.500_IsDockerContainer.dotnetUserLevelCache
-a----       11/16/2018   1:43 PM             64 2.1.500_MachineId.dotnetUserLevelCache
-a----       12/19/2018  10:24 AM              5 2.1.502_IsDockerContainer.dotnetUserLevelCache
-a----       12/19/2018  10:24 AM             64 2.1.502_MachineId.dotnetUserLevelCache
-a----        1/31/2019   2:56 PM              5 2.1.503_IsDockerContainer.dotnetUserLevelCache
-a----        1/31/2019   2:56 PM             64 2.1.503_MachineId.dotnetUserLevelCache
-a----         3/6/2019   1:33 PM              0 2.1.504.aspNetCertificateSentinel
-a----         3/6/2019   1:33 PM              0 2.1.504.dotnetFirstUseSentinel
-a----         3/6/2019   1:33 PM              0 2.1.504.toolpath.sentinel
-a----        2/19/2019   1:12 PM              5 2.1.504_IsDockerContainer.dotnetUserLevelCache
-a----        2/19/2019   1:12 PM             64 2.1.504_MachineId.dotnetUserLevelCache
-a----        3/12/2019   7:27 PM              5 2.1.505_IsDockerContainer.dotnetUserLevelCache
-a----        3/12/2019   7:27 PM             64 2.1.505_MachineId.dotnetUserLevelCache

I'm not sure who/what is adding this, since even a search on Microsoft's GitHub provides no clues:

https://github.com/search?q=org%3AMicrosoft+IsDockerContainer&type=Code

jzabroski avatar Mar 19 '19 20:03 jzabroski

Tracked it down, baby! https://github.com/dotnet/cli/search?q=isdockercontainer&unscoped_q=isdockercontainer What, what, woop woop.

Probably best to use the same telemetry as Dotnet Cli Tools.

https://github.com/dotnet/cli/blob/95c6eff6daa1a69f29c42b2d405400ad44bdec91/src/dotnet/Telemetry/DockerContainerDetectorForTelemetry.cs#L15

jzabroski avatar Mar 19 '19 21:03 jzabroski

Pull requests accepted :) currently busy taking care of my newborn so sorry for delayed responses.

natemcmaster avatar Mar 24 '19 14:03 natemcmaster

It's cool. I wrote it but haven't used it enough yet to feel comfortable pushing it. Will do soon. Congrats on being the new title holder of world's best dad.

On Sun, Mar 24, 2019, 10:02 AM Nate McMaster [email protected] wrote:

Pull requests accepted :) currently busy taking care of my newborn so sorry for delayed responses.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/natemcmaster/xunit-extensions/issues/1#issuecomment-475962471, or mute the thread https://github.com/notifications/unsubscribe-auth/AAbT_TI2r6QyUnWpeB19bSwEeebJTRNKks5vZ4VngaJpZM4bEDIF .

jzabroski avatar Mar 24 '19 16:03 jzabroski