public async Task ExecuteSuccessfulTests( CommandMethodExpr commandMethodBeingTested, Task <ICommand> commandBeingDecorated, TestExecutionExpr testExpr) { var token = new CancellationToken(); var logFactoryMock = new Mock <ILoggerFactory>(); var logMock = new Mock <ILogger <LoggingCommandFactory> >(); var factoryMock = new Mock <ICommandFactory>(); // mock the command factory method being tested, // have the mock return an appropriate command that should be decorated by the LoggingCommandFactory factoryMock.Setup(commandMethodBeingTested) .Returns(commandBeingDecorated); // use this ILogger mock for verification. logFactoryMock.Setup(l => l.CreateLogger(It.IsAny <string>())) .Returns(logMock.Object); var factory = new LoggingCommandFactory(factoryMock.Object, logFactoryMock.Object); // Execute the test expression ICommand create = await testExpr(factory); // attempt to execute the LoggingCommand we received await create.ExecuteAsync(token); // Assert decorated command is executed, and command is logged. factoryMock.Verify(commandMethodBeingTested); logMock.Verify(l => l.Log(LogLevel.Information, It.IsAny <EventId>(), It.IsAny <object>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); logMock.Verify(l => l.Log(LogLevel.Debug, It.IsAny <EventId>(), It.IsAny <object>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); }
public async Task UndoFailureTests( CommandMethodExpr commandMethodBeingTested, Task <ICommand> commandBeingDecorated, TestExecutionExpr testExpr) { var token = new CancellationToken(); var logFactoryMock = new Mock <ILoggerFactory>(); var logMock = new Mock <ILogger <LoggingCommandFactory> >(); var factoryMock = new Mock <ICommandFactory>(); factoryMock.Setup(commandMethodBeingTested) .Returns(Task.FromResult <ICommand>(FailureCommand.Instance)); logFactoryMock.Setup(l => l.CreateLogger(It.IsAny <string>())) .Returns(logMock.Object); var factory = new LoggingCommandFactory(factoryMock.Object, logFactoryMock.Object); ICommand create = await testExpr(factory); await Assert.ThrowsAsync <ArgumentException>(() => create.UndoAsync(token)); factoryMock.Verify(commandMethodBeingTested); logMock.Verify(l => l.Log(LogLevel.Information, It.IsAny <EventId>(), It.IsAny <object>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); logMock.Verify(l => l.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <object>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); }
public async Task UndoSuccessTests( CommandMethodExpr commandMethodBeingTested, Task <ICommand> commandBeingDecorated, TestExecutionExpr testExpr) { var token = new CancellationToken(); var logFactoryMock = new Mock <ILoggerFactory>(); var logMock = new Mock <ILogger <LoggingCommandFactory> >(); var factoryMock = new Mock <ICommandFactory>(); factoryMock.Setup(commandMethodBeingTested) .Returns(commandBeingDecorated); logFactoryMock.Setup(l => l.CreateLogger(It.IsAny <string>())) .Returns(logMock.Object); var factory = new LoggingCommandFactory(factoryMock.Object, logFactoryMock.Object); ICommand create = await testExpr(factory); await create.UndoAsync(token); factoryMock.Verify(commandMethodBeingTested); logMock.Verify(l => l.Log(LogLevel.Information, It.IsAny <EventId>(), It.IsAny <object>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); logMock.Verify(l => l.Log(LogLevel.Debug, It.IsAny <EventId>(), It.IsAny <object>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); }
public async void TestShow() { var logFactoryMock = new Mock <ILoggerFactory>(); var factoryMock = new Mock <ICommandFactory>(); var moduleIdentity = new Mock <IModuleIdentity>(); var runtimeInfo = Mock.Of <IRuntimeInfo>(); Task <ICommand> nullCmd = NullCommandFactory.Instance.CreateAsync(new ModuleWithIdentity(TestModule, moduleIdentity.Object), runtimeInfo); factoryMock.Setup(f => f.CreateAsync(It.IsAny <IModuleWithIdentity>(), runtimeInfo)) .Returns(nullCmd); var factory = new LoggingCommandFactory(factoryMock.Object, logFactoryMock.Object); ICommand create = await factory.CreateAsync(new ModuleWithIdentity(TestModule, moduleIdentity.Object), runtimeInfo); Assert.Equal(create.Show(), nullCmd.Result.Show()); }
protected override void Load(ContainerBuilder builder) { // IKubernetesClient builder.Register( c => { if (this.enableServiceCallTracing) { // enable tracing of k8s requests made by the client var loggerFactory = c.Resolve <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger(typeof(Kubernetes)); ServiceClientTracing.IsEnabled = true; ServiceClientTracing.AddTracingInterceptor(new DebugTracer(logger)); } // load the k8s config from KUBECONFIG or $HOME/.kube/config or in-cluster if its available KubernetesClientConfiguration kubeConfig = Option.Maybe(Environment.GetEnvironmentVariable("KUBECONFIG")) .Else(() => Option.Maybe(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".kube", "config"))) .Filter(File.Exists) .Map(path => KubernetesClientConfiguration.BuildConfigFromConfigFile(path)) .GetOrElse(KubernetesClientConfiguration.InClusterConfig); return(new Kubernetes(kubeConfig)); }) .As <IKubernetes>() .SingleInstance(); // IModuleClientProvider builder.Register( c => new ModuleClientProvider( c.Resolve <ISdkModuleClientProvider>(), this.upstreamProtocol, this.proxy, this.productInfo.OrDefault(), this.closeOnIdleTimeout, this.idleTimeout)) .As <IModuleClientProvider>() .SingleInstance(); // IModuleManager builder.Register(c => new ModuleManagementHttpClient(this.managementUri, this.apiVersion, Core.Constants.EdgeletClientApiVersion)) .As <IModuleManager>() .As <IIdentityManager>() .SingleInstance(); // IModuleIdentityLifecycleManager var identityBuilder = new ModuleIdentityProviderServiceBuilder(this.resourceName.Hostname, this.resourceName.DeviceId, this.edgeDeviceHostName); builder.Register(c => new KubernetesModuleIdentityLifecycleManager(c.Resolve <IIdentityManager>(), identityBuilder, this.workloadUri)) .As <IModuleIdentityLifecycleManager>() .SingleInstance(); // CombinedKubernetesConfigProvider builder.Register( c => { bool enableKubernetesExtensions = this.experimentalFeatures.Enabled && this.experimentalFeatures.EnableExtensions; return(new CombinedKubernetesConfigProvider(this.dockerAuthConfig, this.workloadUri, this.managementUri, enableKubernetesExtensions)); }) .As <ICombinedConfigProvider <CombinedKubernetesConfig> >() .SingleInstance(); // ICommandFactory builder.Register( c => { var loggerFactory = c.Resolve <ILoggerFactory>(); var kubernetesCommandFactory = new KubernetesCommandFactory(); ICommandFactory factory = new LoggingCommandFactory(kubernetesCommandFactory, loggerFactory); return(Task.FromResult(factory)); }) .As <Task <ICommandFactory> >() .SingleInstance(); // IPlanner builder.Register( async c => { var configProvider = c.Resolve <ICombinedConfigProvider <CombinedKubernetesConfig> >(); ICommandFactory commandFactory = await c.Resolve <Task <ICommandFactory> >(); IPlanner planner = new KubernetesPlanner(this.deviceNamespace, this.resourceName, c.Resolve <IKubernetes>(), commandFactory, configProvider); return(planner); }) .As <Task <IPlanner> >() .SingleInstance(); // KubernetesRuntimeInfoProvider builder.Register(c => new KubernetesRuntimeInfoProvider(this.deviceNamespace, c.Resolve <IKubernetes>(), c.Resolve <IModuleManager>())) .As <IRuntimeInfoProvider>() .As <IRuntimeInfoSource>() .SingleInstance(); // KubernetesDeploymentProvider builder.Register( c => new KubernetesDeploymentMapper( this.deviceNamespace, this.edgeDeviceHostName, this.proxyImage, this.proxyConfigPath, this.proxyConfigVolumeName, this.proxyConfigMapName, this.proxyTrustBundlePath, this.proxyTrustBundleVolumeName, this.proxyTrustBundleConfigMapName, this.persistentVolumeName, this.storageClassName, this.apiVersion, this.workloadUri, this.managementUri)) .As <IKubernetesDeploymentMapper>(); // KubernetesServiceMapper builder.Register(c => new KubernetesServiceMapper(this.defaultMapServiceType)) .As <IKubernetesServiceMapper>(); // KubernetesPvcMapper builder.Register(c => new KubernetesPvcMapper(this.persistentVolumeName, this.storageClassName, this.persistentVolumeClaimSizeMb)) .As <IKubernetesPvcMapper>(); // KubernetesServiceAccountProvider builder.Register(c => new KubernetesServiceAccountMapper()) .As <IKubernetesServiceAccountMapper>(); // EdgeDeploymentController builder.Register( c => { var deploymentSelector = $"{Constants.K8sEdgeDeviceLabel}={KubeUtils.SanitizeK8sValue(this.resourceName.DeviceId)},{Constants.K8sEdgeHubNameLabel}={KubeUtils.SanitizeK8sValue(this.resourceName.Hostname)}"; IEdgeDeploymentController watchOperator = new EdgeDeploymentController( this.resourceName, deploymentSelector, this.deviceNamespace, c.Resolve <IKubernetes>(), c.Resolve <IModuleIdentityLifecycleManager>(), c.Resolve <IKubernetesServiceMapper>(), c.Resolve <IKubernetesDeploymentMapper>(), c.Resolve <IKubernetesPvcMapper>(), c.Resolve <IKubernetesServiceAccountMapper>()); return(watchOperator); }) .As <IEdgeDeploymentController>() .SingleInstance(); // IEdgeDeploymentOperator builder.Register( c => { IEdgeDeploymentOperator watchOperator = new EdgeDeploymentOperator( this.resourceName, this.deviceNamespace, c.Resolve <IKubernetes>(), c.Resolve <IEdgeDeploymentController>()); return(watchOperator); }) .As <IEdgeDeploymentOperator>() .SingleInstance(); // IKubernetesEnvironmentOperator builder.Register( c => { IKubernetesEnvironmentOperator watchOperator = new KubernetesEnvironmentOperator( this.deviceNamespace, c.Resolve <IRuntimeInfoSource>(), c.Resolve <IKubernetes>()); return(watchOperator); }) .As <IKubernetesEnvironmentOperator>() .SingleInstance(); // Task<IEnvironmentProvider> builder.Register( async c => { var moduleStateStore = c.Resolve <IEntityStore <string, ModuleState> >(); var restartPolicyManager = c.Resolve <IRestartPolicyManager>(); IRuntimeInfoProvider runtimeInfoProvider = c.Resolve <IRuntimeInfoProvider>(); IEnvironmentProvider dockerEnvironmentProvider = await DockerEnvironmentProvider.CreateAsync(runtimeInfoProvider, moduleStateStore, restartPolicyManager); return(dockerEnvironmentProvider); }) .As <Task <IEnvironmentProvider> >() .SingleInstance(); }
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); } }