public async void ChangeFileAndSeeChange()
        {
            // Set up initial config file and create `FileConfigSource`
            File.WriteAllText(this.tempFileName, ValidJson1);
            Diff validDiff1To2 = ValidSet2.Diff(ValidSet1);

            using (FileConfigSource configSource = await FileConfigSource.Create(this.tempFileName, this.config, this.serde))
            {
                Assert.NotNull(configSource);

                DeploymentConfigInfo deploymentConfigInfo = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(deploymentConfigInfo);
                ModuleSet initialModuleSet = deploymentConfigInfo.DeploymentConfig.GetModuleSet();
                Diff      emptyDiff        = ValidSet1.Diff(initialModuleSet);
                Assert.True(emptyDiff.IsEmpty);

                // Modify the config file by writing new content.
                File.WriteAllText(this.tempFileName, ValidJson2);
                await Task.Delay(TimeSpan.FromSeconds(20));

                DeploymentConfigInfo updatedAgentConfig = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(updatedAgentConfig);
                ModuleSet updatedModuleSet = updatedAgentConfig.DeploymentConfig.GetModuleSet();
                Diff      newDiff          = updatedModuleSet.Diff(initialModuleSet);
                Assert.False(newDiff.IsEmpty);
                Assert.Equal(newDiff, validDiff1To2);
            }
        }
Beispiel #2
0
        async Task <DeploymentConfigInfo> ReadFromBackup()
        {
            try
            {
                if (!File.Exists(this.configFilePath))
                {
                    Events.BackupFileDoesNotExist(this.configFilePath);
                }
                else
                {
                    using (await this.sync.LockAsync())
                    {
                        string encryptedJson = await DiskFile.ReadAllAsync(this.configFilePath);

                        string json = await this.encryptionProvider.DecryptAsync(encryptedJson);

                        DeploymentConfigInfo deploymentConfigInfo = this.serde.Deserialize(json);
                        Events.ObtainedDeploymentFromBackup(this.configFilePath);
                        return(deploymentConfigInfo);
                    }
                }
            }
            catch (Exception e)
            {
                Events.GetBackupFailed(e, this.configFilePath);
            }
            return(DeploymentConfigInfo.Empty);
        }
Beispiel #3
0
            public static void RestoringFromBackup(DeploymentConfigInfo deploymentConfig, string filename)
            {
                string reason = deploymentConfig.Exception.Map(e => $"Error getting edge agent config - {e}")
                                .GetOrElse("Empty edge agent config was received");

                Log.LogWarning((int)EventIds.RestoringFromBackup, $"{reason}. Attempting to read config from backup file ({filename}) instead");
            }
        public async Task <DeploymentConfigInfo> GetDeploymentConfigInfoAsync()
        {
            try
            {
                DeploymentConfigInfo deploymentConfig = await this.underlying.GetDeploymentConfigInfoAsync();

                if (deploymentConfig == DeploymentConfigInfo.Empty)
                {
                    Events.RestoringFromBackup(deploymentConfig, this.configFilePath);
                    deploymentConfig = await this.ReadFromBackup();
                }
                else if (!deploymentConfig.Exception.HasValue)
                {
                    // TODO - Backing up the config every time for now, probably should optimize this.
                    await this.BackupDeploymentConfig(deploymentConfig);
                }

                return(deploymentConfig);
            }
            catch (Exception ex)
            {
                Events.RestoringFromBackup(ex, this.configFilePath);
                return(await this.ReadFromBackup());
            }
        }
Beispiel #5
0
        protected override async Task <Option <object> > HandleRequestInternal(Option <RestartRequest> payloadOption, CancellationToken cancellationToken)
        {
            RestartRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));

            if (ExpectedSchemaVersion.CompareMajorVersion(payload.SchemaVersion, "restart module request schema") != 0)
            {
                Events.MismatchedMinorVersions(payload.SchemaVersion, ExpectedSchemaVersion);
            }

            Events.ProcessingRequest(payload);

            DeploymentConfigInfo deploymentConfigInfo = await this.configSource.GetDeploymentConfigInfoAsync();

            IEnvironment environment = this.environmentProvider.Create(deploymentConfigInfo.DeploymentConfig);
            ModuleSet    modules     = await environment.GetModulesAsync(cancellationToken);

            if (!modules.TryGetModule(payload.Id, out IModule module))
            {
                throw new InvalidOperationException($"Module {payload.Id} not found in the current environment");
            }

            Events.RestartingModule(payload.Id);
            ICommand restartCommand = await this.commandFactory.RestartAsync(module);

            await restartCommand.ExecuteAsync(cancellationToken);

            Events.RestartedModule(payload.Id);
            return(Option.None <object>());
        }
        public async void ReadsBackupOnce()
        {
            DeploymentConfigInfo configInfo = SetupNonEmptyDeployment();

            var underlying = new Mock <IConfigSource>();

            underlying.Setup(u => u.GetDeploymentConfigInfoAsync()).ThrowsAsync(new NullException("failure"));
            var backup = new Mock <IDeploymentBackupSource>();

            backup.SetupGet(b => b.Name).Returns("backup");
            backup.SetupSequence(b => b.ReadFromBackupAsync())
            .ReturnsAsync(configInfo)
            .ReturnsAsync(DeploymentConfigInfo.Empty);

            var backupSource = new BackupConfigSource(backup.Object, underlying.Object);
            var result1      = await backupSource.GetDeploymentConfigInfoAsync();

            var result2 = await backupSource.GetDeploymentConfigInfoAsync();

            Assert.Equal(configInfo, result1);
            Assert.Equal(configInfo, result2);

            underlying.VerifyAll();
            backup.Verify(b => b.ReadFromBackupAsync(), Times.Once);
        }
