public void BasicTest() { var edgeAgentModule = Mock.Of <IEdgeAgentModule>(m => m.Name == "edgeAgent"); var edgeHubModule = Mock.Of <IEdgeHubModule>(m => m.Name == "edgeHub"); var systemModules = new SystemModules(edgeAgentModule, edgeHubModule); var mod1 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod1"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultPriority, new ConfigurationInfo(), null); var mod2 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod2"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultPriority, new ConfigurationInfo(), null); var modules = new Dictionary <string, IModule> { ["mod1"] = mod1, ["mod2"] = mod2 }; var deploymentConfig = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), systemModules, modules); Assert.Equal("mod1", deploymentConfig.Modules["mod1"].Name); Assert.Equal("mod2", deploymentConfig.Modules["mod2"].Name); ModuleSet moduleSet = deploymentConfig.GetModuleSet(); Assert.NotNull(moduleSet); Assert.Equal(4, moduleSet.Modules.Count); Assert.Equal(edgeHubModule.Name, moduleSet.Modules["edgeHub"].Name); Assert.Equal(edgeAgentModule.Name, moduleSet.Modules["edgeAgent"].Name); Assert.Equal(modules["mod1"].Name, moduleSet.Modules["mod1"].Name); Assert.Equal(modules["mod2"].Name, moduleSet.Modules["mod2"].Name); }
public async Task TestEnvVars() { const string Image = "hello-world:latest"; const string Name = "test-env"; string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("deviceKey")); string fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}"; try { using (var cts = new CancellationTokenSource(Timeout)) { await Client.CleanupContainerAsync(Name, Image); string createOptions = @"{""Env"": [ ""k1=v1"", ""k2=v2""]}"; var config = new DockerConfig(Image, createOptions); var loggingConfig = new DockerLoggingConfig("json-file"); var module = new DockerModule(Name, "1.0", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.OnUnhealthy, config, null, null); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { "EdgeDeviceConnectionString", fakeConnectionString } }).Build(); var deploymentConfigModules = new Dictionary <string, IModule> { [Name] = module }; var systemModules = new SystemModules(null, null); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", string.Empty)), systemModules, deploymentConfigModules)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); var credential = new ConnectionStringCredentials("fake"); var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(credential); ICommand create = await CreateCommand.BuildAsync(Client, module, identity.Object, loggingConfig, configSource.Object, false); await Client.PullImageAsync(Image, cts.Token); // create module using command await create.ExecuteAsync(cts.Token); // check that the environment variables are being returned RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(Client); IEnumerable <ModuleRuntimeInfo> modules = await runtimeInfoProvider.GetModules(cts.Token); var returnedModule = modules.First(m => m.Name == Name) as ModuleRuntimeInfo <DockerReportedConfig>; Assert.NotNull(returnedModule); } } finally { await Client.CleanupContainerAsync(Name, Image); await Client.CleanupContainerAsync("test-filters-external", Image); } }
public void BasicTest(string[] signercert, string[] intermediatecacert, string signature, string algo) { var edgeAgentModule = Mock.Of <IEdgeAgentModule>(m => m.Name == "edgeAgent"); var edgeHubModule = Mock.Of <IEdgeHubModule>(m => m.Name == "edgeHub"); var systemModules = new SystemModules(edgeAgentModule, edgeHubModule); var mod1 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod1"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultStartupOrder, new ConfigurationInfo(), null); var mod2 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod2"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultStartupOrder, new ConfigurationInfo(), null); var modules = new Dictionary <string, IModule> { ["mod1"] = mod1, ["mod2"] = mod2 }; var deploymentConfig = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), systemModules, modules, null); ManifestIntegrity integrity = new ManifestIntegrity(new TwinHeader(signercert, intermediatecacert), new TwinSignature(signature, algo)); var deploymentConfigWithTwinIntegrity = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), systemModules, modules, integrity); Assert.Equal("mod1", deploymentConfig.Modules["mod1"].Name); Assert.Equal("mod2", deploymentConfig.Modules["mod2"].Name); ModuleSet moduleSet = deploymentConfig.GetModuleSet(); Assert.NotNull(moduleSet); Assert.Equal(4, moduleSet.Modules.Count); Assert.Equal(edgeHubModule.Name, moduleSet.Modules["edgeHub"].Name); Assert.Equal(edgeAgentModule.Name, moduleSet.Modules["edgeAgent"].Name); Assert.Equal(modules["mod1"].Name, moduleSet.Modules["mod1"].Name); Assert.Equal(modules["mod2"].Name, moduleSet.Modules["mod2"].Name); Assert.Equal(deploymentConfigWithTwinIntegrity.Integrity, Option.Some(integrity)); }
private void GetProcessModules() { var modules = ProcessModel.Process.Modules; for (var i = 0; i < modules.Count; i++) { var module = modules[i]; SystemModules.Add(module); } }
public static DeploymentConfigInfo SetupNonEmptyDeployment(string moduleName = "m1") { var runtime = Mock.Of <IRuntimeInfo>(); var m1 = Mock.Of <IModule>(); var modules = new Dictionary <string, IModule> { [moduleName] = m1 }; SystemModules systemMods = new SystemModules(Option.None <IEdgeAgentModule>(), Option.None <IEdgeHubModule>()); return(new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtime, systemMods, modules))); }
public static DeploymentConfigInfo SetupNonEmptyDeployment(string moduleName = "m1") { var runtime = Mock.Of <IRuntimeInfo>(); var m1 = Mock.Of <IModule>(); var modules = new Dictionary <string, IModule> { [moduleName] = m1 }; SystemModules systemMods = new SystemModules(Option.None <IEdgeAgentModule>(), Option.None <IEdgeHubModule>()); var integrity = new ManifestIntegrity(new TwinHeader(new string[] { "signercert1", "signercert2" }, new string[] { "intermediatecacert1", "intermediatecacert2" }), new TwinSignature("bytes", "algo")); return(new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtime, systemMods, modules, integrity))); }
public async void GetDeploymentConfigTest2() { // Arrange var runtimeInfo = Mock.Of <IRuntimeInfo>(); var edgeHubModule = Mock.Of <IEdgeHubModule>(m => m.Name == "$edgeHub"); var edgeAgentModule = Mock.Of <IEdgeAgentModule>(m => m.Name == "$edgeAgent"); var systemModules = new SystemModules(edgeAgentModule, edgeHubModule); string customModule1Name = null; string customModule2Name = null; var customModule1 = Mock.Of <IModule>(); var customModule2 = Mock.Of <IModule>(); Mock.Get(customModule1).SetupSet(n => n.Name = It.IsAny <string>()).Callback <string>(n => customModule1Name = n); Mock.Get(customModule2).SetupSet(n => n.Name = It.IsAny <string>()).Callback <string>(n => customModule2Name = n); IDictionary <string, IModule> modules = new Dictionary <string, IModule> { ["module1"] = customModule1, ["module2"] = customModule2 }; var deploymentConfig = new DeploymentConfig("1.0", runtimeInfo, systemModules, modules); var deploymentConfigInfo = new DeploymentConfigInfo(5, deploymentConfig); var edgeAgentConnection = new Mock <IEdgeAgentConnection>(); edgeAgentConnection.Setup(e => e.GetDeploymentConfigInfoAsync()).ReturnsAsync(Option.Some(deploymentConfigInfo)); var configuration = Mock.Of <IConfiguration>(); var twinConfigSource = new TwinConfigSource(edgeAgentConnection.Object, configuration); // Act DeploymentConfigInfo receivedDeploymentConfigInfo = await twinConfigSource.GetDeploymentConfigInfoAsync(); // Assert Assert.NotNull(receivedDeploymentConfigInfo); Assert.NotNull(receivedDeploymentConfigInfo.DeploymentConfig); Assert.Equal(5, receivedDeploymentConfigInfo.Version); DeploymentConfig returnedDeploymentConfig = receivedDeploymentConfigInfo.DeploymentConfig; Assert.Equal(Option.Some(edgeAgentModule), returnedDeploymentConfig.SystemModules.EdgeAgent); Assert.Equal(Option.Some(edgeHubModule), returnedDeploymentConfig.SystemModules.EdgeHub); ModuleSet moduleSet = returnedDeploymentConfig.GetModuleSet(); Assert.Equal(4, returnedDeploymentConfig.GetModuleSet().Modules.Count); Assert.Equal(customModule1.Name, moduleSet.Modules["module1"].Name); Assert.Equal(customModule2.Name, moduleSet.Modules["module2"].Name); Assert.Equal(edgeHubModule.Name, moduleSet.Modules["$edgeHub"].Name); Assert.Equal(edgeAgentModule.Name, moduleSet.Modules["$edgeAgent"].Name); Assert.Equal("module1", customModule1Name); Assert.Equal("module2", customModule2Name); }
public AgentState( long lastDesiredVersion = 0, DeploymentStatus lastDesiredStatus = null, IRuntimeInfo runtimeInfo = null, SystemModules systemModules = null, IDictionary <string, IModule> modules = null, string schemaVersion = "", VersionInfo version = null) { this.SchemaVersion = schemaVersion ?? string.Empty; this.Version = version ?? VersionInfo.Empty; this.LastDesiredVersion = lastDesiredVersion; this.LastDesiredStatus = lastDesiredStatus ?? DeploymentStatus.Unknown; this.RuntimeInfo = runtimeInfo; this.SystemModules = systemModules ?? new SystemModules(UnknownEdgeAgentModule.Instance, UnknownEdgeHubModule.Instance); this.Modules = modules?.ToImmutableDictionary() ?? ImmutableDictionary <string, IModule> .Empty; }
public void SetProcess(ProcessModel processModel, string gameLanguage = "English", string patchVersion = "latest", bool useLocalCache = true, bool scanAllMemoryRegions = false) { ProcessModel = processModel; GameLanguage = gameLanguage; UseLocalCache = useLocalCache; UnsetProcess(); try { ProcessHandle = UnsafeNativeMethods.OpenProcess(UnsafeNativeMethods.ProcessAccessFlags.PROCESS_VM_ALL, false, (uint)ProcessModel.ProcessID); } catch (Exception) { ProcessHandle = processModel.Process.Handle; } finally { Constants.ProcessHandle = ProcessHandle; IsAttached = true; } if (IsNewInstance) { IsNewInstance = false; ActionHelper.Resolve(); StatusEffectHelper.Resolve(); ZoneHelper.Resolve(); ResolveMemoryStructures(processModel, patchVersion); } AttachmentWorker = new AttachmentWorker(); AttachmentWorker.StartScanning(processModel); SystemModules.Clear(); GetProcessModules(); Scanner.Instance.Locations.Clear(); Scanner.Instance.LoadOffsets(Signatures.Resolve(processModel, patchVersion), scanAllMemoryRegions); }
public async Task UpstreamProtocolTest() { const string Image = "hello-world:latest"; const string Name = "test-helloworld"; string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")); string fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}"; try { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15))) { // Arrange await DockerHelper.Client.CleanupContainerAsync(Name, Image); // ensure image has been pulled await DockerHelper.Client.PullImageAsync(Image, cts.Token); var dockerLoggingOptions = new Dictionary <string, string> { { "max-size", "1m" }, { "max-file", "1" } }; // Logging options will be derived from these default logging options var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions); var config = new DockerConfig(Image, @"{""Env"": [""k1=v1"", ""k2=v2""], ""HostConfig"": {""PortBindings"": {""8080/tcp"": [{""HostPort"": ""80""}]}}}"); var module = new DockerModule(Name, "1.0", ModuleStatus.Running, Core.RestartPolicy.OnUnhealthy, config, null, EnvVars); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { "EdgeHubConnectionString", fakeConnectionString }, { Constants.EdgeModuleCaCertificateFileKey, "/module.ca.cert" }, { "UpstreamProtocol", "AmqpWs" } }).Build(); var modules = new Dictionary <string, IModule> { [Name] = module }; var systemModules = new SystemModules(null, null); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", "")), systemModules, modules)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(fakeConnectionString)); ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, false); // Act // run the command await command.ExecuteAsync(cts.Token); // Assert // verify container is created and has correct settings ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name); Assert.Equal(Name, container.Name.Substring(1)); // for whatever reason the container name is returned with a starting "/" Assert.Equal("1.0", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing")); // port mapping Assert.Equal("8080/tcp", container.HostConfig.PortBindings.First().Key); // logging Assert.Equal("json-file", container.HostConfig.LogConfig.Type); Assert.True(container.HostConfig.LogConfig.Config.Count == 2); Assert.Equal("1m", container.HostConfig.LogConfig.Config.GetOrElse("max-size", "missing")); Assert.Equal("1", container.HostConfig.LogConfig.Config.GetOrElse("max-file", "missing")); // environment variables IDictionary <string, string> envMap = container.Config.Env.ToDictionary('='); Assert.Equal("v1", envMap["k1"]); Assert.Equal("v2", envMap["k2"]); Assert.Equal("AmqpWs", envMap["UpstreamProtocol"]); Assert.Equal(fakeConnectionString, envMap["EdgeHubConnectionString"]); // certificates env variables Assert.Equal("/module.ca.cert", envMap[Constants.EdgeModuleCaCertificateFileKey]); } } finally { await DockerHelper.Client.CleanupContainerAsync(Name, Image); } }
public async Task TestMountModuleVolume() { // Arrange const string VolumeName = "vol1"; const string VolumePath = "/azure-edge/vol1"; CreateContainerParameters createContainerParameters = null; var containerOperations = new Mock <IContainerOperations>(); containerOperations.Setup(co => co.CreateContainerAsync(It.IsAny <CreateContainerParameters>(), It.IsAny <CancellationToken>())) .Callback((CreateContainerParameters ccp, CancellationToken tok) => createContainerParameters = ccp) .ReturnsAsync(new CreateContainerResponse()); var dockerClient = new Mock <IDockerClient>(); dockerClient.SetupGet(c => c.Containers) .Returns(containerOperations.Object); var moduleIdentity = new Mock <IModuleIdentity>(); moduleIdentity.SetupGet(i => i.Credentials) .Returns(new ConnectionStringCredentials(string.Empty)); var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >(); runtimeInfo.SetupGet(r => r.Config) .Returns(new DockerRuntimeConfig("1.25", string.Empty)); var systemModules = new SystemModules( this.CreateMockEdgeAgentModule(), this.CreateMockEdgeHubModule() ); IConfigurationRoot configuration = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { Constants.EdgeModuleVolumeNameKey, VolumeName }, { Constants.EdgeModuleVolumePathKey, VolumePath } } ).Build(); var configSource = new Mock <IConfigSource>(); var deploymentConfig = new DeploymentConfig( "1.0", runtimeInfo.Object, systemModules, ImmutableDictionary <string, IModule> .Empty ); var deploymentConfigInfo = new DeploymentConfigInfo(10, deploymentConfig); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()) .ReturnsAsync(deploymentConfigInfo); configSource.SetupGet(cs => cs.Configuration) .Returns(configuration); // Act ICommand createCommand = await CreateCommand.BuildAsync( dockerClient.Object, new DockerModule( "mod1", "1.0", ModuleStatus.Running, Core.RestartPolicy.OnUnhealthy, new DockerConfig("image1"), new ConfigurationInfo("1234"), EnvVars ), moduleIdentity.Object, new DockerLoggingConfig("json"), configSource.Object, false); await createCommand.ExecuteAsync(CancellationToken.None); // Assert Assert.NotNull(createContainerParameters); Assert.Contains($"{VolumeName}:{VolumePath}:ro", createContainerParameters.HostConfig.Binds); }
public async Task EdgeHubLaunchWithBadLogOptions() { const string Image = "hello-world:latest"; const string Name = Constants.EdgeHubModuleName; string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")); string fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}"; try { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15))) { await DockerHelper.Client.CleanupContainerAsync(Name, Image); // ensure image has been pulled await DockerHelper.Client.PullImageAsync(Image, cts.Token); var dockerLoggingOptions = new Dictionary <string, string> { { "max-size", "1m" }, { "max-file", "1" } }; var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions); var config = new DockerConfig(Image, @"{""Env"": [""k1=v1"", ""k2=v2""]}"); var configurationInfo = new ConfigurationInfo("43"); var module = new EdgeHubDockerModule("docker", ModuleStatus.Running, Core.RestartPolicy.Always, config, configurationInfo, EnvVars); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { "EdgeHubConnectionString", fakeConnectionString } }).Build(); var modules = new Dictionary <string, IModule> { [Name] = module }; var systemModules = new SystemModules(null, null); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", "Not a valid JSON")), systemModules, modules)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(fakeConnectionString)); ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, true); // run the command await command.ExecuteAsync(cts.Token); // verify container is created with correct settings ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name); Assert.Equal(Name, container.Name.Substring(1)); // for whatever reason the container name is returned with a starting "/" // labels - edgeHub doesn's have a version Assert.Equal("missing", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing")); Assert.Equal("43", container.Config.Labels.GetOrElse(Constants.Labels.ConfigurationId, "missing")); // port bindings - check that we added default bindings for hub Assert.True(container.HostConfig.PortBindings.ContainsKey("8883/tcp")); Assert.True(container.HostConfig.PortBindings["8883/tcp"].Count == 1); Assert.Equal("8883", container.HostConfig.PortBindings["8883/tcp"].First().HostPort); Assert.True(container.HostConfig.PortBindings.ContainsKey("443/tcp")); Assert.True(container.HostConfig.PortBindings["443/tcp"].Count == 1); Assert.Equal("443", container.HostConfig.PortBindings["443/tcp"][0].HostPort); // logging Assert.Equal("json-file", container.HostConfig.LogConfig.Type); Assert.True(container.HostConfig.LogConfig.Config.Count == 2); Assert.Equal("1m", container.HostConfig.LogConfig.Config.GetOrElse("max-size", "missing")); Assert.Equal("1", container.HostConfig.LogConfig.Config.GetOrElse("max-file", "missing")); // environment variables IDictionary <string, string> envMap = container.Config.Env.ToDictionary('='); Assert.Equal("v1", envMap["k1"]); Assert.Equal("v2", envMap["k2"]); Assert.Equal(fakeConnectionString, envMap[Constants.IotHubConnectionStringKey]); } } finally { await DockerHelper.Client.CleanupContainerAsync(Name, Image); } }
public async Task TestUdpModuleConfig() { const string Image = "hello-world:latest"; const string Name = "test-helloworld"; string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")); string fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}"; try { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15))) { await DockerHelper.Client.CleanupContainerAsync(Name, Image); // ensure image has been pulled await DockerHelper.Client.PullImageAsync(Image, cts.Token); var loggingConfig = new DockerLoggingConfig("json-file"); var config = new DockerConfig(Image, @"{""HostConfig"": {""PortBindings"": {""42/udp"": [{""HostPort"": ""42""}]}}}"); var module = new DockerModule(Name, "1.0", ModuleStatus.Running, Core.RestartPolicy.OnUnhealthy, config, null, EnvVars); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary <string, string> { { "EdgeHubConnectionString", fakeConnectionString } }).Build(); // Logging options will be derived from application level configuration var modules = new Dictionary <string, IModule> { [Name] = module }; var systemModules = new SystemModules(null, null); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", @"{""Type"":""json-file"",""Config"":{""max-size"":""100M""}}")), systemModules, modules)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); string credential = "fake"; var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(credential)); ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, false); // run the command await command.ExecuteAsync(cts.Token); // verify container is created with correct settings. ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name); Assert.Equal(Name, container.Name.Substring(1)); // for whatever reason the container name is returned with a starting "/" Assert.Equal("1.0", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing")); // port bindings Assert.Equal(1, container.HostConfig.PortBindings.Count); Assert.False(container.HostConfig.PortBindings.ContainsKey("8883/tcp")); Assert.False(container.HostConfig.PortBindings.ContainsKey("443/tcp")); // logging Assert.Equal("json-file", container.HostConfig.LogConfig.Type); Assert.True(container.HostConfig.LogConfig.Config.Count == 1); Assert.Equal("100M", container.HostConfig.LogConfig.Config["max-size"]); } } finally { await DockerHelper.Client.CleanupContainerAsync(Name, Image); } }
public async Task TestFilters() { const string Image = "hello-world:latest"; const string Name = "test-filters"; string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")); string fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}"; try { using (var cts = new CancellationTokenSource(Timeout)) { await Client.CleanupContainerAsync(Name, Image); await Client.CleanupContainerAsync("test-filters-external", Image); var loggingConfig = new DockerLoggingConfig("json-file"); var config = new DockerConfig(Image); var module = new DockerModule(Name, "1.0", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.OnUnhealthy, config, ImagePullPolicy.OnCreate, Constants.DefaultStartupOrder, null, null); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { "EdgeDeviceConnectionString", fakeConnectionString } }).Build(); var deploymentConfigModules = new Dictionary <string, IModule> { [Name] = module }; var systemModules = new SystemModules(null, null); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", string.Empty)), systemModules, deploymentConfigModules, null)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); var credential = new ConnectionStringCredentials("fake"); var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(credential); ICommand create = await CreateCommand.BuildAsync(Client, module, identity.Object, loggingConfig, configSource.Object, false); // pull the image for both containers await Client.PullImageAsync(Image, cts.Token); // pull and create module using commands await create.ExecuteAsync(cts.Token); var createParams = new CreateContainerParameters { Name = "test-filters-external", Image = Image, }; await Client.Containers.CreateContainerAsync(createParams); // Check that only containers created via command are listed in the environment RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(Client); IEnumerable <ModuleRuntimeInfo> modules = await runtimeInfoProvider.GetModules(cts.Token); Assert.Single(modules); Assert.Equal(module.Name, modules.First().Name); } } finally { await Client.CleanupContainerAsync(Name, Image); await Client.CleanupContainerAsync("test-filters-external", Image); } }
public async Task EdgeHubLaunch() { const string Image = "hello-world:latest"; const string Name = Constants.EdgeHubModuleName; string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")); string fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}"; try { using (var cts = new CancellationTokenSource(this.defaultTimeout)) { var mountMap = new Dictionary <string, string>() { { Constants.EdgeModuleCaCertificateFileKey, "/module.ca.cert" }, { Constants.EdgeModuleHubServerCaChainCertificateFileKey, "/module.ca.chain.cert" }, { Constants.EdgeModuleHubServerCertificateFileKey, "/module.server.cert" } }; await DockerHelper.Client.CleanupContainerAsync(Name, Image); // ensure image has been pulled await DockerHelper.Client.PullImageAsync(Image, cts.Token); var dockerLoggingOptions = new Dictionary <string, string> { { "max-size", "1m" }, { "max-file", "1" } }; var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions); // Logging options will be derived from module options. var config = new DockerConfig(Image, @"{""Env"": [""k1=v1"", ""k2=v2""], ""HostConfig"": {""LogConfig"": {""Type"":""none""}, ""PortBindings"": {""8080/tcp"": [{""HostPort"": ""80""}],""443/tcp"": [{""HostPort"": ""11443""}]}}}", Option.None <string>()); var configurationInfo = new ConfigurationInfo(); var module = new EdgeHubDockerModule("docker", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, config, ImagePullPolicy.Never, Constants.HighestPriority, configurationInfo, EnvVars); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { "EdgeHubConnectionString", fakeConnectionString }, { Constants.NetworkIdKey, "testnetwork" }, { Constants.EdgeDeviceHostNameKey, "testdevice" }, { Constants.EdgeModuleHubServerCaChainCertificateFileKey, mountMap[Constants.EdgeModuleHubServerCaChainCertificateFileKey] }, { Constants.EdgeModuleHubServerCertificateFileKey, mountMap[Constants.EdgeModuleHubServerCertificateFileKey] }, }).Build(); var modules = new Dictionary <string, IModule> { [Name] = module }; var systemModules = new SystemModules(null, null); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", string.Empty)), systemModules, modules, null)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(fakeConnectionString)); ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, true); // run the command await command.ExecuteAsync(cts.Token); // verify container is created with correct settings ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name); Assert.Equal(Name, container.Name.Substring(1)); // for whatever reason the container name is returned with a starting "/" // edgeHub doesn't have a version Assert.Equal("missing", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing")); // port bindings - added default bindings for edgeHub Assert.True(container.HostConfig.PortBindings.ContainsKey("8080/tcp")); Assert.True(container.HostConfig.PortBindings.ContainsKey("8883/tcp")); Assert.Equal("8883", container.HostConfig.PortBindings["8883/tcp"].First().HostPort); Assert.True(container.HostConfig.PortBindings.ContainsKey("443/tcp")); Assert.True(container.HostConfig.PortBindings["443/tcp"].Count == 2); Assert.Equal("11443", container.HostConfig.PortBindings["443/tcp"][0].HostPort); Assert.Equal("443", container.HostConfig.PortBindings["443/tcp"][1].HostPort); // logging Assert.Equal("none", container.HostConfig.LogConfig.Type); Assert.True(container.HostConfig.LogConfig.Config.Count == 0); // network settings Assert.Equal("testdevice", container.NetworkSettings.Networks.GetOrElse("testnetwork", new EndpointSettings()).Aliases.FirstOrDefault()); Assert.Equal("testdevice", container.NetworkSettings.Networks.GetOrElse("testnetwork", new EndpointSettings()).Aliases.FirstOrDefault()); // environment variables IDictionary <string, string> envMap = container.Config.Env.ToDictionary('='); Assert.Equal("v1", envMap["k1"]); Assert.Equal("v2", envMap["k2"]); Assert.Equal(fakeConnectionString, envMap[Constants.IotHubConnectionStringKey]); // certificates env variables Assert.Equal("/module.ca.chain.cert", envMap[Constants.EdgeModuleHubServerCaChainCertificateFileKey]); Assert.Equal("/module.server.cert", envMap[Constants.EdgeModuleHubServerCertificateFileKey]); } } finally { await DockerHelper.Client.CleanupContainerAsync(Name, Image); } }
public async Task AgentStartsUpModules(TestConfig testConfig) { // Build the docker host URL. string dockerHostUrl = ConfigHelper.TestConfig["dockerHostUrl"]; DockerClient client = new DockerClientConfiguration(new Uri(dockerHostUrl)).CreateClient(); try { // Remove any running containers with the same name that may be a left-over // from previous test runs. await RemoveContainer(client, testConfig); // Initialize docker configuration for this module. DockerConfig dockerConfig = testConfig.ImageCreateOptions != null ? new DockerConfig(testConfig.Image, testConfig.ImageCreateOptions) : new DockerConfig(testConfig.Image); // Initialize an Edge Agent module object. var dockerModule = new DockerModule( testConfig.Name, testConfig.Version, ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.OnUnhealthy, dockerConfig, null, null); var modules = new Dictionary <string, IModule> { [testConfig.Name] = dockerModule }; var systemModules = new SystemModules(null, null); // Start up the agent and run a "reconcile". var dockerLoggingOptions = new Dictionary <string, string> { { "max-size", "1m" }, { "max-file", "1" } }; var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions); string sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")); IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary <string, string> { { "DeviceConnectionString", $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}" } }).Build(); var runtimeConfig = new DockerRuntimeConfig("1.24.0", "{}"); var runtimeInfo = new DockerRuntimeInfo("docker", runtimeConfig); var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtimeInfo, systemModules, modules)); var configSource = new Mock <IConfigSource>(); configSource.Setup(cs => cs.Configuration).Returns(configRoot); configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo); // TODO: Fix this up with a real reporter. But before we can do that we need to use // the real configuration source that talks to IoT Hub above. NullReporter reporter = NullReporter.Instance; var restartStateStore = Mock.Of <IEntityStore <string, ModuleState> >(); var configStore = Mock.Of <IEntityStore <string, string> >(); var deploymentConfigInfoSerde = Mock.Of <ISerde <DeploymentConfigInfo> >(); IRestartPolicyManager restartManager = new Mock <IRestartPolicyManager>().Object; var dockerCommandFactory = new DockerCommandFactory(client, loggingConfig, configSource.Object, new CombinedDockerConfigProvider(Enumerable.Empty <AuthConfig>())); IRuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(client); IEnvironmentProvider environmentProvider = await DockerEnvironmentProvider.CreateAsync(runtimeInfoProvider, restartStateStore, restartManager); var logFactoryMock = new Mock <ILoggerFactory>(); var logMock = new Mock <ILogger <LoggingCommandFactory> >(); logFactoryMock.Setup(l => l.CreateLogger(It.IsAny <string>())) .Returns(logMock.Object); var commandFactory = new LoggingCommandFactory(dockerCommandFactory, logFactoryMock.Object); var credential = new ConnectionStringCredentials("fake"); var identity = new Mock <IModuleIdentity>(); identity.Setup(id => id.Credentials).Returns(credential); identity.Setup(id => id.ModuleId).Returns(testConfig.Name); IImmutableDictionary <string, IModuleIdentity> identities = new Dictionary <string, IModuleIdentity>() { [testConfig.Name] = identity.Object }.ToImmutableDictionary(); var moduleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>(); moduleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(It.IsAny <ModuleSet>(), It.IsAny <ModuleSet>())).Returns(Task.FromResult(identities)); Agent agent = await Agent.Create( configSource.Object, new RestartPlanner(commandFactory), new OrderedPlanRunner(), reporter, moduleIdentityLifecycleManager.Object, environmentProvider, configStore, deploymentConfigInfoSerde, NullEncryptionProvider.Instance); await agent.ReconcileAsync(CancellationToken.None); // Sometimes the container is still not ready by the time we run the validator. // So we attempt validation multiple times and bail only if all of them fail. bool validated = false; int attempts = 0; const int MaxAttempts = 5; while (!validated && attempts < MaxAttempts) { validated = testConfig.Validator.Validate(); if (!validated) { Thread.Sleep(TimeSpan.FromSeconds(5)); } ++attempts; } Assert.Equal(true, validated); } finally { await RemoveContainer(client, testConfig); } }