private IEnumerable <SdkContentFileInfo> GetActualSdkContents(ProductImageData imageData) { string dotnetPath; if (DockerHelper.IsLinuxContainerModeEnabled) { dotnetPath = "/usr/share/dotnet"; } else { dotnetPath = "Program Files\\dotnet"; } string powerShellCommand = $"Get-ChildItem -File -Force -Recurse '{dotnetPath}' " + "| Get-FileHash -Algorithm SHA512 " + "| select @{name='Value'; expression={$_.Hash + ' ' +$_.Path}} " + "| select -ExpandProperty Value"; string command = $"pwsh -Command \"{powerShellCommand}\""; string containerFileList = DockerHelper.Run( image: imageData.GetImage(ImageType, DockerHelper), command: command, name: imageData.GetIdentifier("DotnetFolder")); IEnumerable <SdkContentFileInfo> actualDotnetFiles = containerFileList .Replace("\r\n", "\n") .Split("\n") .Select(output => { string[] outputParts = output.Split(" "); return(new SdkContentFileInfo(outputParts[1], outputParts[0])); }) .OrderBy(fileInfo => fileInfo.Path) .ToArray(); return(actualDotnetFiles); }
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); } }
private IEnumerable <string> GetInstalledRpmPackages(ProductImageData imageData) { // Get list of installed RPM packages string command = $"bash -c \"rpm -qa | sort\""; string imageTag; if (imageData.IsDistroless) { imageTag = DockerHelper.BuildDistrolessHelper(ImageType, imageData, "bash", "rpm"); } else { imageTag = imageData.GetImage(ImageType, DockerHelper); } string installedPackages = DockerHelper.Run( image: imageTag, command: command, name: imageData.GetIdentifier("PackageInstallation")); return(installedPackages.Split(Environment.NewLine)); }
public ImageTests(ITestOutputHelper outputHelper) { _dockerHelper = new DockerHelper(outputHelper); _outputHelper = outputHelper; }
public static EnvironmentVariableInfo GetRuntimeVersionVariableInfo(ProductImageData imageData, DockerHelper dockerHelper) { string version = imageData.GetProductVersion(DotNetImageType.Runtime, dockerHelper); return(new EnvironmentVariableInfo("DOTNET_VERSION", version)); }
public static void Validate( IEnumerable <EnvironmentVariableInfo> variables, string imageName, ImageData imageData, DockerHelper dockerHelper) { const char delimiter = '|'; IEnumerable <string> echoParts; string invokeCommand; char delimiterEscape; string entrypoint; if (DockerHelper.IsLinuxContainerModeEnabled) { echoParts = variables.Select(envVar => $"${envVar.Name}"); entrypoint = "/bin/sh"; invokeCommand = "-c"; delimiterEscape = '\\'; } else { echoParts = variables.Select(envVar => $"%{envVar.Name}%"); entrypoint = "CMD"; invokeCommand = "/S /C"; delimiterEscape = '^'; } string combinedValues = dockerHelper.Run( image: imageName, name: imageData.GetIdentifier($"env"), optionalRunArgs: $"--entrypoint {entrypoint}", command: $"{invokeCommand} \"echo {string.Join($"{delimiterEscape}{delimiter}", echoParts)}\""); string[] values = combinedValues.Split(delimiter); Assert.Equal(variables.Count(), values.Count()); for (int i = 0; i < values.Count(); i++) { EnvironmentVariableInfo variable = variables.ElementAt(i); string actualValue; // Process unset variables in Windows if (!DockerHelper.IsLinuxContainerModeEnabled && string.Equals(values[i], $"%{variable.Name}%", StringComparison.Ordinal)) { actualValue = string.Empty; } else { actualValue = values[i]; } if (variable.AllowAnyValue) { Assert.NotEmpty(actualValue); } else { Assert.Equal(variable.ExpectedValue, actualValue); } } }
public static EnvironmentVariableInfo GetAspnetVersionVariableInfo(ProductImageData imageData, DockerHelper dockerHelper) { string versionEnvName = null; if (imageData.Version.Major == 2 && DockerHelper.IsLinuxContainerModeEnabled) { versionEnvName = "ASPNETCORE_VERSION"; } else if (imageData.Version.Major >= 5) { versionEnvName = "ASPNET_VERSION"; } if (versionEnvName != null) { string version = imageData.GetProductVersion(DotNetImageType.Aspnet, dockerHelper); return(new EnvironmentVariableInfo(versionEnvName, version)); } return(null); }
public static async Task VerifyHttpResponseFromContainerAsync(string containerName, DockerHelper dockerHelper, ITestOutputHelper outputHelper) { var retries = 30; // Can't use localhost when running inside containers or Windows. var url = !Config.IsRunningInContainer && DockerHelper.IsLinuxContainerModeEnabled ? $"http://localhost:{dockerHelper.GetContainerHostPort(containerName)}" : $"http://{dockerHelper.GetContainerAddress(containerName)}"; using (HttpClient client = new HttpClient()) { while (retries > 0) { retries--; await Task.Delay(TimeSpan.FromSeconds(2)); try { using (HttpResponseMessage result = await client.GetAsync(url)) { outputHelper.WriteLine($"HTTP {result.StatusCode}\n{(await result.Content.ReadAsStringAsync())}"); result.EnsureSuccessStatusCode(); } return; } catch (Exception ex) { outputHelper.WriteLine($"Request to {url} failed - retrying: {ex.ToString()}"); } } } throw new TimeoutException($"Timed out attempting to access the endpoint {url} on container {containerName}"); }
public ImageTests(ITestOutputHelper output) { DockerHelper = new DockerHelper(output); }
public static async Task VerifyHttpResponseFromContainerAsync(string containerName, DockerHelper dockerHelper, ITestOutputHelper outputHelper, int containerPort = 80, string pathAndQuery = null) { (await GetHttpResponseFromContainerAsync( containerName, dockerHelper, outputHelper, containerPort, pathAndQuery)).Dispose(); }
public static async Task <HttpResponseMessage> GetHttpResponseFromContainerAsync(string containerName, DockerHelper dockerHelper, ITestOutputHelper outputHelper, int containerPort = 80, string pathAndQuery = null, Action <HttpResponseMessage> validateCallback = null) { int retries = 30; // Can't use localhost when running inside containers or Windows. string url = !Config.IsRunningInContainer && DockerHelper.IsLinuxContainerModeEnabled ? $"http://localhost:{dockerHelper.GetContainerHostPort(containerName, containerPort)}/{pathAndQuery}" : $"http://{dockerHelper.GetContainerAddress(containerName)}:{containerPort}/{pathAndQuery}"; using (HttpClient client = new HttpClient()) { while (retries > 0) { retries--; await Task.Delay(TimeSpan.FromSeconds(2)); HttpResponseMessage result = null; try { result = await client.GetAsync(url); outputHelper.WriteLine($"HTTP {result.StatusCode}\n{(await result.Content.ReadAsStringAsync())}"); if (null == validateCallback) { result.EnsureSuccessStatusCode(); } else { validateCallback(result); } // Store response in local that will not be disposed HttpResponseMessage returnResult = result; result = null; return(returnResult); } catch (Exception ex) { outputHelper.WriteLine($"Request to {url} failed - retrying: {ex}"); } finally { result?.Dispose(); } } } throw new TimeoutException($"Timed out attempting to access the endpoint {url} on container {containerName}"); }
public MonitorImageTests(ITestOutputHelper outputHelper) { OutputHelper = outputHelper; DockerHelper = new DockerHelper(outputHelper); }
/// <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); } } }
public SampleImageTests(ITestOutputHelper outputHelper) { OutputHelper = outputHelper; DockerHelper = new DockerHelper(outputHelper); }
protected ImageTests(ITestOutputHelper outputHelper) { DockerHelper = new DockerHelper(outputHelper); OutputHelper = outputHelper; }
private string GetRuntimeVersion(string imageName, string containerName, string runtimeName, DockerHelper dockerHelper) { const string versionGroupName = "Version"; string runtimeListing = dockerHelper.Run(imageName, containerName, "dotnet --list-runtimes"); Regex versionRegex = new Regex($"{runtimeName} (?<{versionGroupName}>[^\\s]+) "); Match match = versionRegex.Match(runtimeListing); return(match.Success ? match.Groups[versionGroupName].Value : string.Empty); }
public static EnvironmentVariableInfo GetAspnetVersionVariableInfo(ProductImageData imageData, DockerHelper dockerHelper) { if (imageData.Version.Major >= 5) { string version = imageData.GetProductVersion(DotNetImageType.Aspnet, dockerHelper); return(new EnvironmentVariableInfo("ASPNET_VERSION", version)); } return(null); }