Beispiel #7
0
        public async void FileBackupSuccessCallsEncrypt()
        {
            if (File.Exists(this.tempFileName))
            {
                File.Delete(this.tempFileName);
            }

            var underlying = new Mock <IConfigSource>();

            underlying.SetupSequence(t => t.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(ValidConfigInfo1);

            ISerde <DeploymentConfigInfo> serde = this.GetSerde();
            var encryptionProvider = new Mock <IEncryptionProvider>();

            encryptionProvider.Setup(ep => ep.EncryptAsync(It.IsAny <string>()))
            .ReturnsAsync(serde.Serialize(ValidConfigInfo1));
            using (IConfigSource configSource = new FileBackupConfigSource(this.tempFileName, underlying.Object, serde, encryptionProvider.Object))
            {
                DeploymentConfigInfo config1 = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(config1);

                Assert.True(File.Exists(this.tempFileName));
                string backupJson = await DiskFile.ReadAllAsync(this.tempFileName);

                string returnedJson = serde.Serialize(config1);

                Assert.Equal(backupJson, returnedJson, true);
                encryptionProvider.Verify(ep => ep.EncryptAsync(It.IsAny <string>()));
            }
        }
Beispiel #8
0
        public async void FileBackupReadFromBackupCallsEncryptDecrypt()
        {
            if (File.Exists(this.tempFileName))
            {
                File.Delete(this.tempFileName);
            }

            ISerde <DeploymentConfigInfo> serde = this.GetSerde();
            var encryptionProvider = new Mock <IEncryptionProvider>();

            encryptionProvider.Setup(ep => ep.EncryptAsync(It.IsAny <string>()))
            .ReturnsAsync(serde.Serialize(ValidConfigInfo1));
            encryptionProvider.Setup(ep => ep.DecryptAsync(It.IsAny <string>()))
            .ReturnsAsync(serde.Serialize(ValidConfigInfo1));

            IDeploymentBackupSource fileBackup = new DeploymentFileBackup(this.tempFileName, serde, encryptionProvider.Object);

            await fileBackup.BackupDeploymentConfigAsync(ValidConfigInfo1);

            DeploymentConfigInfo config1 = await fileBackup.ReadFromBackupAsync();

            Assert.NotNull(config1);
            Assert.True(File.Exists(this.tempFileName));
            string backupJson = await DiskFile.ReadAllAsync(this.tempFileName);

            string returnedJson = serde.Serialize(config1);
            string expectedJson = serde.Serialize(ValidConfigInfo1);

            Assert.Equal(expectedJson, backupJson, ignoreCase: true);
            Assert.Equal(expectedJson, returnedJson, ignoreCase: true);

            encryptionProvider.Verify(ep => ep.EncryptAsync(It.IsAny <string>()));
            encryptionProvider.Verify(ep => ep.DecryptAsync(It.IsAny <string>()));
        }
Beispiel #9
0
        public async void ReconcileAsyncAbortsWhenEnvironmentSourceThrows()
        {
            // Arrange
            var mockConfigSource = new Mock <IConfigSource>();
            var mockEnvironment  = new Mock <IEnvironment>();
            var mockPlanner      = new Mock <IPlanner>();
            var mockPlanRunner   = new Mock <IPlanRunner>();
            var mockReporter     = new Mock <IReporter>();
            var token            = default(CancellationToken);
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var configStore             = Mock.Of <IEntityStore <string, string> >();
            var mockEnvironmentProvider = Mock.Of <IEnvironmentProvider>(m => m.Create(It.IsAny <DeploymentConfig>()) == mockEnvironment.Object);
            var serde = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var encryptionDecryptionProvider = Mock.Of <IEncryptionProvider>();
            var deploymentConfig             = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), new SystemModules(null, null), new Dictionary <string, IModule>());
            var deploymentConfigInfo         = new DeploymentConfigInfo(0, deploymentConfig);

            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(env => env.GetModulesAsync(token)).Throws <InvalidOperationException>();
            mockReporter.Setup(r => r.ReportAsync(token, null, It.IsAny <IRuntimeInfo>(), It.IsAny <long>(), It.Is <DeploymentStatus>(s => s.Code == DeploymentStatusCode.Failed)))
            .Returns(Task.CompletedTask);

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider);

            // Act
            // Assert
            await agent.ReconcileAsync(token);

            mockPlanner.Verify(p => p.PlanAsync(It.IsAny <ModuleSet>(), It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <ImmutableDictionary <string, IModuleIdentity> >()), Times.Never);
            mockReporter.VerifyAll();
            mockPlanRunner.Verify(r => r.ExecuteAsync(1, It.IsAny <Plan>(), token), Times.Never);
        }
