public async void KubernetesPlannerPlanFailsWithNonDistinctModules() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("Module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet addRunning = ModuleSet.Create(m1, m2); var planner = new KubernetesPlanner <CombinedDockerConfig>(Ns, Hostname, DeviceId, DefaultClient, DefaultCommandFactory, DefaultConfigProvider); await Assert.ThrowsAsync <InvalidIdentityException>(() => planner.PlanAsync(addRunning, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty)); }
public async void KubernetesPlannerShutdownTest() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, Core.Constants.DefaultPriority, DefaultConfigurationInfo, EnvVars, Secrets); ModuleSet current = ModuleSet.Create(m1); var planner = new KubernetesPlanner(ResourceName, Selector, Namespace, DefaultClient, DefaultCommandFactory, ConfigProvider, EdgeletModuleOwner); var plan = await planner.CreateShutdownPlanAsync(current); Assert.Equal(Plan.Empty, plan); }
public async Task <Plan> CreateShutdownPlanAsync(ModuleSet current) { IEnumerable <Task <ICommand> > stopTasks = current.Modules.Values .Where(c => !c.Name.Equals(Constants.EdgeAgentModuleName, StringComparison.OrdinalIgnoreCase)) .Select(m => this.commandFactory.StopAsync(m)); IList <ICommand> commands = await Task.WhenAll(stopTasks); Events.PlanCreated(commands); return(new Plan(commands)); }
public static ModuleSet FromEnumerable(IEnumerable <Module> source) { var result = new ModuleSet(); foreach (var module in source) { result.Add(module); } return(result); }
public async void KubernetesPlannerShutdownTest() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet current = ModuleSet.Create(m1); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, DefaultConfigProvider); var plan = await planner.CreateShutdownPlanAsync(current); Assert.Equal(Plan.Empty, plan); }
public Slot(Vector3i position, AbstractMap map, bool initializeModuleHealth) { this.Position = position; this.map = map; this.Modules = new ModuleSet(initializeFull: true); if (initializeModuleHealth) { this.ModuleHealth = map.CopyInititalModuleHealth(); } }
public void RemoveModules(ModuleSet modulesToRemove, bool recursive = true) { #if UNITY_EDITOR Slot.iterationCount++; #endif foreach (var module in modulesToRemove) { if (!this.Modules.Contains(module) || module == this.Module) { continue; } if (this.map.History != null && this.map.History.Any()) { this.map.History.Peek().RemoveModule(this, module); } for (int d = 0; d < 6; d++) { int inverseDirection = (d + 3) % 6; var neighbor = this.GetNeighbor(d); if (neighbor == null) { continue; } for (int i = 0; i < module.PossibleNeighbors[d].Length; i++) { var possibleNeighbor = module.PossibleNeighbors[d][i]; if (neighbor.ModuleHealth[inverseDirection][possibleNeighbor.Index] == 1 && neighbor.Modules.Contains(possibleNeighbor)) { this.map.RemovalQueue[neighbor.Position].Add(possibleNeighbor); } #if UNITY_EDITOR if (neighbor.ModuleHealth[inverseDirection][possibleNeighbor.Index] < 1) { throw new System.InvalidOperationException("ModuleHealth must not be negative. " + this.Position + " d: " + d); } #endif neighbor.ModuleHealth[inverseDirection][possibleNeighbor.Index]--; } } this.Modules.Remove(module); } if (this.Modules.Count == 0) { throw new CollapseFailedException(this); } if (recursive) { this.map.FinishRemovalQueue(); } }
public void RemoveModules(ModuleSet modulesToRemove) { var affectedNeighbouredModules = Enumerable.Range(0, 6).Select(_ => new ModuleSet()).ToArray(); foreach (var module in modulesToRemove) { if (!this.Modules.Contains(module) || module == this.Module) { continue; } if (this.mapGenerator.History != null && this.mapGenerator.History.Any()) { this.mapGenerator.History.Peek().RemoveModule(this, module); } for (int d = 0; d < 6; d++) { int inverseDirection = (d + 3) % 6; var neighbor = this.GetNeighbor(d); if (neighbor == null) { continue; } foreach (var possibleNeighbor in module.PossibleNeighbors[d]) { if (neighbor.ModuleHealth[inverseDirection][possibleNeighbor.Index] == 1) { affectedNeighbouredModules[d].Add(possibleNeighbor); } #if UNITY_EDITOR if (neighbor.ModuleHealth[inverseDirection][possibleNeighbor.Index] < 1) { throw new System.InvalidOperationException("ModuleHealth must not be negative."); } #endif neighbor.ModuleHealth[inverseDirection][possibleNeighbor.Index]--; } } this.Modules.Remove(module); } if (this.Modules.Count == 0) { throw new CollapseFailedException(this); } for (int d = 0; d < 6; d++) { if (affectedNeighbouredModules[d].Any() && this.GetNeighbor(d) != null && !this.GetNeighbor(d).Collapsed) { this.GetNeighbor(d).RemoveModules(affectedNeighbouredModules[d]); } } }
public async Task <Plan> PlanAsync( ModuleSet desired, ModuleSet current, IRuntimeInfo runtimeInfo, IImmutableDictionary <string, IModuleIdentity> moduleIdentities) { Events.LogDesired(desired); Events.LogCurrent(current); Events.LogIdentities(moduleIdentities); // Check that module names sanitize and remain unique. var groupedModules = desired.Modules.ToLookup(pair => KubeUtils.SanitizeK8sValue(pair.Key)); if (groupedModules.Any(c => c.Count() > 1)) { string nameList = groupedModules .Where(c => c.Count() > 1) .SelectMany(g => g, (pairs, pair) => pair.Key) .Join(","); throw new InvalidIdentityException($"Deployment will cause a name collision in Kubernetes namespace, modules: [{nameList}]"); } // TODO: improve this so it is generic for all potential module types. if (!desired.Modules.Values.All(p => p is IModule <DockerConfig>)) { throw new InvalidModuleException($"Kubernetes deployment currently only handles type={typeof(DockerConfig).FullName}"); } Diff moduleDifference = desired.Diff(current); Plan plan; if (!moduleDifference.IsEmpty) { // The "Plan" here is very simple - if we have any change, publish all desired modules to a EdgeDeployment CRD. // The CRD allows us to give the customer a Kubernetes-centric way to see the deployment // and the status of that deployment through the "edgedeployments" API. var crdCommand = new EdgeDeploymentCommand(this.deviceNamespace, this.resourceName, this.client, desired.Modules.Values, runtimeInfo, this.configProvider); var planCommand = await this.commandFactory.WrapAsync(crdCommand); var planList = new List <ICommand> { planCommand }; Events.PlanCreated(planList); plan = new Plan(planList); } else { plan = Plan.Empty; } return(plan); }
public void TestApplyDiff(ModuleSet starting, Diff diff, ModuleSet expected) { ModuleSet updated = starting.ApplyDiff(diff); Assert.Equal(expected.Modules.Count, updated.Modules.Count); foreach (KeyValuePair <string, IModule> module in expected.Modules) { Assert.True(updated.TryGetModule(module.Key, out IModule updatedMod)); Assert.Equal(module.Value, updatedMod); } }
public async void KubernetesPlannerEmptyPlanWhenNoChanges() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("module2", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet desired = ModuleSet.Create(m1, m2); ModuleSet current = ModuleSet.Create(m1, m2); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider); var plan = await planner.PlanAsync(desired, current, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.Equal(Plan.Empty, plan); }
public async void ReconcileAsyncReportsFailedWhenEncryptProviderThrows() { var token = new 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 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, new ConfigurationInfo("1"), null) } }); var desiredModule = new TestModule("desired", "v1", "test", ModuleStatus.Running, new TestConfig("image"), RestartPolicy.OnUnhealthy, new ConfigurationInfo("1"), null); Option <TestPlanRecorder> 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 IoTEdgedException("failed", 404, "", null, null)); var agent = new Agent(mockConfigSource.Object, mockEnvironmentProvider.Object, mockPlanner.Object, mockPlanRunner.Object, mockReporter.Object, mockModuleIdentityLifecycleManager.Object, configStore, DeploymentConfigInfo.Empty, serde, encryptionDecryptionProvider.Object); 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, Option.Some(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)); }
public void OnHitRangeLimit(Vector3Int position, ModuleSet modulesToRemove) { if (this.muteRangeLimitWarning || position.y < 0 || position.y >= this.Height) { return; } var moduleNames = modulesToRemove.Select(module => module.Name); Debug.LogWarning("Hit range limit at " + position + ". Module(s) to be removed:\n" + string.Join("\n", moduleNames.ToArray()) + "\n"); this.muteRangeLimitWarning = true; }
DiffState ProcessDiff(ModuleSet desired, ModuleSet current) { Diff diff = desired.Diff(current); IList <IModule> added = diff.Added.ToList(); IList <IRuntimeModule> removed = diff.Removed.Select(name => (IRuntimeModule)current.Modules[name]).ToList(); // We are interested in 3 kinds of "updated" modules: // // [1] someone pushed a new deployment for this device that changed something // for an existing module // [2] someone pushed a new deployment for this device that changed the desired // status of a module (running to stopped, or stopped to running) // [3] something changed in the runtime state of the module - for example, it // had a tragic untimely death // We need to be able to distinguish between the three cases because we handle them differently IList <IModule> updateDeployed = diff.Updated.ToList(); IList <IModule> desiredStatusUpdated = diff.DesiredStatusUpdated.ToList(); // Get the list of modules unaffected by deployment ISet <string> modulesInDeployment = diff.AddedOrUpdated .Concat(diff.DesiredStatusUpdated) .Select(m => m.Name) .Concat(diff.Removed) .ToImmutableHashSet(); IList <IRuntimeModule> currentRuntimeModules = current.Modules.Values .Select(m => (IRuntimeModule)m) .Where(m => !modulesInDeployment.Contains(m.Name)) .Except(updateDeployed.Select(m => current.Modules[m.Name] as IRuntimeModule)).ToList(); // Find the modules whose desired and runtime status are not the same IList <IRuntimeModule> updateStateChanged = currentRuntimeModules .Where(m => m.DesiredStatus != m.RuntimeStatus && m.RuntimeStatus != ModuleStatus.Dead).ToList(); // Identify dead modules IList <IRuntimeModule> dead = currentRuntimeModules .Where(m => m.RuntimeStatus == ModuleStatus.Dead).ToList(); // Apart from all of the lists above, there can be modules in "current" where neither // the desired state has changed nor the runtime state has changed. For example, a module // that is expected to be "running" continues to run just fine. This won't show up in // any of the lists above. But we are still interested in these because we want to clear // the restart stats on them when they have been behaving well for "intensiveCareTime". // // Note that we are only interested in "running" modules. If there's a module that was // expected to be in the "stopped" state and continues to be in the "stopped" state, that // is not very interesting to us. IList <IRuntimeModule> runningGreat = currentRuntimeModules .Where(m => m.DesiredStatus == ModuleStatus.Running && m.RuntimeStatus == ModuleStatus.Running).ToList(); return(added, updateDeployed, desiredStatusUpdated, updateStateChanged, removed, dead, runningGreat); }
public void ComputeAvailability(ModuleSet desired, ModuleSet current) { IEnumerable <IRuntimeModule> modulesToCheck = current.Modules.Values .OfType <IRuntimeModule>() .Where(m => m.Name != Constants.EdgeAgentModuleName); /* Get all modules that are not running but should be */ var down = new HashSet <string>(modulesToCheck .Where(m => m.RuntimeStatus != ModuleStatus.Running && desired.Modules.TryGetValue(m.Name, out var d) && d.DesiredStatus == ModuleStatus.Running) .Select(m => m.Name)); /* Get all correctly running modules */ var up = new HashSet <string>(modulesToCheck .Where(m => m.RuntimeStatus == ModuleStatus.Running) .Select(m => m.Name)); /* handle edgeAgent specially */ this.edgeAgent.Value.AddPoint(true); this.running.Set(this.edgeAgent.Value.ExpectedTime.TotalSeconds, new[] { this.edgeAgent.Value.Name, true.ToString() }); this.expectedRunning.Set(this.edgeAgent.Value.RunningTime.TotalSeconds, new[] { this.edgeAgent.Value.Name, true.ToString() }); /* Add points for all other modules found */ foreach (Availability availability in this.availabilities) { if (down.Remove(availability.Name)) { availability.AddPoint(false); } else if (up.Remove(availability.Name)) { availability.AddPoint(true); } else { /* stop calculating if in intentional stopped state or not deployed */ availability.NoPoint(); } string[] tags = new string[] { availability.Name, (availability.Name == Constants.EdgeHubModuleName).ToString() }; this.running.Set(availability.RunningTime.TotalSeconds, tags); this.expectedRunning.Set(availability.ExpectedTime.TotalSeconds, tags); } /* Add new modules to track */ foreach (string module in down.Union(up)) { this.availabilities.Add(new Availability(module, this.systemTime)); } }
public void SetModuleSet(ModuleSet modSet, ButtonPress callBack, Select select) { moduleSet = modSet; buttonCallBack = callBack; selectCallBack = select; ModuleName.text = moduleSet.GetName(); ModuleDescription.text = moduleSet.GetDescription(); ModuleMod.text = moduleSet.GetParentModName(); ModuleTexture.overrideSprite = moduleSet.GetTexture(); ModuleTexture.preserveAspect = true; }
public async void KubernetesPlannerPlanExistsWhenChangesMade() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("module2", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet desired = ModuleSet.Create(m1); ModuleSet current = ModuleSet.Create(m2); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider); var plan = await planner.PlanAsync(desired, current, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.Single(plan.Commands); Assert.True(plan.Commands.First() is EdgeDeploymentCommand); }
public async Task <Plan> PlanAsync( ModuleSet desired, ModuleSet current, IRuntimeInfo runtimeInfo, IImmutableDictionary <string, IModuleIdentity> moduleIdentities) { Events.LogDesired(desired); Events.LogCurrent(current); List <ICommand> commands = new List <ICommand>(); // WARN: handles all secret commands irrespective of priority commands.AddRange(await GetUpdateSecretsCommands(desired.Modules.Values, current.Modules.Values)); // Create a grouping of desired and current modules based on their priority. // We want to process all the modules in the deployment (desired modules) and also include the modules // that are not specified in the deployment but are currently running on the device. This is so that // their processing is done in the right priority order. ILookup <uint, KeyValuePair <string, IModule> > desiredPriorityGroups = desired.Modules.ToLookup(x => x.Value.Priority); ILookup <uint, KeyValuePair <string, IModule> > currentPriorityGroups = current.Modules.ToLookup(x => x.Value.Priority); ImmutableSortedSet <uint> orderedPriorities = desiredPriorityGroups .Select(x => x.Key) .Union(currentPriorityGroups.Select(x => x.Key)) .ToImmutableSortedSet(); ISet <string> processedDesiredMatchingCurrentModules = new HashSet <string>(); foreach (uint priority in orderedPriorities) { // The desired set is all the desired modules that have the priority of the current priority group being evaluated. ModuleSet priorityBasedDesiredSet = ModuleSet.Create(desiredPriorityGroups[priority].Select(x => x.Value).ToArray()); // The current set is: // - All the current modules that correspond to the desired modules present in the current priority group. // - All the current modules that have the priority of the current priority group being evaluated which were not specified in the desired deployment config // -and- have not already been processed yet. // These are included so that they can be stopped and removed in the right priority order. IEnumerable <KeyValuePair <string, IModule> > desiredMatchingCurrentModules = current.Modules.Where(x => priorityBasedDesiredSet.Modules.ContainsKey(x.Key)); ModuleSet priorityBasedCurrentSet = ModuleSet.Create( desiredMatchingCurrentModules .Union(currentPriorityGroups[priority].Where(x => !processedDesiredMatchingCurrentModules.Contains(x.Key))) .Select(y => y.Value) .ToArray() ); processedDesiredMatchingCurrentModules.UnionWith(desiredMatchingCurrentModules.Select(x => x.Key)); commands.AddRange(await this.ProcessDesiredAndCurrentSets(priorityBasedDesiredSet, priorityBasedCurrentSet, runtimeInfo, moduleIdentities)); } Events.PlanCreated(commands); return(new Plan(commands)); }
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 void Remove(ModuleSet set) { for (int i = 0; i < this.data.Length; i++) { long current = this.data[i]; long updated = current & ~set.data[i]; if (current != updated) { this.data[i] = updated; this.entropyOutdated = true; } } }
public void ComputeAvailability(ModuleSet desired, ModuleSet current) { /* Get all modules that are not running but should be */ var down = new HashSet <string>(current.Modules.Values .Where(c => (c is IRuntimeModule) && (c as IRuntimeModule).RuntimeStatus != ModuleStatus.Running && desired.Modules.TryGetValue(c.Name, out var d) && d.DesiredStatus == ModuleStatus.Running) .Select(c => c.Name)); /* Get all correctly running modules */ var up = new HashSet <string>(current.Modules.Values .Where(c => (c is IRuntimeModule) && (c as IRuntimeModule).RuntimeStatus == ModuleStatus.Running) .Select(c => c.Name)); /* handle edgeAgent specially */ this.edgeAgent.Value.AddPoint(true); down.Remove("edgeAgent"); up.Remove("edgeAgent"); this.running.Set(this.edgeAgent.Value.ExpectedTime.TotalSeconds, new[] { this.edgeAgent.Value.Name }); this.expectedRunning.Set(this.edgeAgent.Value.RunningTime.TotalSeconds, new[] { this.edgeAgent.Value.Name }); /* Add points for all other modules found */ foreach (Availability availability in this.availabilities) { if (down.Remove(availability.Name)) { availability.AddPoint(false); } else if (up.Remove(availability.Name)) { availability.AddPoint(true); } else { /* stop calculating if in intentional stopped state or not deployed */ availability.NoPoint(); } this.running.Set(availability.RunningTime.TotalSeconds, new[] { availability.Name }); this.expectedRunning.Set(availability.ExpectedTime.TotalSeconds, new[] { availability.Name }); } /* Add new modules to track */ foreach (string module in down.Union(up)) { this.availabilities.Add(new Availability(module, this.time)); } }
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(); }
/// <summary> /// Removes all modules that are not in the supplied set. /// </summary> /// <param name="moduleSet"></param> /// <returns></returns> public void Intersect(ModuleSet moduleSet) { for (int i = 0; i < this.data.Length; i++) { long current = this.data[i]; long mask = moduleSet.data[i]; long updated = current & mask; if (current != updated) { this.data[i] = updated; this.entropyOutdated = true; } } }
public EdgeDeploymentOperator( ResourceName resourceName, string deviceNamespace, IKubernetes client, IEdgeDeploymentController controller) { this.deviceNamespace = Preconditions.CheckNonWhiteSpace(deviceNamespace, nameof(deviceNamespace)); this.resourceName = Preconditions.CheckNotNull(resourceName, nameof(resourceName)); this.client = Preconditions.CheckNotNull(client, nameof(client)); this.operatorWatch = Option.None <Watcher <EdgeDeploymentDefinition> >(); this.controller = Preconditions.CheckNotNull(controller, nameof(controller)); this.currentModules = ModuleSet.Empty; }
public void SetModuleSet(ModuleSet modSet, ButtonPress callBack, Select select) { moduleSet = modSet; buttonCallBack = callBack; selectCallBack = select; ModuleName.text = moduleSet.GetName(); ModuleDescription.text = moduleSet.GetDescription(); ModuleMod.text = "Mod: " + moduleSet.GetParentModName(); Texture2D texture = moduleSet.GetTexture(); ModuleTexture.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); ModuleTexture.preserveAspect = true; }
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); } }
protected void SwapModulesInList(ModuleSet newModuleSet, List <SlotedModule> sectionModules) { foreach (SlotedModule slotedModule in sectionModules) { if (slotedModule.module.GetParentSet().SwapType == newModuleSet.SwapType) { foreach (Module newModule in newModuleSet.GetModules()) { if (slotedModule.module.SizeX == newModule.SizeX && slotedModule.module.SizeY == newModule.SizeY) { slotedModule.SwapModule(newModule); } } } } }
public async void TestNullEnvironment() { NullEnvironment testNullEnvironment = NullEnvironment.Instance; Assert.NotNull(testNullEnvironment); var token = new CancellationToken(); ModuleSet testModuleSet = await testNullEnvironment.GetModulesAsync(token); Assert.NotNull(testModuleSet); Assert.Equal(testModuleSet, ModuleSet.Empty); IRuntimeInfo runtimeInfo = await testNullEnvironment.GetRuntimeInfoAsync(); Assert.NotNull(runtimeInfo); Assert.True(ReferenceEquals(runtimeInfo, UnknownRuntimeInfo.Instance)); }
public async Task CheckIfCreateDeploymentWithServiceNoPvcIsSuccessful() { var moduleName = "module-a"; var deviceSelector = $"{Kubernetes.Constants.K8sEdgeDeviceLabel}=deviceid"; var moduleLifeCycleManager = this.CreateModuleLifeCycleManager(moduleName); var controller = this.CreateDeploymentController(deviceSelector, moduleLifeCycleManager, string.Empty); KubernetesModule km1 = this.CreateKubernetesModuleWithExposedPorts(moduleName); moduleLifeCycleManager.SetModules(moduleName); await controller.DeployModulesAsync(ModuleSet.Create(km1), ModuleSet.Empty); this.AssertNoMatchingDeployments(deviceSelector, moduleName); this.AssertNoMatchingServiceAccounts(deviceSelector, moduleName); this.AssertNoMatchingService(deviceSelector, moduleName); this.AssertNoPvcsExist(); }