예제 #1
0
        public async Task GetLogsTest()
        {
            // Arrange
            string id        = "mod1";
            string dummyLogs = new string('*', 1000);

            Stream GetLogsStream() => new MemoryStream(Encoding.UTF8.GetBytes(dummyLogs));

            var moduleManager = new Mock <IModuleManager>();

            moduleManager.Setup(m => m.GetModuleLogs(id, It.IsAny <bool>(), It.IsAny <Option <int> >(), It.IsAny <Option <int> >(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(GetLogsStream);

            var runtimeInfoProvider = new RuntimeInfoProvider <TestConfig>(moduleManager.Object);

            // Act
            Stream receivedLogsStream = await runtimeInfoProvider.GetModuleLogs(id, false, Option.None <int>(), Option.None <int>(), CancellationToken.None);

            // Assert
            var buffer    = new byte[1024];
            int readBytes = await receivedLogsStream.ReadAsync(buffer);

            Assert.Equal(1000, readBytes);
            string receivedLogs = Encoding.UTF8.GetString(buffer, 0, readBytes);

            Assert.Equal(dummyLogs, receivedLogs);
        }
예제 #2
0
        public async Task GetSystemInfoTest()
        {
            // Arrange
            var systemInfoResponse = new SystemInfoResponse
            {
                OSType       = OperatingSystemType,
                Architecture = Architecture
            };

            var dockerClient = Mock.Of <IDockerClient>(
                dc =>
                dc.System == Mock.Of <ISystemOperations>(so => so.GetSystemInfoAsync(default(CancellationToken)) == Task.FromResult(systemInfoResponse)));

            var inputRuntimeInfo = new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.13", string.Empty));

            // Act
            RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(dockerClient);

            SystemInfo systemInfo = await runtimeInfoProvider.GetSystemInfo();

            // Assert
            Assert.NotNull(systemInfo);
            Assert.Equal(systemInfo.OperatingSystemType, systemInfoResponse.OSType);
            Assert.Equal(systemInfo.Architecture, systemInfoResponse.Architecture);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        public async Task GetModuleLogsTest()
        {
            // Arrange
            string id        = "mod1";
            string dummyLogs = new string('*', 1000);

            Stream GetLogsStream() => new MemoryStream(Encoding.UTF8.GetBytes(dummyLogs));

            var systemInfoResponse = new SystemInfoResponse
            {
                OSType       = OperatingSystemType,
                Architecture = Architecture
            };

            ContainerLogsParameters receivedContainerLogsParameters = null;
            var containerOperations = new Mock <IContainerOperations>();

            containerOperations.Setup(co => co.GetContainerLogsAsync(id, It.IsAny <ContainerLogsParameters>(), It.IsAny <CancellationToken>()))
            .Callback <string, ContainerLogsParameters, CancellationToken>((m, c, t) => receivedContainerLogsParameters = c)
            .ReturnsAsync(GetLogsStream);

            var dockerClient = Mock.Of <IDockerClient>(
                dc =>
                dc.Containers == containerOperations.Object &&
                dc.System == Mock.Of <ISystemOperations>(so => so.GetSystemInfoAsync(default(CancellationToken)) == Task.FromResult(systemInfoResponse)));
            var runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(dockerClient);

            // Act
            Stream receivedLogsStream = await runtimeInfoProvider.GetModuleLogs(id, false, Option.None <int>(), CancellationToken.None);

            // Assert
            Assert.NotNull(receivedContainerLogsParameters);
            Assert.False(receivedContainerLogsParameters.Follow);
            Assert.Null(receivedContainerLogsParameters.Tail);
            Assert.True(receivedContainerLogsParameters.ShowStderr);
            Assert.True(receivedContainerLogsParameters.ShowStdout);
            var buffer    = new byte[1024];
            int readBytes = await receivedLogsStream.ReadAsync(buffer);

            Assert.Equal(1000, readBytes);
            string receivedLogs = Encoding.UTF8.GetString(buffer, 0, readBytes);

            Assert.Equal(dummyLogs, receivedLogs);

            // Act
            receivedLogsStream = await runtimeInfoProvider.GetModuleLogs(id, true, Option.Some(1000), CancellationToken.None);

            // Assert
            Assert.NotNull(receivedContainerLogsParameters);
            Assert.True(receivedContainerLogsParameters.Follow);
            Assert.Equal("1000", receivedContainerLogsParameters.Tail);
            Assert.True(receivedContainerLogsParameters.ShowStderr);
            Assert.True(receivedContainerLogsParameters.ShowStdout);
            buffer    = new byte[1024];
            readBytes = await receivedLogsStream.ReadAsync(buffer);

            Assert.Equal(1000, readBytes);
            receivedLogs = Encoding.UTF8.GetString(buffer, 0, readBytes);
            Assert.Equal(dummyLogs, receivedLogs);
        }
예제 #5
0
        public async Task GetModulesTest()
        {
            // Arrange
            string module1Hash = Guid.NewGuid().ToString();
            var    module1     = new ModuleRuntimeInfo <TestConfig>(
                "module1",
                "docker",
                ModuleStatus.Running,
                "running",
                0,
                Option.Some(new DateTime(2010, 01, 02, 03, 04, 05)),
                Option.None <DateTime>(),
                new TestConfig(module1Hash));

            string module2Hash = Guid.NewGuid().ToString();
            var    module2     = new ModuleRuntimeInfo <TestConfig>(
                "module2",
                "docker",
                ModuleStatus.Stopped,
                "stopped",
                5,
                Option.Some(new DateTime(2011, 02, 03, 04, 05, 06)),
                Option.Some(new DateTime(2011, 02, 03, 05, 06, 07)),
                new TestConfig(module2Hash));

            var modules = new List <ModuleRuntimeInfo> {
                module1, module2
            };
            var moduleManager = Mock.Of <IModuleManager>(m => m.GetModules <TestConfig>(It.IsAny <CancellationToken>()) == Task.FromResult(modules.AsEnumerable()));
            IRuntimeInfoProvider runtimeInfoProvider = new RuntimeInfoProvider <TestConfig>(moduleManager);

            // Act
            List <ModuleRuntimeInfo> runtimeInfos = (await runtimeInfoProvider.GetModules(CancellationToken.None)).ToList();

            // Assert
            Assert.NotNull(runtimeInfos);
            Assert.Equal(2, runtimeInfos.Count);

            ModuleRuntimeInfo runtimeInfo1 = runtimeInfos[0];

            Assert.Equal("module1", runtimeInfo1.Name);
            Assert.Equal(new DateTime(2010, 01, 02, 03, 04, 05), runtimeInfo1.StartTime.OrDefault());
            Assert.Equal(ModuleStatus.Running, runtimeInfo1.ModuleStatus);
            Assert.Equal("running", runtimeInfo1.Description);
            Assert.Equal(0, runtimeInfo1.ExitCode);
            Assert.False(runtimeInfo1.ExitTime.HasValue);
            Assert.Equal((runtimeInfo1 as ModuleRuntimeInfo <TestConfig>)?.Config.ImageHash, module1Hash);

            ModuleRuntimeInfo runtimeInfo2 = runtimeInfos[1];

            Assert.Equal("module2", runtimeInfo2.Name);
            Assert.Equal(new DateTime(2011, 02, 03, 04, 05, 06), runtimeInfo2.StartTime.OrDefault());
            Assert.Equal(ModuleStatus.Stopped, runtimeInfo2.ModuleStatus);
            Assert.Equal("stopped", runtimeInfo2.Description);
            Assert.Equal(5, runtimeInfo2.ExitCode);
            Assert.Equal(new DateTime(2011, 02, 03, 05, 06, 07), runtimeInfo2.ExitTime.OrDefault());
            Assert.Equal((runtimeInfo2 as ModuleRuntimeInfo <TestConfig>)?.Config.ImageHash, module2Hash);
        }
예제 #6
0
        public async Task TestEmptyEnvironment()
        {
            using (var cts = new CancellationTokenSource(Timeout))
            {
                RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(Client);

                IEnumerable <ModuleRuntimeInfo> modules = await runtimeInfoProvider.GetModules(cts.Token);

                Assert.Empty(modules);
            }
        }
예제 #7
0
        public void InspectResponseToModuleTest()
        {
            const string StatusText    = "Running for 1 second";
            DateTime     lastStartTime = DateTime.Parse("2017-08-04T17:52:13.0419502Z", null, DateTimeStyles.RoundtripKind);
            DateTime     lastExitTime  = lastStartTime.AddDays(1);
            // Arrange
            string id   = Guid.NewGuid().ToString();
            string hash = Guid.NewGuid().ToString();

            var inspectContainerResponse = new ContainerInspectResponse
            {
                State = new ContainerState
                {
                    Status     = StatusText,
                    ExitCode   = 0,
                    StartedAt  = lastStartTime.ToString("o"),
                    FinishedAt = lastExitTime.ToString("o"),
                },
                Name   = "/sensor",
                Image  = hash,
                Config = new Config {
                    Image = "ubuntu"
                }
            };

            var systemInfoResponse = new SystemInfoResponse
            {
                OSType       = OperatingSystemType,
                Architecture = Architecture
            };

            var dockerClient = Mock.Of <IDockerClient>(
                dc =>
                dc.Containers == Mock.Of <IContainerOperations>(co => co.InspectContainerAsync(id, default(CancellationToken)) == Task.FromResult(inspectContainerResponse)) &&
                dc.System == Mock.Of <ISystemOperations>(so => so.GetSystemInfoAsync(default(CancellationToken)) == Task.FromResult(systemInfoResponse)));

            // Act
            ModuleRuntimeInfo module = RuntimeInfoProvider.InspectResponseToModule(inspectContainerResponse);

            // Assert
            Assert.NotNull(module);
            var dockerModule = module as ModuleRuntimeInfo <DockerReportedConfig>;

            Assert.NotNull(dockerModule);
            Assert.Equal("ubuntu:latest", dockerModule.Config.Image);

            Assert.Equal("sensor", dockerModule.Name);
            Assert.Equal(0, dockerModule.ExitCode);
            Assert.Equal(StatusText, dockerModule.Description);
            Assert.Equal(lastStartTime, dockerModule.StartTime.OrDefault());
            Assert.Equal(lastExitTime, dockerModule.ExitTime.OrDefault());
        }
예제 #8
0
        public async Task GetModules_Handles_MissingEdgeAgent()
        {
            var missingContainerName   = "edgeAgent";
            var expectedContainerNames = new[] { "container1", "container2", "container3" };

            var dockerClient = this.SetupDockerClient(missingContainerName, expectedContainerNames);
            var provider     = await RuntimeInfoProvider.CreateAsync(dockerClient);

            var moduleInfo = await provider.GetModules(CancellationToken.None);

            var actualContainerNames = moduleInfo.Select(m => m.Name);

            Assert.Equal(expectedContainerNames, actualContainerNames);
        }
예제 #9
0
        public async Task GetSystemInfoTest()
        {
            // Arrange
            var systemInfoSample = new SystemInfo("linux", "x86", "1");

            var moduleManager = Mock.Of <IModuleManager>(m => m.GetSystemInfoAsync() == Task.FromResult(systemInfoSample));
            IRuntimeInfoProvider runtimeInfoProvider = new RuntimeInfoProvider <TestConfig>(moduleManager);

            // Act
            SystemInfo systemInfo = await runtimeInfoProvider.GetSystemInfo();

            // Assert
            Assert.NotNull(systemInfo);
            Assert.Equal("linux", systemInfo.OperatingSystemType);
            Assert.Equal("x86", systemInfo.Architecture);
            Assert.Equal("1", systemInfo.Version);
        }
예제 #10
0
        public async Task TestPlatformInfo()
        {
            using (var cts = new CancellationTokenSource(Timeout))
            {
                // Arrange
                SystemInfoResponse systemInfo = await Client.System.GetSystemInfoAsync(cts.Token);

                RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(Client);

                // Act
                SystemInfo recivedSystemInfo = await runtimeInfoProvider.GetSystemInfo();

                // Assert
                Assert.Equal(systemInfo.OSType, recivedSystemInfo.OperatingSystemType);
                Assert.Equal(systemInfo.Architecture, recivedSystemInfo.Architecture);
            }
        }
예제 #11
0
        public async Task GetModules_Handles_NotFoundException()
        {
            var missingContainerName = "container2";
            var containersToReturn   = new[] { "container1", "container2", "container3" };

            var dockerClient = this.SetupDockerClient(missingContainerName, containersToReturn);
            var provider     = await RuntimeInfoProvider.CreateAsync(dockerClient);

            var moduleInfo = await provider.GetModules(CancellationToken.None);

            var actualContainerNames = moduleInfo
                                       .Select(m => m.Name);

            var expectedContainerNames = containersToReturn
                                         .Where(c => !c.Equals(missingContainerName))
                                         .Concat(new[] { "edgeAgent" });

            Assert.Equal(expectedContainerNames, actualContainerNames);
        }
예제 #12
0
        protected override void Load(ContainerBuilder builder)
        {
            // IModuleClientProvider
            string edgeAgentConnectionString = $"{this.edgeDeviceConnectionString};{Constants.ModuleIdKey}={Constants.EdgeAgentModuleIdentityName}";

            builder.Register(
                c => new ModuleClientProvider(
                    edgeAgentConnectionString,
                    c.Resolve <ISdkModuleClientProvider>(),
                    this.upstreamProtocol,
                    this.proxy,
                    this.productInfo,
                    this.closeOnIdleTimeout,
                    this.idleTimeout))
            .As <IModuleClientProvider>()
            .SingleInstance();

            // IServiceClient
            builder.Register(c => new RetryingServiceClient(new ServiceClient(this.edgeDeviceConnectionString, this.deviceId)))
            .As <IServiceClient>()
            .SingleInstance();

            // IModuleIdentityLifecycleManager
            builder.Register(c => new ModuleIdentityLifecycleManager(c.Resolve <IServiceClient>(), this.iotHubHostName, this.deviceId, this.gatewayHostName))
            .As <IModuleIdentityLifecycleManager>()
            .SingleInstance();

            // IDockerClient
            builder.Register(c => new DockerClientConfiguration(this.dockerHostname).CreateClient())
            .As <IDockerClient>()
            .SingleInstance();

            // ICombinedConfigProvider<CombinedDockerConfig>
            builder.Register(c => new CombinedDockerConfigProvider(this.dockerAuthConfig))
            .As <ICombinedConfigProvider <CombinedDockerConfig> >()
            .SingleInstance();

            // ICommandFactory
            builder.Register(
                async c =>
            {
                var dockerClient                 = c.Resolve <IDockerClient>();
                var dockerLoggingConfig          = c.Resolve <DockerLoggingConfig>();
                var combinedDockerConfigProvider = c.Resolve <ICombinedConfigProvider <CombinedDockerConfig> >();
                IConfigSource configSource       = await c.Resolve <Task <IConfigSource> >();
                var dockerFactory                = new DockerCommandFactory(dockerClient, dockerLoggingConfig, configSource, combinedDockerConfigProvider);
                return(new LoggingCommandFactory(dockerFactory, c.Resolve <ILoggerFactory>()) as ICommandFactory);
            })
            .As <Task <ICommandFactory> >()
            .SingleInstance();

            // IRuntimeInfoProvider
            builder.Register(
                async c =>
            {
                IRuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(c.Resolve <IDockerClient>());
                return(runtimeInfoProvider);
            })
            .As <Task <IRuntimeInfoProvider> >()
            .SingleInstance();

            // Task<IEnvironmentProvider>
            builder.Register(
                async c =>
            {
                var moduleStateStore     = await c.Resolve <Task <IEntityStore <string, ModuleState> > >();
                var restartPolicyManager = c.Resolve <IRestartPolicyManager>();
                IRuntimeInfoProvider runtimeInfoProvider       = await c.Resolve <Task <IRuntimeInfoProvider> >();
                IEnvironmentProvider dockerEnvironmentProvider = await DockerEnvironmentProvider.CreateAsync(runtimeInfoProvider, moduleStateStore, restartPolicyManager);
                return(dockerEnvironmentProvider);
            })
            .As <Task <IEnvironmentProvider> >()
            .SingleInstance();

            // IDeviceManager
            builder.Register(c => new NullDeviceManager())
            .As <IDeviceManager>()
            .SingleInstance();
        }
예제 #13
0
        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);
            }
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        public async Task GetModulesTest()
        {
            // Arrange
            string module1Hash = Guid.NewGuid().ToString();
            var    module1     = new ModuleDetails
            {
                Id     = Guid.NewGuid().ToString(),
                Name   = "module1",
                Status = new Status
                {
                    StartTime     = new DateTime(2010, 01, 02, 03, 04, 05),
                    RuntimeStatus = new RuntimeStatus {
                        Status = "Running", Description = "running"
                    },
                    ExitStatus = null
                },
                Type   = "docker",
                Config = new Config
                {
                    Env = new ObservableCollection <EnvVar>(new List <EnvVar> {
                        new EnvVar {
                            Key = "k1", Value = "v1"
                        }
                    }),
                    Settings = JObject.FromObject(new TestConfig(module1Hash))
                }
            };

            string module2Hash = Guid.NewGuid().ToString();
            var    module2     = new ModuleDetails
            {
                Id     = Guid.NewGuid().ToString(),
                Name   = "module2",
                Status = new Status
                {
                    StartTime     = new DateTime(2011, 02, 03, 04, 05, 06),
                    RuntimeStatus = new RuntimeStatus {
                        Status = "Stopped", Description = "stopped"
                    },
                    ExitStatus = new ExitStatus {
                        ExitTime = new DateTime(2011, 02, 03, 05, 06, 07), StatusCode = "5"
                    }
                },
                Type   = "docker",
                Config = new Config
                {
                    Env = new ObservableCollection <EnvVar>(new List <EnvVar> {
                        new EnvVar {
                            Key = "k2", Value = "v2"
                        }
                    }),
                    Settings = JObject.FromObject(new TestConfig(module2Hash))
                }
            };

            var modules = new List <ModuleDetails> {
                module1, module2
            };
            var moduleManager = Mock.Of <IModuleManager>(m => m.GetModules(It.IsAny <CancellationToken>()) == Task.FromResult(modules.AsEnumerable()));
            IRuntimeInfoProvider runtimeInfoProvider = new RuntimeInfoProvider <TestConfig>(moduleManager);

            // Act
            List <ModuleRuntimeInfo> runtimeInfos = (await runtimeInfoProvider.GetModules(CancellationToken.None)).ToList();

            // Assert
            Assert.NotNull(runtimeInfos);
            Assert.Equal(2, runtimeInfos.Count);

            ModuleRuntimeInfo runtimeInfo1 = runtimeInfos[0];

            Assert.Equal("module1", runtimeInfo1.Name);
            Assert.Equal(new DateTime(2010, 01, 02, 03, 04, 05), runtimeInfo1.StartTime.OrDefault());
            Assert.Equal(ModuleStatus.Running, runtimeInfo1.ModuleStatus);
            Assert.Equal("running", runtimeInfo1.Description);
            Assert.Equal(0, runtimeInfo1.ExitCode);
            Assert.False(runtimeInfo1.ExitTime.HasValue);
            Assert.Equal((runtimeInfo1 as ModuleRuntimeInfo <TestConfig>)?.Config.ImageHash, module1Hash);

            ModuleRuntimeInfo runtimeInfo2 = runtimeInfos[1];

            Assert.Equal("module2", runtimeInfo2.Name);
            Assert.Equal(new DateTime(2011, 02, 03, 04, 05, 06), runtimeInfo2.StartTime.OrDefault());
            Assert.Equal(ModuleStatus.Stopped, runtimeInfo2.ModuleStatus);
            Assert.Equal("stopped", runtimeInfo2.Description);
            Assert.Equal(5, runtimeInfo2.ExitCode);
            Assert.Equal(new DateTime(2011, 02, 03, 05, 06, 07), runtimeInfo2.ExitTime.OrDefault());
            Assert.Equal((runtimeInfo2 as ModuleRuntimeInfo <TestConfig>)?.Config.ImageHash, module2Hash);
        }