Beispiel #10
0
        public async void FileBackupDoesNotThrowWhenEncryptFails()
        {
            if (File.Exists(this.tempFileName))
            {
                File.Delete(this.tempFileName);
            }

            var underlying = new Mock <IConfigSource>();

            underlying.SetupSequence(t => t.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(ValidConfigInfo1);

            ISerde <DeploymentConfigInfo> serde = this.GetSerde();
            var encryptionProvider = new Mock <IEncryptionProvider>();

            encryptionProvider.Setup(ep => ep.EncryptAsync(It.IsAny <string>()))
            .ThrowsAsync(new IoTEdgedException("failed", 404, "", null, null));
            using (IConfigSource configSource = new FileBackupConfigSource(this.tempFileName, underlying.Object, serde, encryptionProvider.Object))
            {
                DeploymentConfigInfo config1 = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(config1);

                Assert.Equal(ValidConfigInfo1, config1);

                encryptionProvider.Verify(ep => ep.EncryptAsync(It.IsAny <string>()));
            }
        }
Beispiel #11
0
        public async void FileBackupSuccessWhenFileNotExists()
        {
            if (File.Exists(this.tempFileName))
            {
                File.Delete(this.tempFileName);
            }

            var underlying = new Mock <IConfigSource>();

            underlying.SetupSequence(t => t.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(ValidConfigInfo1)
            .ThrowsAsync(new InvalidOperationException());
            ISerde <DeploymentConfigInfo> serde = this.GetSerde();

            using (IConfigSource configSource = new FileBackupConfigSource(this.tempFileName, underlying.Object, serde, NullEncryptionProvider.Instance))
            {
                DeploymentConfigInfo config1 = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(config1);

                Assert.True(File.Exists(this.tempFileName));
                string backupJson = await DiskFile.ReadAllAsync(this.tempFileName);

                string returnedJson = serde.Serialize(config1);

                Assert.True(string.Equals(backupJson, returnedJson, StringComparison.OrdinalIgnoreCase));

                DeploymentConfigInfo config2 = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(config2);

                Assert.Equal(serde.Serialize(config1), serde.Serialize(config2));
            }
        }
Beispiel #12
0
        public async Task DesiredIsNotNullBecauseCurrentThrew()
        {
            // Arrange
            var mockConfigSource = new Mock <IConfigSource>();
            var mockEnvironment  = new Mock <IEnvironment>();
            var mockPlanner      = new Mock <IPlanner>();
            var mockPlanRunner   = new Mock <IPlanRunner>();
            var mockReporter     = new Mock <IReporter>();
            var runtimeInfo      = new Mock <IRuntimeInfo>();
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var token                        = default(CancellationToken);
            var configStore                  = Mock.Of <IEntityStore <string, string> >();
            var mockEnvironmentProvider      = Mock.Of <IEnvironmentProvider>(m => m.Create(It.IsAny <DeploymentConfig>()) == mockEnvironment.Object);
            var serde                        = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var encryptionDecryptionProvider = Mock.Of <IEncryptionProvider>();
            var deploymentConfigInfo         = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtimeInfo.Object, new SystemModules(null, null), ImmutableDictionary <string, IModule> .Empty));

            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(e => e.GetModulesAsync(token))
            .Throws <InvalidOperationException>();

            // Act
            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider);
            await agent.ReconcileAsync(token);

            // Assert
            mockReporter.Verify(r => r.ReportAsync(token, null, It.IsAny <IRuntimeInfo>(), It.IsAny <long>(), It.Is <DeploymentStatus>(s => s.Code == DeploymentStatusCode.Failed)));
            mockPlanRunner.Verify(r => r.ExecuteAsync(1, It.IsAny <Plan>(), token), Times.Never);
        }
Beispiel #13
0
        public async Task ReportShutdownAsyncConfigTest()
        {
            // Arrange
            var mockConfigSource = new Mock <IConfigSource>();
            var mockEnvironment  = new Mock <IEnvironment>();
            var mockPlanner      = new Mock <IPlanner>();
            var mockPlanRunner   = new Mock <IPlanRunner>();
            var mockReporter     = new Mock <IReporter>();
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var configStore             = Mock.Of <IEntityStore <string, string> >();
            var mockEnvironmentProvider = Mock.Of <IEnvironmentProvider>(m => m.Create(It.IsAny <DeploymentConfig>()) == mockEnvironment.Object);
            var serde = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var encryptionDecryptionProvider = Mock.Of <IEncryptionProvider>();
            var deploymentConfig             = new DeploymentConfig(
                "1.0",
                Mock.Of <IRuntimeInfo>(),
                new SystemModules(null, null),
                new Dictionary <string, IModule>
            {
                { "mod1", new TestModule("mod1", "1.0", "docker", ModuleStatus.Running, new TestConfig("boo"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null) }
            });
            var deploymentConfigInfo = new DeploymentConfigInfo(0, deploymentConfig);
            var token = default(CancellationToken);

            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(e => e.GetModulesAsync(token))
            .ReturnsAsync(ModuleSet.Empty);

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider);
            await agent.ReportShutdownAsync(token);

            // Assert
            mockReporter.Verify(r => r.ReportShutdown(It.IsAny <DeploymentStatus>(), token));
        }
