natemcmaster / xunit-extensions

Making XUnit.NET test projects even better
Apache License 2.0
23 stars 3 forks source link

Docker skip doesn't work on Windows #1

Open jzabroski opened 5 years ago

jzabroski commented 5 years ago

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...

natemcmaster commented 5 years ago

I'd welcome a PR to fix this.

jzabroski commented 5 years ago

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 commented 5 years ago

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.

natemcmaster commented 5 years ago

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.

jzabroski commented 5 years ago

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 commented 5 years ago

@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?

natemcmaster commented 5 years ago

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

jzabroski commented 5 years ago

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 commented 5 years ago

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

natemcmaster commented 5 years ago

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

jzabroski commented 5 years ago

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 notifications@github.com 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 .