Beispiel #1
0
        public void EqualsTest()
        {
            // Arrange
            string image = "repo/microsoft/azureiotedge-hub:002";
            var    edgeHubDockerModule = new EdgeHubDockerModule(
                "docker",
                ModuleStatus.Running,
                RestartPolicy.Always,
                new DockerConfig(image),
                new ConfigurationInfo("1"),
                new Dictionary <string, EnvVal>());

            var edgeHubDockerRuntimeModule = new EdgeHubDockerRuntimeModule(
                ModuleStatus.Running,
                RestartPolicy.Always,
                new DockerConfig(image),
                0,
                string.Empty,
                DateTime.MinValue,
                DateTime.MinValue,
                0,
                DateTime.MinValue,
                ModuleStatus.Running,
                new ConfigurationInfo("1"),
                new Dictionary <string, EnvVal>());

            // Act
            bool equal = edgeHubDockerModule.Equals(edgeHubDockerRuntimeModule);

            // Assert
            Assert.True(equal);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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 GetModulesTest()
        {
            // Arrange
            var restartPolicyManager = new Mock <IRestartPolicyManager>();

            restartPolicyManager.Setup(
                r => r.ComputeModuleStatusFromRestartPolicy(
                    It.IsAny <ModuleStatus>(),
                    It.IsAny <RestartPolicy>(),
                    It.IsAny <int>(),
                    It.IsAny <DateTime>()))
            .Returns <ModuleStatus, RestartPolicy, int, DateTime>((m, r, c, d) => m);

            string module1Hash           = Guid.NewGuid().ToString();
            string module2Hash           = Guid.NewGuid().ToString();
            string edgeHubHash           = Guid.NewGuid().ToString();
            string edgeAgentHash         = Guid.NewGuid().ToString();
            var    moduleRuntimeInfoList = new List <ModuleRuntimeInfo>();

            moduleRuntimeInfoList.Add(
                new ModuleRuntimeInfo <DockerReportedConfig>(
                    "module1",
                    "docker",
                    ModuleStatus.Stopped,
                    "dummy1",
                    0,
                    Option.Some(new DateTime(2017, 10, 10)),
                    Option.None <DateTime>(),
                    new DockerReportedConfig("mod1:v1", string.Empty, module1Hash)));
            moduleRuntimeInfoList.Add(
                new ModuleRuntimeInfo <DockerReportedConfig>(
                    "module2",
                    "docker",
                    ModuleStatus.Failed,
                    "dummy2",
                    5,
                    Option.Some(new DateTime(2017, 10, 12)),
                    Option.Some(new DateTime(2017, 10, 14)),
                    new DockerReportedConfig("mod2:v2", string.Empty, module2Hash)));
            moduleRuntimeInfoList.Add(
                new ModuleRuntimeInfo <DockerReportedConfig>(
                    "edgeHub",
                    "docker",
                    ModuleStatus.Running,
                    string.Empty,
                    0,
                    Option.Some(new DateTime(2017, 10, 10)),
                    Option.None <DateTime>(),
                    new DockerReportedConfig("edgehub:v1", string.Empty, edgeHubHash)));
            moduleRuntimeInfoList.Add(
                new ModuleRuntimeInfo <DockerReportedConfig>(
                    "edgeAgent",
                    "docker",
                    ModuleStatus.Running,
                    string.Empty,
                    0,
                    Option.Some(new DateTime(2017, 10, 10)),
                    Option.None <DateTime>(),
                    new DockerReportedConfig("edgeAgent:v1", string.Empty, edgeAgentHash)));

            var runtimeInfoProvider = Mock.Of <IRuntimeInfoProvider>(r => r.GetModules(CancellationToken.None) == Task.FromResult(moduleRuntimeInfoList.AsEnumerable()));
            var moduleStateStore    = new Mock <IEntityStore <string, ModuleState> >();

            moduleStateStore.Setup(m => m.Get("module1")).ReturnsAsync(Option.Some(new ModuleState(1, new DateTime(2017, 10, 13))));
            moduleStateStore.Setup(m => m.Get("module2")).ReturnsAsync(Option.Some(new ModuleState(2, new DateTime(2017, 10, 13))));
            moduleStateStore.Setup(m => m.Get("edgeHub")).ReturnsAsync(Option.Some(new ModuleState(3, new DateTime(2017, 10, 13))));
            moduleStateStore.Setup(m => m.Get("edgeAgent")).ReturnsAsync(Option.Some(new ModuleState(4, new DateTime(2017, 10, 13))));

            string minDockerVersion     = "20";
            string dockerLoggingOptions = "dummy logging options";

            var module1          = new DockerModule("module1", "v1", ModuleStatus.Stopped, RestartPolicy.Always, new DockerConfig("mod1:v1", "{\"Env\":[\"foo=bar\"]}"), ImagePullPolicy.OnCreate, Constants.DefaultPriority, new ConfigurationInfo(), null);
            var module2          = new DockerModule("module2", "v2", ModuleStatus.Running, RestartPolicy.OnUnhealthy, new DockerConfig("mod2:v2", "{\"Env\":[\"foo2=bar2\"]}"), ImagePullPolicy.Never, Constants.DefaultPriority, new ConfigurationInfo(), null);
            var edgeHubModule    = new EdgeHubDockerModule("docker", ModuleStatus.Running, RestartPolicy.Always, new DockerConfig("edgehub:v1", "{\"Env\":[\"foo3=bar3\"]}"), ImagePullPolicy.OnCreate, Constants.HighestPriority, new ConfigurationInfo(), null);
            var edgeAgentModule  = new EdgeAgentDockerModule("docker", new DockerConfig("edgeAgent:v1", string.Empty), ImagePullPolicy.OnCreate, new ConfigurationInfo(), null);
            var deploymentConfig = new DeploymentConfig(
                "1.0",
                new DockerRuntimeInfo("docker", new DockerRuntimeConfig(minDockerVersion, dockerLoggingOptions)),
                new SystemModules(edgeAgentModule, edgeHubModule),
                new Dictionary <string, IModule> {
                [module1.Name] = module1, [module2.Name] = module2
            });

            var environment = new DockerEnvironment(runtimeInfoProvider, deploymentConfig, moduleStateStore.Object, restartPolicyManager.Object, OperatingSystemType, Architecture, Version);

            // Act
            ModuleSet moduleSet = await environment.GetModulesAsync(CancellationToken.None);

            // Assert
            Assert.NotNull(moduleSet);
            Assert.True(moduleSet.Modules.TryGetValue("module1", out IModule receivedModule1));
            Assert.True(moduleSet.Modules.TryGetValue("module2", out IModule receivedModule2));
            Assert.True(moduleSet.Modules.TryGetValue("edgeHub", out IModule receivedEdgeHub));
            Assert.True(moduleSet.Modules.TryGetValue("edgeAgent", out IModule receivedEdgeAgent));

            var receivedDockerModule1 = receivedModule1 as DockerRuntimeModule;

            Assert.NotNull(receivedDockerModule1);
            Assert.Equal("module1", receivedDockerModule1.Name);
            Assert.Equal("v1", receivedDockerModule1.Version);
            Assert.Equal(ModuleStatus.Stopped, receivedDockerModule1.DesiredStatus);
            Assert.Equal(RestartPolicy.Always, receivedDockerModule1.RestartPolicy);
            Assert.Equal(ImagePullPolicy.OnCreate, receivedDockerModule1.ImagePullPolicy);
            Assert.Equal(Constants.DefaultPriority, receivedDockerModule1.Priority);
            Assert.Equal("mod1:v1", receivedDockerModule1.Config.Image);
            Assert.Equal("{\"Env\":[\"foo=bar\"]}", JsonConvert.SerializeObject(receivedDockerModule1.Config.CreateOptions));
            Assert.Equal(ModuleStatus.Stopped, receivedDockerModule1.RuntimeStatus);
            Assert.Equal("dummy1", receivedDockerModule1.StatusDescription);
            Assert.Equal(0, receivedDockerModule1.ExitCode);
            Assert.Equal(new DateTime(2017, 10, 10), receivedDockerModule1.LastStartTimeUtc);
            Assert.Equal(DateTime.MinValue, receivedDockerModule1.LastExitTimeUtc);
            Assert.Equal(new DateTime(2017, 10, 13), receivedDockerModule1.LastRestartTimeUtc);
            Assert.Equal(module1Hash, (receivedDockerModule1.Config as DockerReportedConfig)?.ImageHash);
            Assert.Equal(1, receivedDockerModule1.RestartCount);

            var receivedDockerModule2 = receivedModule2 as DockerRuntimeModule;

            Assert.NotNull(receivedDockerModule2);
            Assert.Equal("module2", receivedDockerModule2.Name);
            Assert.Equal("v2", receivedDockerModule2.Version);
            Assert.Equal(ModuleStatus.Running, receivedDockerModule2.DesiredStatus);
            Assert.Equal(RestartPolicy.OnUnhealthy, receivedDockerModule2.RestartPolicy);
            Assert.Equal(ImagePullPolicy.Never, receivedDockerModule2.ImagePullPolicy);
            Assert.Equal(Constants.DefaultPriority, receivedDockerModule2.Priority);
            Assert.Equal("mod2:v2", receivedDockerModule2.Config.Image);
            Assert.Equal("{\"Env\":[\"foo2=bar2\"]}", JsonConvert.SerializeObject(receivedDockerModule2.Config.CreateOptions));
            Assert.Equal(ModuleStatus.Failed, receivedDockerModule2.RuntimeStatus);
            Assert.Equal("dummy2", receivedDockerModule2.StatusDescription);
            Assert.Equal(5, receivedDockerModule2.ExitCode);
            Assert.Equal(new DateTime(2017, 10, 12), receivedDockerModule2.LastStartTimeUtc);
            Assert.Equal(new DateTime(2017, 10, 14), receivedDockerModule2.LastExitTimeUtc);
            Assert.Equal(new DateTime(2017, 10, 13), receivedDockerModule2.LastRestartTimeUtc);
            Assert.Equal(module2Hash, (receivedDockerModule2.Config as DockerReportedConfig)?.ImageHash);
            Assert.Equal(2, receivedDockerModule2.RestartCount);

            var receivedDockerEdgeHub = receivedEdgeHub as EdgeHubDockerRuntimeModule;

            Assert.NotNull(receivedDockerEdgeHub);
            Assert.Equal("edgeHub", receivedDockerEdgeHub.Name);
            Assert.Equal(string.Empty, receivedDockerEdgeHub.Version);
            Assert.Equal(ModuleStatus.Running, receivedDockerEdgeHub.DesiredStatus);
            Assert.Equal(RestartPolicy.Always, receivedDockerEdgeHub.RestartPolicy);
            Assert.Equal(ImagePullPolicy.OnCreate, receivedDockerEdgeHub.ImagePullPolicy);
            Assert.Equal(Constants.HighestPriority, receivedDockerEdgeHub.Priority);
            Assert.Equal("edgehub:v1", receivedDockerEdgeHub.Config.Image);
            Assert.Equal("{\"Env\":[\"foo3=bar3\"]}", JsonConvert.SerializeObject(receivedDockerEdgeHub.Config.CreateOptions));
            Assert.Equal(ModuleStatus.Running, receivedDockerEdgeHub.RuntimeStatus);
            Assert.Equal(string.Empty, receivedDockerEdgeHub.StatusDescription);
            Assert.Equal(0, receivedDockerEdgeHub.ExitCode);
            Assert.Equal(new DateTime(2017, 10, 10), receivedDockerEdgeHub.LastStartTimeUtc);
            Assert.Equal(DateTime.MinValue, receivedDockerEdgeHub.LastExitTimeUtc);
            Assert.Equal(new DateTime(2017, 10, 13), receivedDockerEdgeHub.LastRestartTimeUtc);
            Assert.Equal(edgeHubHash, (receivedDockerEdgeHub.Config as DockerReportedConfig)?.ImageHash);
            Assert.Equal(3, receivedDockerEdgeHub.RestartCount);

            var receivedDockerEdgeAgent = receivedEdgeAgent as EdgeAgentDockerRuntimeModule;

            Assert.NotNull(receivedDockerEdgeAgent);
            Assert.Equal("edgeAgent", receivedDockerEdgeAgent.Name);
            Assert.Equal(string.Empty, receivedDockerEdgeAgent.Version);
            Assert.Equal(ModuleStatus.Running, receivedDockerEdgeAgent.RuntimeStatus);
            Assert.Equal(ImagePullPolicy.OnCreate, receivedDockerEdgeAgent.ImagePullPolicy);
            Assert.Equal(Constants.HighestPriority, receivedDockerEdgeAgent.Priority);
            Assert.Equal("edgeAgent:v1", receivedDockerEdgeAgent.Config.Image);
            Assert.Equal("{}", JsonConvert.SerializeObject(receivedDockerEdgeAgent.Config.CreateOptions));
            Assert.Equal(new DateTime(2017, 10, 10), receivedDockerEdgeAgent.LastStartTimeUtc);
            Assert.Equal(edgeAgentHash, (receivedDockerEdgeAgent.Config as DockerReportedConfig)?.ImageHash);
        }