Beispiel #14
0
        public async void ReconcileAsyncOnSetPlan()
        {
            var desiredModule       = new TestModule("desired", "v1", "test", ModuleStatus.Running, new TestConfig("image"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null);
            var currentModule       = new TestModule("current", "v1", "test", ModuleStatus.Running, new TestConfig("image"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null);
            var recordKeeper        = Option.Some(new TestPlanRecorder());
            var moduleExecutionList = new List <TestRecordType>
            {
                new TestRecordType(TestCommandType.TestCreate, desiredModule),
                new TestRecordType(TestCommandType.TestRemove, currentModule)
            };
            var commandList = new List <ICommand>
            {
                new TestCommand(TestCommandType.TestCreate, desiredModule, recordKeeper),
                new TestCommand(TestCommandType.TestRemove, currentModule, recordKeeper)
            };
            var testPlan = new Plan(commandList);

            var token = new CancellationToken();

            var runtimeInfo      = Mock.Of <IRuntimeInfo>();
            var deploymentConfig = new DeploymentConfig("1.0", runtimeInfo, new SystemModules(null, null), new Dictionary <string, IModule> {
                ["desired"] = desiredModule
            });
            var       deploymentConfigInfo = new DeploymentConfigInfo(0, deploymentConfig);
            ModuleSet desiredSet           = deploymentConfig.GetModuleSet();
            ModuleSet currentSet           = ModuleSet.Create(currentModule);

            var mockConfigSource = new Mock <IConfigSource>();
            var mockEnvironment  = new Mock <IEnvironment>();
            var mockPlanner      = new Mock <IPlanner>();
            var planRunner       = new OrderedPlanRunner();
            var mockReporter     = new Mock <IReporter>();
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var configStore             = Mock.Of <IEntityStore <string, string> >();
            var mockEnvironmentProvider = Mock.Of <IEnvironmentProvider>(m => m.Create(It.IsAny <DeploymentConfig>()) == mockEnvironment.Object);
            var serde = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var encryptionDecryptionProvider = Mock.Of <IEncryptionProvider>();

            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(env => env.GetModulesAsync(token))
            .ReturnsAsync(currentSet);
            mockModuleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(desiredSet, currentSet))
            .ReturnsAsync(ImmutableDictionary <string, IModuleIdentity> .Empty);
            mockPlanner.Setup(pl => pl.PlanAsync(It.IsAny <ModuleSet>(), currentSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty))
            .Returns(Task.FromResult(testPlan));
            mockModuleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(It.IsAny <ModuleSet>(), currentSet))
            .Returns(Task.FromResult((IImmutableDictionary <string, IModuleIdentity>)ImmutableDictionary <string, IModuleIdentity> .Empty));
            mockReporter.Setup(r => r.ReportAsync(token, It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <long>(), Option.Some(DeploymentStatus.Success)))
            .Returns(Task.CompletedTask);

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider, mockPlanner.Object, planRunner, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider);

            await agent.ReconcileAsync(token);

            mockEnvironment.Verify(env => env.GetModulesAsync(token), Times.Exactly(1));
            mockPlanner.Verify(pl => pl.PlanAsync(It.IsAny <ModuleSet>(), currentSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty), Times.Once);
            mockReporter.VerifyAll();
            recordKeeper.ForEach(r => Assert.Equal(moduleExecutionList, r.ExecutionList));
        }
        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);
            }
        }
