private string CreateTestAppWithSdkImage(string appType) { string appDir = Path.Combine(Directory.GetCurrentDirectory(), $"{appType}App{DateTime.Now.ToFileTime()}"); string containerName = _imageData.GetIdentifier($"create-{appType}"); try { string targetFramework; // TODO: Until https://github.com/dotnet/aspnetcore/pull/19860 is fixed, 5.0 web projects need to // continue to use the old TFM. if (_imageData.Version.Major < 5 || appType == "web") { targetFramework = $"netcoreapp{_imageData.Version}"; } else { targetFramework = $"net{_imageData.Version}"; } _dockerHelper.Run( image: _imageData.GetImage(DotNetImageType.SDK, _dockerHelper), name: containerName, command: $"dotnet new {appType} --framework {targetFramework} --no-restore", workdir: "/app", skipAutoCleanup: true); _dockerHelper.Copy($"{containerName}:/app", appDir); string sourceDockerfileName = $"Dockerfile.{DockerHelper.DockerOS.ToLower()}"; File.Copy( Path.Combine(_testArtifactsDir, sourceDockerfileName), Path.Combine(appDir, "Dockerfile")); string nuGetConfigFileName = "NuGet.config"; if (Config.IsNightlyRepo) { nuGetConfigFileName += ".nightly"; } File.Copy(Path.Combine(_testArtifactsDir, nuGetConfigFileName), Path.Combine(appDir, "NuGet.config")); File.Copy(Path.Combine(_testArtifactsDir, ".dockerignore"), Path.Combine(appDir, ".dockerignore")); } catch (Exception) { if (Directory.Exists(appDir)) { Directory.Delete(appDir, true); } throw; } finally { _dockerHelper.DeleteContainer(containerName); } return(appDir); }
private string CreateTestAppWithSdkImage(string appType) { string appDir = Path.Combine(Directory.GetCurrentDirectory(), $"{appType}App{DateTime.Now.ToFileTime()}"); string containerName = _imageData.GetIdentifier($"create-{appType}"); try { _dockerHelper.Run( image: _imageData.GetImage(DotNetImageType.SDK, _dockerHelper), name: containerName, command: $"dotnet new {appType} --framework netcoreapp{_imageData.Version}", workdir: "/app", skipAutoCleanup: true); _dockerHelper.Copy($"{containerName}:/app", appDir); ApplyProjectCustomizations(_imageData, Path.Combine(appDir, "app.csproj")); string sourceDockerfileName = $"Dockerfile.{DockerHelper.DockerOS.ToLower()}"; // TODO: Remove Windows arm workaround once underlying Windows/Docker issue is resolved // https://github.com/dotnet/dotnet-docker/issues/1054 if (!DockerHelper.IsLinuxContainerModeEnabled && _imageData.Arch == Arch.Arm) { sourceDockerfileName += $".{Enum.GetName(typeof(Arch), _imageData.Arch).ToLowerInvariant()}"; } File.Copy( Path.Combine(_testArtifactsDir, sourceDockerfileName), Path.Combine(appDir, "Dockerfile")); string nuGetConfigFileName = "NuGet.config"; if (Config.IsNightlyRepo) { nuGetConfigFileName += ".nightly"; } File.Copy(Path.Combine(_testArtifactsDir, nuGetConfigFileName), Path.Combine(appDir, "NuGet.config")); File.Copy(Path.Combine(_testArtifactsDir, ".dockerignore"), Path.Combine(appDir, ".dockerignore")); } catch (Exception) { if (Directory.Exists(appDir)) { Directory.Delete(appDir, true); } throw; } finally { _dockerHelper.DeleteContainer(containerName); } return(appDir); }
public async Task VerifyAspnetSample(SampleImageData imageData) { if (imageData.OS == OS.Bionic && imageData.DockerfileSuffix != "ubuntu-x64") { return; } await VerifySampleAsync(imageData, SampleImageType.Aspnetapp, async (image, containerName) => { try { DockerHelper.Run( image: image, name: containerName, detach: true, optionalRunArgs: "-p 80"); if (!Config.IsHttpVerificationDisabled) { await ImageScenarioVerifier.VerifyHttpResponseFromContainerAsync(containerName, DockerHelper, OutputHelper); } ValidateEnvironmentVariables(imageData, image, SampleImageType.Aspnetapp); } finally { DockerHelper.DeleteContainer(containerName); } }); }
private string CreateTestAppWithSdkImage(string appType) { string appDir = Path.Combine(Directory.GetCurrentDirectory(), $"{appType}App{DateTime.Now.ToFileTime()}"); string containerName = _imageData.GetIdentifier($"create-{appType}"); try { _dockerHelper.Run( image: _imageData.GetImage(DotNetImageType.SDK, _dockerHelper), name: containerName, command: $"dotnet new {appType} --framework netcoreapp{_imageData.Version}", workdir: "/app", skipAutoCleanup: true); _dockerHelper.Copy($"{containerName}:/app", appDir); ApplyProjectCustomizations(_imageData, Path.Combine(appDir, "app.csproj")); File.Copy( Path.Combine(_testArtifactsDir, $"Dockerfile.{DockerHelper.DockerOS.ToLower()}"), Path.Combine(appDir, "Dockerfile")); string nuGetConfigFileName = "NuGet.config"; if (Config.IsNightlyRepo) { nuGetConfigFileName += ".nightly"; } File.Copy(Path.Combine(_testArtifactsDir, nuGetConfigFileName), Path.Combine(appDir, "NuGet.config")); File.Copy(Path.Combine(_testArtifactsDir, ".dockerignore"), Path.Combine(appDir, ".dockerignore")); } catch (Exception) { if (Directory.Exists(appDir)) { Directory.Delete(appDir, true); } throw; } finally { _dockerHelper.DeleteContainer(containerName); } return(appDir); }
public void VerifyComplexAppSample() { string appTag = SampleImageData.GetImageName("complexapp-local-app"); string testTag = SampleImageData.GetImageName("complexapp-local-test"); string sampleFolder = Path.Combine(s_samplesPath, "complexapp"); string dockerfilePath = $"{sampleFolder}/Dockerfile"; string testContainerName = ImageData.GenerateContainerName("sample-complex-test"); string tempDir = null; try { // Test that the app works DockerHelper.Build(appTag, dockerfilePath, contextDir: sampleFolder, pull: Config.PullImages); string containerName = ImageData.GenerateContainerName("sample-complex"); string output = DockerHelper.Run(appTag, containerName); Assert.StartsWith("string: The quick brown fox jumps over the lazy dog", output); if (!DockerHelper.IsLinuxContainerModeEnabled && DockerHelper.DockerArchitecture.StartsWith("arm", StringComparison.OrdinalIgnoreCase)) { // Skipping run app tests due to a .NET issue: https://github.com/dotnet/runtime/issues/2082 return; } // Run the app's tests DockerHelper.Build(testTag, dockerfilePath, target: "test", contextDir: sampleFolder); DockerHelper.Run(testTag, testContainerName, skipAutoCleanup: true); // Copy the test log from the container to the host tempDir = Directory.CreateDirectory( Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())).FullName; DockerHelper.Copy($"{testContainerName}:/source/tests/TestResults", tempDir); string testLogFile = new DirectoryInfo($"{tempDir}/TestResults").GetFiles("*.trx").First().FullName; // Open the test log file and verify the tests passed XDocument doc = XDocument.Load(testLogFile); XElement summary = doc.Root.Element(XName.Get("ResultSummary", doc.Root.Name.NamespaceName)); Assert.Equal("Completed", summary.Attribute("outcome").Value); XElement counters = summary.Element(XName.Get("Counters", doc.Root.Name.NamespaceName)); Assert.Equal("2", counters.Attribute("total").Value); Assert.Equal("2", counters.Attribute("passed").Value); } finally { if (tempDir != null) { Directory.Delete(tempDir, true); } DockerHelper.DeleteContainer(testContainerName); DockerHelper.DeleteImage(testTag); DockerHelper.DeleteImage(appTag); } }
private async Task VerifySdkImage_RunApp(ImageData imageData, string appSdkImage) { try { // dotnet run the new app using the sdk image _dockerHelper.Run( image: appSdkImage, command: "dotnet run --no-launch-profile", detach: imageData.IsWeb, containerName: appSdkImage); if (imageData.IsWeb && !s_isHttpVerificationDisabled) { await VerifyHttpResponseFromContainer(appSdkImage); } } finally { _dockerHelper.DeleteContainer(appSdkImage); } }
/// <summary> /// Runs a single instance of the dotnet-monitor image. /// </summary> /// <param name="imageData">The image data of the dotnet-monitor image.</param> /// <param name="noAuthentication">Set to true to disable dotnet-monitor authenication.</param> /// <param name="verifyContainerAsync">Callback to test some aspect of the container.</param> /// <param name="runArgsCallback">Allows for modifying the "docker run" args of the container.</param> private async Task VerifyMonitorAsync( MonitorImageData imageData, bool noAuthentication, Func <string, Task> verifyContainerAsync = null, Action <DockerRunArgsBuilder> runArgsCallback = null) { GetNames(imageData, out string monitorImageName, out string monitorContainerName); try { DockerRunArgsBuilder runArgsBuilder = DockerRunArgsBuilder.Create() .ExposePort(DefaultMetricsPort); if (null != runArgsCallback) { runArgsCallback(runArgsBuilder); } DockerHelper.Run( image: monitorImageName, name: monitorContainerName, command: GetMonitorAdditionalArgs(noAuthentication), detach: true, optionalRunArgs: runArgsBuilder.Build()); if (!Config.IsHttpVerificationDisabled) { // Verify metrics endpoint is accessible using HttpResponseMessage metricsMessage = await ImageScenarioVerifier.GetHttpResponseFromContainerAsync( monitorContainerName, DockerHelper, OutputHelper, DefaultMetricsPort, UrlPath_Metrics); string metricsContent = await metricsMessage.Content.ReadAsStringAsync(); // Metrics should not return any content if // no processes are detected. Assert.Equal(string.Empty, metricsContent); } if (null != verifyContainerAsync) { await verifyContainerAsync(monitorContainerName); } } finally { DockerHelper.DeleteContainer(monitorContainerName); } }
public async Task VerifyAspnetSample(SampleImageData imageData) { string image = imageData.GetImage(SampleImageType.Aspnetapp, DockerHelper); string containerName = imageData.GetIdentifier("sample-aspnetapp"); try { DockerHelper.Run( image: image, name: containerName, detach: true, optionalRunArgs: "-p 80"); if (!Config.IsHttpVerificationDisabled) { await ImageScenarioVerifier.VerifyHttpResponseFromContainerAsync(containerName, DockerHelper, OutputHelper); } } finally { DockerHelper.DeleteContainer(containerName); } }
/// <summary> /// Runs a single instance of each of the dotnet-monitor and samples images. /// </summary> /// <param name="monitorImageData">The image data of the dotnet-monitor image.</param> /// <param name="shareTmpVolume">Set to true to mount the /tmp directory in both containers.</param> /// <param name="listenDiagPortVolume"> /// Set to true to have the monitor container listen with a diagnostic port listener /// for diagnostic connections from the samples container. /// </param> /// <param name="noAuthentication">Set to true to disable dotnet-monitor authenication.</param> /// <param name="verifyContainerAsync">Callback to test some aspect of the containers.</param> /// <param name="monitorRunArgsCallback">Allows for modifying the "docker run" args of the dotnet-monitor container.</param> /// <param name="sampleRunArgsCallback">Allows for modifying the "docker run" args of the samples container.</param> private async Task VerifyScenarioAsync( MonitorImageData monitorImageData, SampleImageData sampleImageData, bool shareTmpVolume, bool listenDiagPortVolume, bool noAuthentication, Func <string, string, Task> verifyContainerAsync, Action <DockerRunArgsBuilder> monitorRunArgsCallback = null, Action <DockerRunArgsBuilder> sampleRunArgsCallback = null) { GetNames(monitorImageData, out string monitorImageName, out string monitorContainerName); GetNames(sampleImageData, out string sampleImageName, out string sampleContainerName); DockerRunArgsBuilder monitorArgsBuilder = DockerRunArgsBuilder.Create() .MonitorUrl(DefaultArtifactsPort); DockerRunArgsBuilder sampleArgsBuilder = DockerRunArgsBuilder.Create() .ExposePort(DefaultHttpPort); string diagPortVolumeName = null; string tmpVolumeName = null; try { // Create a volume for the two containers to share the /tmp directory. if (shareTmpVolume) { tmpVolumeName = DockerHelper.CreateVolume(UniqueName("tmpvol")); monitorArgsBuilder.VolumeMount(tmpVolumeName, Directory_Tmp); sampleArgsBuilder.VolumeMount(tmpVolumeName, Directory_Tmp); } // Create a volume so that the dotnet-monitor container can provide a // diagnostic listening port to the samples container so that the samples // process can connect to the dotnet-monitor process. if (listenDiagPortVolume) { diagPortVolumeName = DockerHelper.CreateVolume(UniqueName("diagportvol")); monitorArgsBuilder.VolumeMount(diagPortVolumeName, Directory_Diag); monitorArgsBuilder.MonitorListen(File_DiagPort); sampleArgsBuilder.VolumeMount(diagPortVolumeName, Directory_Diag); sampleArgsBuilder.RuntimeSuspend(File_DiagPort); } // Allow modification of the "docker run" args of the monitor container if (null != monitorRunArgsCallback) { monitorRunArgsCallback(monitorArgsBuilder); } // Allow modification of the "docker run" args of the samples container if (null != sampleRunArgsCallback) { sampleRunArgsCallback(sampleArgsBuilder); } // Run the sample container DockerHelper.Run( image: sampleImageName, name: sampleContainerName, detach: true, optionalRunArgs: sampleArgsBuilder.Build()); // Run the dotnet-monitor container DockerHelper.Run( image: monitorImageName, name: monitorContainerName, command: GetMonitorAdditionalArgs(noAuthentication), detach: true, optionalRunArgs: monitorArgsBuilder.Build()); await verifyContainerAsync( monitorContainerName, sampleContainerName); } finally { DockerHelper.DeleteContainer(monitorContainerName); DockerHelper.DeleteContainer(sampleContainerName); if (!string.IsNullOrEmpty(diagPortVolumeName)) { DockerHelper.DeleteVolume(diagPortVolumeName); } if (!string.IsNullOrEmpty(tmpVolumeName)) { DockerHelper.DeleteVolume(tmpVolumeName); } } }