protected override void Load(ContainerBuilder builder) { // IModuleClientProvider string edgeAgentConnectionString = $"{this.edgeDeviceConnectionString};{Constants.ModuleIdKey}={Constants.EdgeAgentModuleIdentityName}"; builder.Register( c => new ModuleClientProvider( edgeAgentConnectionString, c.Resolve <ISdkModuleClientProvider>(), this.upstreamProtocol, this.proxy, this.productInfo, this.closeOnIdleTimeout, this.idleTimeout)) .As <IModuleClientProvider>() .SingleInstance(); // IServiceClient builder.Register(c => new RetryingServiceClient(new ServiceClient(this.edgeDeviceConnectionString, this.deviceId))) .As <IServiceClient>() .SingleInstance(); // IModuleIdentityLifecycleManager builder.Register(c => new ModuleIdentityLifecycleManager(c.Resolve <IServiceClient>(), this.iotHubHostName, this.deviceId, this.gatewayHostName)) .As <IModuleIdentityLifecycleManager>() .SingleInstance(); // IDockerClient builder.Register(c => new DockerClientConfiguration(this.dockerHostname).CreateClient()) .As <IDockerClient>() .SingleInstance(); // ICombinedConfigProvider<CombinedDockerConfig> builder.Register(c => new CombinedDockerConfigProvider(this.dockerAuthConfig)) .As <ICombinedConfigProvider <CombinedDockerConfig> >() .SingleInstance(); // ICommandFactory builder.Register( async c => { var dockerClient = c.Resolve <IDockerClient>(); var dockerLoggingConfig = c.Resolve <DockerLoggingConfig>(); var combinedDockerConfigProvider = c.Resolve <ICombinedConfigProvider <CombinedDockerConfig> >(); IConfigSource configSource = await c.Resolve <Task <IConfigSource> >(); var dockerFactory = new DockerCommandFactory(dockerClient, dockerLoggingConfig, configSource, combinedDockerConfigProvider); return(new LoggingCommandFactory(dockerFactory, c.Resolve <ILoggerFactory>()) as ICommandFactory); }) .As <Task <ICommandFactory> >() .SingleInstance(); // IRuntimeInfoProvider builder.Register( async c => { IRuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(c.Resolve <IDockerClient>()); return(runtimeInfoProvider); }) .As <Task <IRuntimeInfoProvider> >() .SingleInstance(); // Task<IEnvironmentProvider> builder.Register( async c => { var moduleStateStore = await c.Resolve <Task <IEntityStore <string, ModuleState> > >(); var restartPolicyManager = c.Resolve <IRestartPolicyManager>(); IRuntimeInfoProvider runtimeInfoProvider = await c.Resolve <Task <IRuntimeInfoProvider> >(); IEnvironmentProvider dockerEnvironmentProvider = await DockerEnvironmentProvider.CreateAsync(runtimeInfoProvider, moduleStateStore, restartPolicyManager); return(dockerEnvironmentProvider); }) .As <Task <IEnvironmentProvider> >() .SingleInstance(); // IDeviceManager builder.Register(c => new NullDeviceManager()) .As <IDeviceManager>() .SingleInstance(); }
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); } }