Beispiel #16
0
        public async void FileBackupDoesNotThrowWhenBackupFileDoesNotExist()
        {
            if (File.Exists(this.tempFileName))
            {
                File.Delete(this.tempFileName);
            }

            // Arrange
            var underlying = new Mock <IConfigSource>();

            underlying.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(DeploymentConfigInfo.Empty);

            ISerde <DeploymentConfigInfo> serde = this.GetSerde();

            // Act
            using (IConfigSource configSource = new FileBackupConfigSource(this.tempFileName, underlying.Object, serde, NullEncryptionProvider.Instance))
            {
                // this call should fetch the config properly
                DeploymentConfigInfo config1 = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(config1);
                Assert.Equal(DeploymentConfigInfo.Empty, config1);
            }
        }
        public async void ConfigBacksUpEachTimeItChanges()
        {
            DeploymentConfigInfo configInfo1 = SetupNonEmptyDeployment();
            DeploymentConfigInfo configInfo2 = SetupNonEmptyDeployment("new-module");

            var underlying = new Mock <IConfigSource>();

            underlying.SetupSequence(u => u.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(configInfo1)
            .ReturnsAsync(configInfo2);
            var backup = new Mock <IDeploymentBackupSource>();

            backup.SetupGet(b => b.Name).Returns("backup");
            backup.Setup(b => b.BackupDeploymentConfigAsync(configInfo1)).Returns(TaskEx.Done);
            backup.Setup(b => b.BackupDeploymentConfigAsync(configInfo2)).Returns(TaskEx.Done);

            var backupSource = new BackupConfigSource(backup.Object, underlying.Object);
            var result1      = await backupSource.GetDeploymentConfigInfoAsync();

            var result2 = await backupSource.GetDeploymentConfigInfoAsync();

            Assert.Equal(configInfo1, result1);
            Assert.Equal(configInfo2, result2);
            underlying.VerifyAll();
            backup.Verify(b => b.BackupDeploymentConfigAsync(configInfo1), Times.Once);
            backup.Verify(b => b.BackupDeploymentConfigAsync(configInfo2), Times.Once);
        }
Beispiel #18
0
        static async Task <DeploymentConfigInfo> ReadFromDisk(string path, ISerde <DeploymentConfigInfo> serde)
        {
            string json = await DiskFile.ReadAllAsync(path);

            DeploymentConfigInfo deploymentConfig = serde.Deserialize(json);

            return(deploymentConfig);
        }
        public void TestEquality(DeploymentConfigInfo configInfo1, DeploymentConfigInfo configInfo2, bool areEqual)
        {
            // Act
            bool result = configInfo1.Equals(configInfo2);

            // Assert
            Assert.Equal(areEqual, result);
        }
Beispiel #20
0
        public async void ReconcileAsyncReportsFailedWhenEncryptProviderThrows()
        {
            var token                              = default(CancellationToken);
            var serde                              = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var mockConfigSource                   = new Mock <IConfigSource>();
            var mockEnvironment                    = new Mock <IEnvironment>();
            var mockEnvironmentProvider            = new Mock <IEnvironmentProvider>();
            var mockPlanner                        = new Mock <IPlanner>();
            var mockPlanRunner                     = new Mock <IPlanRunner>();
            var mockReporter                       = new Mock <IReporter>();
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var runtimeInfo                        = Mock.Of <IRuntimeInfo>();
            var configStore                        = Mock.Of <IEntityStore <string, string> >();
            var encryptionDecryptionProvider       = new Mock <IEncryptionProvider>();
            var availabilityMetric                 = Mock.Of <IAvailabilityMetric>();
            var deploymentConfig                   = new DeploymentConfig(
                "1.0",
                runtimeInfo,
                new SystemModules(null, null),
                new Dictionary <string, IModule>
            {
                { "mod1", new TestModule("mod1", "1.0", "docker", ModuleStatus.Running, new TestConfig("boo"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null) }
            });
            var       desiredModule        = new TestModule("desired", "v1", "test", ModuleStatus.Running, new TestConfig("image"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null);
            var       recordKeeper         = Option.Some(new TestPlanRecorder());
            var       deploymentConfigInfo = new DeploymentConfigInfo(0, deploymentConfig);
            ModuleSet desiredModuleSet     = deploymentConfig.GetModuleSet();
            ModuleSet currentModuleSet     = desiredModuleSet;

            var commandList = new List <ICommand>
            {
                new TestCommand(TestCommandType.TestCreate, desiredModule, recordKeeper)
            };
            var testPlan = new Plan(commandList);

            mockEnvironmentProvider.Setup(m => m.Create(It.IsAny <DeploymentConfig>())).Returns(mockEnvironment.Object);
            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(env => env.GetModulesAsync(token))
            .ReturnsAsync(currentModuleSet);
            mockEnvironment.Setup(env => env.GetRuntimeInfoAsync()).ReturnsAsync(runtimeInfo);
            mockModuleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(It.Is <ModuleSet>(ms => ms.Equals(desiredModuleSet)), currentModuleSet))
            .ReturnsAsync(ImmutableDictionary <string, IModuleIdentity> .Empty);
            mockPlanner.Setup(pl => pl.PlanAsync(It.Is <ModuleSet>(ms => ms.Equals(desiredModuleSet)), currentModuleSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty))
            .ReturnsAsync(testPlan);
            encryptionDecryptionProvider.Setup(ep => ep.EncryptAsync(It.IsAny <string>()))
            .ThrowsAsync(new WorkloadCommunicationException("failed", 404));

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider.Object, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider.Object, availabilityMetric);

            await agent.ReconcileAsync(token);

            // Assert
            mockPlanner.Verify(p => p.PlanAsync(It.IsAny <ModuleSet>(), It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <ImmutableDictionary <string, IModuleIdentity> >()), Times.Once);
            mockReporter.Verify(r => r.ReportAsync(It.IsAny <CancellationToken>(), It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), 0, new DeploymentStatus(DeploymentStatusCode.Failed, "failed")));
            mockPlanRunner.Verify(r => r.ExecuteAsync(0, It.IsAny <Plan>(), token), Times.Once);
            encryptionDecryptionProvider.Verify(ep => ep.EncryptAsync(It.IsAny <string>()), Times.Exactly(2));
        }
Beispiel #21
0
        void UpdateCurrent(DeploymentConfigInfo updated)
        {
            DeploymentConfigInfo snapshot = this.current.Value;

            if (!this.current.CompareAndSet(snapshot, updated))
            {
                throw new InvalidOperationException("Invalid update current moduleset operation.");
            }
        }
Beispiel #22
0
        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 async Task RestartTest()
        {
            // Arrange
            var cts                  = new CancellationTokenSource();
            var edgeAgent            = Mock.Of <IEdgeAgentModule>(m => m.Name == "edgeAgent");
            var edgeHub              = Mock.Of <IEdgeHubModule>(m => m.Name == "edgeHub");
            var mod1                 = Mock.Of <IRuntimeModule>(m => m.Name == "mod1" && m.RuntimeStatus == ModuleStatus.Running);
            var mod2                 = Mock.Of <IRuntimeModule>(m => m.Name == "mod2" && m.RuntimeStatus == ModuleStatus.Running);
            var deploymentConfigInfo = new DeploymentConfigInfo(
                1,
                new DeploymentConfig(
                    "1.0",
                    Mock.Of <IRuntimeInfo>(),
                    new SystemModules(edgeAgent, edgeHub),
                    new Dictionary <string, IModule>
            {
                ["mod1"] = mod1,
                ["mod2"] = mod2
            },
                    null));
            var configSource = Mock.Of <IConfigSource>(c => c.GetDeploymentConfigInfoAsync() == Task.FromResult(deploymentConfigInfo));

            var moduleSet           = ModuleSet.Create(edgeAgent, edgeHub, mod1, mod2);
            var environment         = Mock.Of <IEnvironment>(e => e.GetModulesAsync(cts.Token) == Task.FromResult(moduleSet));
            var environmentProvider = Mock.Of <IEnvironmentProvider>(e => e.Create(deploymentConfigInfo.DeploymentConfig) == environment);

            var restartCommand = new Mock <ICommand>(MockBehavior.Strict);

            restartCommand.Setup(r => r.ExecuteAsync(cts.Token))
            .Returns(Task.CompletedTask);
            var commandFactory = new Mock <ICommandFactory>(MockBehavior.Strict);

            commandFactory.Setup(c => c.RestartAsync(mod1)).ReturnsAsync(restartCommand.Object);

            var restartRequestHandler = new RestartRequestHandler(environmentProvider, configSource, commandFactory.Object);

            string payload = "{\"schemaVersion\": \"1.0\",\"id\": \"mod1\"}";

            // Act
            Option <string> response = await restartRequestHandler.HandleRequest(Option.Some(payload), cts.Token);

            // Assert
            Assert.False(response.HasValue);
            restartCommand.Verify(r => r.ExecuteAsync(cts.Token), Times.Once);
            commandFactory.Verify(c => c.RestartAsync(mod1), Times.Once);
            Mock.Get(configSource).VerifyAll();
            Mock.Get(environmentProvider).VerifyAll();
            Mock.Get(environment).VerifyAll();
        }
Beispiel #24
0
        public async void ReconcileAsyncOnEmptyPlan()
        {
            var token                              = default(CancellationToken);
            var serde                              = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var mockConfigSource                   = new Mock <IConfigSource>();
            var mockEnvironment                    = new Mock <IEnvironment>();
            var mockEnvironmentProvider            = new Mock <IEnvironmentProvider>();
            var mockPlanner                        = new Mock <IPlanner>();
            var mockPlanRunner                     = new Mock <IPlanRunner>();
            var mockReporter                       = new Mock <IReporter>();
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var runtimeInfo                        = Mock.Of <IRuntimeInfo>();
            var configStore                        = Mock.Of <IEntityStore <string, string> >();
            var encryptionDecryptionProvider       = Mock.Of <IEncryptionProvider>();
            var availabilityMetric                 = Mock.Of <IAvailabilityMetric>();

            var deploymentConfig = new DeploymentConfig(
                "1.0",
                runtimeInfo,
                new SystemModules(null, null),
                new Dictionary <string, IModule>
            {
                { "mod1", new TestModule("mod1", "1.0", "docker", ModuleStatus.Running, new TestConfig("boo"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null) }
            });
            var       deploymentConfigInfo = new DeploymentConfigInfo(0, deploymentConfig);
            ModuleSet desiredModuleSet     = deploymentConfig.GetModuleSet();
            ModuleSet currentModuleSet     = desiredModuleSet;

            mockEnvironmentProvider.Setup(m => m.Create(It.IsAny <DeploymentConfig>())).Returns(mockEnvironment.Object);
            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(env => env.GetModulesAsync(token))
            .ReturnsAsync(currentModuleSet);
            mockEnvironment.Setup(env => env.GetRuntimeInfoAsync()).ReturnsAsync(runtimeInfo);
            mockModuleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(It.Is <ModuleSet>(ms => ms.Equals(desiredModuleSet)), currentModuleSet))
            .ReturnsAsync(ImmutableDictionary <string, IModuleIdentity> .Empty);
            mockPlanner.Setup(pl => pl.PlanAsync(It.Is <ModuleSet>(ms => ms.Equals(desiredModuleSet)), currentModuleSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty))
            .Returns(Task.FromResult(Plan.Empty));

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider.Object, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider, availabilityMetric);

            await agent.ReconcileAsync(token);

            mockEnvironment.Verify(env => env.GetModulesAsync(token), Times.Once);
            mockPlanner.Verify(pl => pl.PlanAsync(It.Is <ModuleSet>(ms => ms.Equals(desiredModuleSet)), currentModuleSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty), Times.Once);
            mockReporter.Verify(r => r.ReportAsync(token, currentModuleSet, runtimeInfo, DeploymentConfigInfo.Empty.Version, DeploymentStatus.Success), Times.Once);
            mockPlanRunner.Verify(r => r.ExecuteAsync(1, Plan.Empty, token), Times.Never);
        }
        public async void CreateSuccess()
        {
            File.WriteAllText(this.tempFileName, ValidJson1);

            using (FileConfigSource configSource = await FileConfigSource.Create(this.tempFileName, this.config, this.serde))
            {
                Assert.NotNull(configSource);
                DeploymentConfigInfo deploymentConfigInfo = await configSource.GetDeploymentConfigInfoAsync();

                Assert.NotNull(deploymentConfigInfo);
                Assert.NotNull(deploymentConfigInfo.DeploymentConfig);
                ModuleSet moduleSet = deploymentConfigInfo.DeploymentConfig.GetModuleSet();
                Diff      emptyDiff = ValidSet1.Diff(moduleSet);
                Assert.True(emptyDiff.IsEmpty);
            }
        }
        public async void ConfigsWithExceptionsDoNotBackUp()
        {
            DeploymentConfigInfo configInfo = SetupExceptionDeployment();
            var underlying = new Mock <IConfigSource>();

            underlying.Setup(u => u.GetDeploymentConfigInfoAsync()).ReturnsAsync(configInfo);
            var backup = new Mock <IDeploymentBackupSource>();

            backup.SetupGet(b => b.Name).Returns("backup");

            var backupSource = new BackupConfigSource(backup.Object, underlying.Object);
            var result1      = await backupSource.GetDeploymentConfigInfoAsync();

            Assert.Equal(configInfo, result1);
            underlying.VerifyAll();
            backup.VerifyAll();
        }
Beispiel #27
0
        public async void GetDeploymentConfigTest1()
        {
            // Arrange
            var edgeAgentConnection = new Mock <IEdgeAgentConnection>();

            edgeAgentConnection.Setup(e => e.GetDeploymentConfigInfoAsync()).ReturnsAsync(Option.None <DeploymentConfigInfo>());
            var configuration    = Mock.Of <IConfiguration>();
            var twinConfigSource = new TwinConfigSource(edgeAgentConnection.Object, configuration);

            // Act
            DeploymentConfigInfo deploymentConfigInfo = await twinConfigSource.GetDeploymentConfigInfoAsync();

            // Assert
            Assert.NotNull(deploymentConfigInfo);
            Assert.Equal(-1, deploymentConfigInfo.Version);
            Assert.Equal(DeploymentConfig.Empty, deploymentConfigInfo.DeploymentConfig);
        }
Beispiel #28
0
        public async void ReconcileAsyncWithNoDeploymentChange()
        {
            var desiredModule = new TestModule("CustomModule", "v1", "test", ModuleStatus.Running, new TestConfig("image"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null);
            var currentModule = new TestModule("CustomModule", "v1", "test", ModuleStatus.Running, new TestConfig("image"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null);

            var testPlan         = new Plan(new List <ICommand>());
            var token            = default(CancellationToken);
            var runtimeInfo      = Mock.Of <IRuntimeInfo>();
            var deploymentConfig = new DeploymentConfig("1.0", runtimeInfo, new SystemModules(null, null), new Dictionary <string, IModule> {
                ["CustomModule"] = desiredModule
            });
            var       deploymentConfigInfo = new DeploymentConfigInfo(0, deploymentConfig);
            ModuleSet desiredSet           = deploymentConfig.GetModuleSet();
            ModuleSet currentSet           = ModuleSet.Create(currentModule);

            var mockConfigSource = new Mock <IConfigSource>();
            var mockEnvironment  = new Mock <IEnvironment>();
            var mockPlanner      = new Mock <IPlanner>();
            var planRunner       = new OrderedPlanRunner();
            var mockReporter     = new Mock <IReporter>();
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var configStore             = Mock.Of <IEntityStore <string, string> >();
            var mockEnvironmentProvider = Mock.Of <IEnvironmentProvider>(m => m.Create(It.IsAny <DeploymentConfig>()) == mockEnvironment.Object);
            var serde = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var encryptionDecryptionProvider = Mock.Of <IEncryptionProvider>();
            var availabilityMetric           = Mock.Of <IAvailabilityMetric>();

            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(env => env.GetModulesAsync(token))
            .ReturnsAsync(currentSet);
            mockModuleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(desiredSet, currentSet))
            .ReturnsAsync(ImmutableDictionary <string, IModuleIdentity> .Empty);
            mockPlanner.Setup(pl => pl.PlanAsync(It.IsAny <ModuleSet>(), currentSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty))
            .Returns(Task.FromResult(testPlan));
            mockReporter.Setup(r => r.ReportAsync(token, It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <long>(), DeploymentStatus.Success))
            .Returns(Task.CompletedTask);

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider, mockPlanner.Object, planRunner, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider, availabilityMetric);

            await agent.ReconcileAsync(token);

            mockEnvironment.Verify(env => env.GetModulesAsync(token), Times.Exactly(1));
            mockPlanner.Verify(pl => pl.PlanAsync(It.IsAny <ModuleSet>(), currentSet, runtimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty), Times.Once);
            mockReporter.Verify(r => r.ReportAsync(token, It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <long>(), DeploymentStatus.Success), Times.Once);
        }
Beispiel #29
0
        public async void ReconcileAsyncAbortsWhenModuleIdentityLifecycleManagerThrows()
        {
            // Arrange
            var mockConfigSource = new Mock <IConfigSource>();
            var mockEnvironment  = new Mock <IEnvironment>();
            var mockPlanner      = new Mock <IPlanner>();
            var mockPlanRunner   = new Mock <IPlanRunner>();
            var mockReporter     = new Mock <IReporter>();
            var token            = default(CancellationToken);
            var mockModuleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
            var configStore             = Mock.Of <IEntityStore <string, string> >();
            var mockEnvironmentProvider = Mock.Of <IEnvironmentProvider>(m => m.Create(It.IsAny <DeploymentConfig>()) == mockEnvironment.Object);
            var serde = Mock.Of <ISerde <DeploymentConfigInfo> >();
            var encryptionDecryptionProvider = Mock.Of <IEncryptionProvider>();
            var availabilityMetric           = Mock.Of <IAvailabilityMetric>();

            var deploymentConfig = new DeploymentConfig(
                "1.0",
                Mock.Of <IRuntimeInfo>(),
                new SystemModules(null, null),
                new Dictionary <string, IModule>
            {
                { "mod1", new TestModule("mod1", "1.0", "docker", ModuleStatus.Running, new TestConfig("boo"), RestartPolicy.OnUnhealthy, ImagePullPolicy.OnCreate, new ConfigurationInfo("1"), null) }
            });
            var       deploymentConfigInfo = new DeploymentConfigInfo(0, deploymentConfig);
            ModuleSet desiredModuleSet     = deploymentConfig.GetModuleSet();

            mockConfigSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            mockEnvironment.Setup(env => env.GetModulesAsync(token))
            .ReturnsAsync(ModuleSet.Empty);
            mockModuleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(It.Is <ModuleSet>(ms => ms.Equals(desiredModuleSet)), ModuleSet.Empty))
            .Throws <InvalidOperationException>();
            mockReporter.Setup(r => r.ReportAsync(token, It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <long>(), It.Is <DeploymentStatus>(s => s.Code == DeploymentStatusCode.Failed)))
            .Returns(Task.CompletedTask);

            var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider, availabilityMetric);

            // Act
            // Assert
            await agent.ReconcileAsync(token);

            mockPlanner.Verify(p => p.PlanAsync(It.IsAny <ModuleSet>(), It.IsAny <ModuleSet>(), It.IsAny <IRuntimeInfo>(), It.IsAny <ImmutableDictionary <string, IModuleIdentity> >()), Times.Never);
            mockReporter.VerifyAll();
            mockPlanRunner.Verify(r => r.ExecuteAsync(1, It.IsAny <Plan>(), token), Times.Never);
        }
Beispiel #30
0
        FileConfigSource(FileSystemWatcher watcher, DeploymentConfigInfo initial, IConfiguration configuration, ISerde <DeploymentConfigInfo> serde)
        {
            this.watcher        = Preconditions.CheckNotNull(watcher, nameof(watcher));
            this.Configuration  = Preconditions.CheckNotNull(configuration, nameof(configuration));
            this.current        = new AtomicReference <DeploymentConfigInfo>(Preconditions.CheckNotNull(initial, nameof(initial)));
            this.serde          = Preconditions.CheckNotNull(serde, nameof(serde));
            this.configFilePath = Path.Combine(this.watcher.Path, this.watcher.Filter);

            this.sync = new AsyncLock();
            this.watcherSubscription = Observable
                                       .FromEventPattern <FileSystemEventArgs>(this.watcher, "Changed")
                                       // Rx.NET's "Throttle" is really "Debounce". An unfortunate naming mishap.
                                       .Throttle(TimeSpan.FromMilliseconds(FileChangeWatcherDebounceInterval))
                                       .Subscribe(this.WatcherOnChanged);
            this.watcher.EnableRaisingEvents = true;
            Events.Created(this.configFilePath);
        }