├── .gitattributes
├── .gitignore
├── .travis.yml
├── .vscode
├── launch.json
└── tasks.json
├── LICENSE
├── PartitioningAgent.Test
├── AgentTest.cs
├── PartitioningAgent.Test.csproj
└── helpers
│ ├── Constants.cs
│ ├── SomeException.cs
│ └── TaskExtensions.cs
├── PartitioningAgent
├── Agent.cs
└── PartitioningAgent.csproj
├── README.md
├── Services.Test
├── AzureManagementAdapterTest.cs
├── Clustering
│ ├── ClusterNodesTest.cs
│ ├── ClusteringConfigTest.cs
│ └── DevicePartitionsTest.cs
├── Concurrency
│ ├── LoopSettingsTest.cs
│ ├── PerMinuteCounterTest.cs
│ ├── PerSecondCounterTest.cs
│ └── RatedCounterTest.cs
├── CustomDeviceModelsTest.cs
├── DataStructures
│ ├── InstanceTest.cs
│ └── ListExtensionsTest.cs
├── DeviceClientTest.cs
├── DeviceModelScriptsTest.cs
├── DeviceModelsGenerationTest.cs
├── DeviceModelsTest.cs
├── DevicePropertiesTest.cs
├── DevicesTest.cs
├── Diagnostics
│ └── DiagnosticsLoggerTest.cs
├── IntegrationTests
│ └── README.md
├── IotHub
│ ├── ConnectionStringValidationTest.cs
│ └── ConnectionStringsTest.cs
├── IotHubMetricsTest.cs
├── Models
│ ├── DeviceModelTest.cs
│ └── SimulationTest.cs
├── README.md
├── ReplayFileServiceTest.cs
├── Runtime
│ └── ConfigDataTest.cs
├── Services.Test.csproj
├── Simulation
│ └── JavascriptInterpreterTest.cs
├── SimulationsTest.cs
├── SmartDictionaryTest.cs
├── Statistics
│ └── SimulationStatisticsTest.cs
├── StockDeviceModelTest.cs
├── Storage
│ ├── ConfigTest.cs
│ ├── CosmosDbSql
│ │ ├── DataRecordTest.cs
│ │ └── EngineTest.cs
│ ├── EnginesTest.cs
│ └── TableStorage
│ │ ├── DataRecordTest.cs
│ │ └── EngineTest.cs
└── helpers
│ ├── Constants.cs
│ ├── SomeException.cs
│ ├── TargetLogger.cs
│ └── TaskExtensions.cs
├── Services
├── AzureManagementAdapter
│ ├── AadTokenModel.cs
│ ├── AutoScaleSettingsModel.cs
│ ├── AzureManagementAdapter.cs
│ └── MetricsModel.cs
├── Clustering
│ ├── ClusterNodes.cs
│ ├── ClusteringConfig.cs
│ └── DevicePartitions.cs
├── Concurrency
│ ├── ConcurrencyConfig.cs
│ ├── ETags.cs
│ ├── LoopSettings.cs
│ ├── RateLimiting.cs
│ ├── RateLimitingConfig.cs
│ ├── RatedCounter.cs
│ ├── ThreadWrapper.cs
│ └── Timer.cs
├── CustomDeviceModels.cs
├── DataStructures
│ ├── Instance.cs
│ ├── ListExtensions.cs
│ └── SmartDictionary.cs
├── DeviceClient.cs
├── DeviceMethods.cs
├── DeviceModelScripts.cs
├── DeviceModels.cs
├── DeviceModelsGeneration.cs
├── DeviceProperties.cs
├── Devices.cs
├── Diagnostics
│ ├── ActorsLogger.cs
│ ├── ActorsLoggerShim.cs
│ ├── DiagnosticsLogger.cs
│ ├── IActorsLogger.cs
│ ├── ILogger.cs
│ ├── Logger.cs
│ ├── LoggingConfig.cs
│ └── Serialization.cs
├── Exceptions
│ ├── BrokenDeviceClientException.cs
│ ├── ConflictingResourceException.cs
│ ├── CustomException.cs
│ ├── DailyTelemetryQuotaExceededException.cs
│ ├── DeviceAuthFailedException.cs
│ ├── ExternalDependencyException.cs
│ ├── InvalidConfigurationException.cs
│ ├── InvalidInputException.cs
│ ├── InvalidIotHubConnectionStringFormatException.cs
│ ├── IotHubConnectionException.cs
│ ├── PropertySendException.cs
│ ├── ResourceIsLockedByAnotherOwnerException.cs
│ ├── ResourceNotFoundException.cs
│ ├── ResourceOutOfDateException.cs
│ ├── TelemetrySendException.cs
│ ├── TelemetrySendIOException.cs
│ ├── TelemetrySendTimeoutException.cs
│ ├── TotalDeviceCountQuotaExceededException.cs
│ └── UnknownMessageFormatException.cs
├── FileWrapper.cs
├── Http
│ ├── HttpClient.cs
│ ├── HttpRequest.cs
│ ├── HttpRequestOptions.cs
│ └── HttpResponse.cs
├── IotHub
│ ├── ConnectionStringValidation.cs
│ ├── ConnectionStrings.cs
│ ├── DeviceClientWrapper.cs
│ ├── IothubMetrics.cs
│ ├── RegistryManagerWrapper.cs
│ └── ServiceClientWrapper.cs
├── Models
│ ├── DataFile.cs
│ ├── Device.cs
│ ├── DeviceModel.cs
│ ├── DevicesPartition.cs
│ ├── IoTHubProtocol.cs
│ ├── Protobuf
│ │ ├── Truck.cs
│ │ └── proto
│ │ │ └── Truck.proto
│ ├── README.md
│ ├── Simulation.cs
│ ├── SimulationPatch.cs
│ └── SimulationStatisticsModel.cs
├── PreprovisionedIotHub.cs
├── ReplayFileService.cs
├── Runtime
│ ├── ConfigData.cs
│ ├── DeploymentConfig.cs
│ ├── Factory.cs
│ └── ServicesConfig.cs
├── Services.csproj
├── Simulation
│ ├── InternalInterpreter.cs
│ ├── JavascriptInterpreter.cs
│ └── ScriptInterpreter.cs
├── Simulations.cs
├── Statistics
│ ├── SimulationStatistics.cs
│ └── SimulationStatisticsRecord.cs
├── StockDeviceModels.cs
├── Storage
│ ├── Config.cs
│ ├── CosmosDbSql
│ │ ├── DataRecord.cs
│ │ ├── Engine.cs
│ │ └── SDKWrapper.cs
│ ├── Engines.cs
│ ├── IDataRecord.cs
│ ├── IEngine.cs
│ ├── TableStorage
│ │ ├── DataRecord.cs
│ │ ├── Engine.cs
│ │ └── SDKWrapper.cs
│ └── Type.cs
├── StorageAdapter
│ ├── StorageAdapterClient.cs
│ ├── ValueApiModel.cs
│ └── ValueListApiModel.cs
├── Utilities.cs
└── data
│ ├── devicemodels
│ ├── README.md
│ ├── chiller-01.json
│ ├── chiller-02.json
│ ├── delivery-truck-01.json
│ ├── delivery-truck-02.json
│ ├── elevator-01.json
│ ├── elevator-02.json
│ ├── engine-01.json
│ ├── engine-02.json
│ ├── prototype-01.json
│ ├── prototype-02.json
│ ├── scripts
│ │ ├── EmergencyValveRelease-method.js
│ │ ├── EmptyTank-method.js
│ │ ├── FillTank-method.js
│ │ ├── FirmwareUpdate-method.js
│ │ ├── IncreasePressure-method.js
│ │ ├── README.md
│ │ ├── Reboot-method.js
│ │ ├── SetFuelLevel-method.js
│ │ ├── SetTemperature-method.js
│ │ ├── StartElevator-method.js
│ │ ├── StartMovingDevice-method.js
│ │ ├── StopElevator-method.js
│ │ ├── StopMovingDevice-method.js
│ │ ├── TempDecrease-method.js
│ │ ├── TempIncrease-method.js
│ │ ├── chiller-01-state.js
│ │ ├── chiller-02-state.js
│ │ ├── delivery-truck-01-state.js
│ │ ├── delivery-truck-02-state.js
│ │ ├── elevator-01-state.js
│ │ ├── elevator-02-state.js
│ │ ├── engine-01-state.js
│ │ ├── engine-02-state.js
│ │ ├── prototype-01-state.js
│ │ ├── prototype-02-state.js
│ │ ├── truck-01-state.js
│ │ └── truck-02-state.js
│ ├── truck-01-protobuf.json
│ ├── truck-01.json
│ └── truck-02.json
│ ├── iothub
│ └── README.md
│ ├── replayfile
│ ├── replay.json
│ └── simulationReplayTest.csv
│ └── templates
│ ├── multiple-simulations-template.json
│ └── remote-monitoring-simulations-template.json
├── SimulationAgent.Test
├── DeviceConnection
│ ├── ConnectTest.cs
│ ├── DeregisterTest.cs
│ ├── DeviceConnectionActorTest.cs
│ └── DisconnectTest.cs
├── DeviceProperties
│ ├── DevicePropertiesActorTest.cs
│ ├── SetDeviceTagTest.cs
│ └── UpdateReportedPropertiesTest.cs
├── DeviceState
│ └── DeviceStateActorTest.cs
├── DeviceTelemetry
│ └── DeviceTelemetryActorTest.cs
├── SimulationAgent.Test.csproj
├── SimulationManagerTest.cs
├── SimulationThreads
│ ├── DeviceConnectionTaskTest.cs
│ ├── DeviceReplayTaskTest.cs
│ ├── DeviceStateTaskTest.cs
│ ├── DeviceTelemetryTaskTest.cs
│ └── UpdatePropertiesTaskTest.cs
└── helpers
│ ├── Constants.cs
│ ├── Http
│ ├── HttpClient.cs
│ ├── HttpRequest.cs
│ ├── HttpRequestOptions.cs
│ └── HttpResponse.cs
│ └── TaskExtensions.cs
├── SimulationAgent
├── Agent.cs
├── DeviceConnection
│ ├── Connect.cs
│ ├── CredentialsSetup.cs
│ ├── DeRegister.cs
│ ├── DeviceConnectionActor.cs
│ ├── Disconnect.cs
│ ├── FetchFromRegistry.cs
│ ├── IDeviceConnectionLogic.cs
│ └── Register.cs
├── DeviceProperties
│ ├── DevicePropertiesActor.cs
│ ├── IDevicePropertiesLogic.cs
│ ├── SetDeviceTag.cs
│ └── UpdateReportedProperties.cs
├── DeviceReplay
│ └── DeviceReplayActor.cs
├── DeviceState
│ ├── DeviceStateActor.cs
│ └── UpdateDeviceState.cs
├── DeviceTelemetry
│ ├── DeviceTelemetryActor.cs
│ ├── IDeviceTelemetryLogic.cs
│ └── SendTelemetry.cs
├── SimulationAgent.csproj
├── SimulationContext.cs
├── SimulationManager.cs
└── SimulationThreads
│ ├── DeviceConnectionTask.cs
│ ├── DeviceReplayTask.cs
│ ├── DeviceStateTask.cs
│ ├── DeviceTelemetryTask.cs
│ └── UpdatePropertiesTask.cs
├── WebService.Test
├── IntegrationTests
│ └── README.md
├── README.md
├── WebService.Test.csproj
├── helpers
│ ├── Constants.cs
│ ├── Http
│ │ ├── HttpClient.cs
│ │ ├── HttpRequest.cs
│ │ ├── HttpRequestOptions.cs
│ │ └── HttpResponse.cs
│ ├── SomeException.cs
│ ├── TaskExtensions.cs
│ └── WebServiceHost.cs
└── v1
│ ├── Controllers
│ ├── DeviceModelPropertiesControllerTest.cs
│ ├── DeviceModelScriptsControllerTest.cs
│ ├── DeviceModelsControllerTest.cs
│ ├── SimulationsControllerTest.cs
│ └── StatusControllerTest.cs
│ └── Models
│ ├── DeviceModelApiModel
│ ├── DeviceModelApiModelTest.cs
│ ├── DeviceModelSimulationScriptTest.cs
│ ├── DeviceModelSimulationTest.cs
│ ├── DeviceModelTelemetrySchemaTest.cs
│ └── DeviceModelTelemetryTest.cs
│ ├── Helpers
│ └── DateHelperTest.cs
│ └── SimulationApiModel
│ ├── DeviceModelApiModelOverrideTest.cs
│ ├── DeviceModelSimulationOverrideTest.cs
│ ├── DeviceModelSimulationScriptOverrideTest.cs
│ ├── DeviceModelTelemetryMessageSchemaOverrideTest.cs
│ ├── DeviceModelTelemetryOverrideTest.cs
│ ├── MetricsApiModelTest.cs
│ ├── SimulationApiModelTest.cs
│ └── SimulationDeviceModelRefTest.cs
├── WebService
├── Auth
│ ├── AuthMiddleware.cs
│ ├── ClientAuthConfig.cs
│ ├── CorsSetup.cs
│ ├── CorsWhitelistModel.cs
│ ├── RequestExtension.cs
│ └── Startup.cs
├── DependencyResolution.cs
├── Program.cs
├── Properties
│ └── launchSettings.json
├── README.md
├── Runtime
│ ├── Config.cs
│ ├── ConfigFile.cs
│ └── Uptime.cs
├── Startup.cs
├── WebService.csproj
├── appsettings.ini
└── v1
│ ├── Controllers
│ ├── DeviceModelPropertiesController.cs
│ ├── DeviceModelScriptsController.cs
│ ├── DeviceModelsController.cs
│ ├── README.md
│ ├── ReplayFileController.cs
│ ├── SimulationsController.cs
│ └── StatusController.cs
│ ├── Exceptions
│ ├── BadRequestException.cs
│ ├── InvalidDateFormatException.cs
│ ├── InvalidIntervalException.cs
│ └── InvalidIotHubConnectionStringFormatException.cs
│ ├── Filters
│ └── ExceptionsFilterAttribute.cs
│ ├── Models
│ ├── DeviceModelApiModel
│ │ ├── DeviceModelApiModel.cs
│ │ ├── DeviceModelScript.cs
│ │ ├── DeviceModelSimulation.cs
│ │ ├── DeviceModelTelemetry.cs
│ │ └── DeviceModelTelemetryMessageSchema.cs
│ ├── DeviceModelListApiModel.cs
│ ├── DeviceModelPropertyListApiModel.cs
│ ├── DeviceModelScriptApiModel
│ │ └── DeviceModelScriptApiModel.cs
│ ├── DeviceModelScriptListModel.cs
│ ├── Devices
│ │ ├── BatchDeleteActionApiModel.cs
│ │ └── CreateActionApiModel.cs
│ ├── Helpers
│ │ ├── DateHelper.cs
│ │ ├── IntervalHelper.cs
│ │ └── ValidationApiModel.cs
│ ├── IoTHubApiModel.cs
│ ├── README.md
│ ├── ReplayFileApiModel.cs
│ ├── SimulationApiModel
│ │ ├── DeviceModelApiModelOverride.cs
│ │ ├── DeviceModelSimulationOverride.cs
│ │ ├── DeviceModelSimulationScriptOverride.cs
│ │ ├── DeviceModelTelemetryMessageSchemaOverride.cs
│ │ ├── DeviceModelTelemetryOverride.cs
│ │ ├── MetricsApiModel.cs
│ │ ├── SimulationApiModel.cs
│ │ ├── SimulationDeviceModelRef.cs
│ │ ├── SimulationIotHub.cs
│ │ ├── SimulationRateLimits.cs
│ │ └── SimulationStatistics.cs
│ ├── SimulationListApiModel.cs
│ ├── SimulationPatchApiModel.cs
│ └── StatusApiModel.cs
│ └── Version.cs
├── device-simulation.sln
├── device-simulation.sln.DotSettings
├── docs
├── API_SPECS_DEVICE_MODELS.md
├── API_SPECS_DEVICE_MODEL_PROPERTIES.md
├── API_SPECS_DEVICE_MODEL_SCRIPTS.md
├── API_SPECS_SERVICE.md
├── API_SPECS_SIMULATIONS.md
├── BREAKING_CHANGES.md
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DEVICE_MODELS.md
├── ENVIRONMENT_VARIABLES.md
├── INDEX.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
├── overview.png
└── postman
│ ├── Azure IoT Device Simulation solution accelerator.postman_collection.json
│ └── Azure IoT Device Simulation solution accelerator.postman_environment.json
├── global.json
└── scripts
├── .functions.sh
├── build
├── build.cmd
├── clean-up
├── clean-up.cmd
├── compile
├── compile.cmd
├── development
├── create-simulation.sh
├── delete-simulation.sh
├── postman_collection.json
└── start-storage-adapter.sh
├── docker
├── .dockerignore
├── Dockerfile
├── build
├── build.cmd
├── content
│ └── run.sh
├── docker-compose.yml
├── publish
├── publish.cmd
├── run
└── run.cmd
├── env-vars-check
├── env-vars-check.cmd
├── env-vars-setup
├── env-vars-setup.cmd
├── git
├── .functions.sh
├── fix-perms.sh
├── pre-commit-runner-no-sandbox.sh
├── pre-commit-runner-with-sandbox.sh
├── pre-commit.sh
├── setup
└── setup.cmd
├── run
├── run.cmd
├── travis
└── travis.cmd
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Copyright (c) Microsoft. All rights reserved.
2 |
3 | # Auto-detect text files, ensure they use LF.
4 | * text=auto eol=lf
5 |
6 | # Bash scripts
7 | *.sh text eol=lf
8 | scripts/build text eol=lf
9 | scripts/clean-up text eol=lf
10 | scripts/compile text eol=lf
11 | scripts/env-vars-check text eol=lf
12 | scripts/env-vars-setup text eol=lf
13 | scripts/run text eol=lf
14 | scripts/travis text eol=lf
15 | scripts/docker/build text eol=lf
16 | scripts/docker/publish text eol=lf
17 | scripts/docker/run text eol=lf
18 | scripts/git/setup text eol=lf
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | mono: none
3 | dotnet: 3.1
4 | sudo: false
5 | cache:
6 | directories:
7 | - "$HOME/.nuget/"
8 | before_install:
9 | - set -e
10 | addons:
11 | apt:
12 | packages:
13 | # This package is used only to address an issue in Travis CI, which would
14 | # otherwise install a newer 2.1.x preview, which breaks the build.
15 | script:
16 | - "bash ./$CODEBASE/scripts/build"
17 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "command": "dotnet",
4 | "isShellCommand": true,
5 | "args": [],
6 | "tasks": [
7 | {
8 | "taskName": "build",
9 | "args": [
10 | "${workspaceRoot}/WebService/WebService.csproj"
11 | ],
12 | "isBuildCommand": true,
13 | "problemMatcher": "$msCompile"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/PartitioningAgent.Test/PartitioningAgent.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | latest
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/PartitioningAgent.Test/helpers/Constants.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | namespace PartitioningAgent.Test.helpers
4 | {
5 | public static class Constants
6 | {
7 | // Use this to kill unit tests not supposed to run async code
8 | public const int TEST_TIMEOUT = 5000;
9 |
10 | // Use these flags to allow running a subset of tests from the test explorer and the command line.
11 | public const string TYPE = "Type";
12 | public const string UNIT_TEST = "UnitTest";
13 | public const string INTEGRATION_TEST = "IntegrationTest";
14 |
15 | // Use these flags to allow running a subset of tests from the test explorer and the command line.
16 | public const string SPEED = "Speed";
17 | public const string SLOW_TEST = "SlowTest";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PartitioningAgent.Test/helpers/SomeException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System;
4 |
5 | namespace PartitioningAgent.Test.helpers
6 | {
7 | /*
8 | This class is used to inject exceptions in the code under test and to verify that
9 | the system fails with the injected exception, i.e. not ANY exception.
10 | This is to avoid false negatives, i.e. to avoid that a test passes due to
11 | an unexpected exception.
12 |
13 | Example usage:
14 |
15 | this.dependencyMock.Setup(x => x.SomeMethod()).Throws();
16 |
17 | Assert.ThrowsAsync(() => this.target.MethodUnderTest())
18 | */
19 | public class SomeException : Exception
20 | {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/PartitioningAgent.Test/helpers/TaskExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System.Threading.Tasks;
4 | using Xunit.Sdk;
5 |
6 | namespace PartitioningAgent.Test.helpers
7 | {
8 | /**
9 | * Use this class when testing asynchronous code, to avoid tests
10 | * running forever, e.g. in case threads don't end as expected.
11 | *
12 | * Example:
13 | *
14 | * this.target.SomeMethodAsync().CompleteOrTimeout();
15 | *
16 | * var result = this.target.SomeMethodAsync().CompleteOrTimeout().Result;
17 | */
18 | public static class TaskExtensions
19 | {
20 | // Wait for the task to complete or timeout
21 | public static Task CompleteOrTimeout(this Task t)
22 | {
23 | var complete = t.Wait(Constants.TEST_TIMEOUT);
24 | if (!complete)
25 | {
26 | throw new TestTimeoutException(Constants.TEST_TIMEOUT);
27 | }
28 |
29 | return t;
30 | }
31 |
32 | // Wait for the task to complete or timeout
33 | public static Task CompleteOrTimeout(this Task t)
34 | {
35 | var complete = t.Wait(Constants.TEST_TIMEOUT);
36 | if (!complete)
37 | {
38 | throw new TestTimeoutException(Constants.TEST_TIMEOUT);
39 | }
40 |
41 | return t;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/PartitioningAgent/PartitioningAgent.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | Microsoft.Azure.IoTSolutions.DeviceSimulation.PartitioningAgent
6 | Microsoft.Azure.IoTSolutions.DeviceSimulation.PartitioningAgent
7 | latest
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Services.Test/Concurrency/LoopSettingsTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Concurrency;
4 | using Moq;
5 | using Services.Test.helpers;
6 | using Xunit;
7 | using Xunit.Abstractions;
8 |
9 | namespace Services.Test.Concurrency
10 | {
11 | public class LoopSettingsTest
12 | {
13 | private readonly ITestOutputHelper log;
14 | private readonly Mock rateLimitingConfig;
15 | private readonly PropertiesLoopSettings propertiesTarget;
16 |
17 | private const int TWIN_WRITES_PER_SECOND = 10;
18 |
19 | public LoopSettingsTest(ITestOutputHelper logger)
20 | {
21 | this.log = logger;
22 | this.rateLimitingConfig = new Mock();
23 | this.propertiesTarget = new PropertiesLoopSettings(this.rateLimitingConfig.Object);
24 | }
25 |
26 | [Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
27 | public void Should_SetTaggingLimit_When_NewLoopCreated()
28 | {
29 | // Arrange
30 | this.SetupRateLimitingConfig();
31 |
32 | // Act
33 | this.propertiesTarget.NewLoop();
34 |
35 | // Assert
36 | // In order for other threads to be able to schedule twin opertations,
37 | // value should be at least 1 but less than the limit per second.
38 | Assert.True(this.propertiesTarget.SchedulableTaggings >= 1);
39 | Assert.True(this.propertiesTarget.SchedulableTaggings < TWIN_WRITES_PER_SECOND);
40 | }
41 |
42 | [Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
43 | public void Should_UseTwinWrites_When_NewLoopCreated()
44 | {
45 | // Arrange
46 | this.SetupRateLimitingConfig();
47 |
48 | // Act
49 | this.propertiesTarget.NewLoop();
50 |
51 | // Assert
52 | // ensure twin writes were accessed and no other
53 | // config values to calculate properties limits
54 | this.rateLimitingConfig.VerifyGet(x => x.TwinWritesPerSecond);
55 | this.rateLimitingConfig.VerifyNoOtherCalls();
56 | }
57 |
58 | private void SetupRateLimitingConfig()
59 | {
60 | this.rateLimitingConfig.Setup(x => x.TwinWritesPerSecond).Returns(TWIN_WRITES_PER_SECOND);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Services.Test/Concurrency/RatedCounterTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Concurrency;
4 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Diagnostics;
5 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Exceptions;
6 | using Moq;
7 | using Services.Test.helpers;
8 | using Xunit;
9 |
10 | namespace Services.Test.Concurrency
11 | {
12 | public class RatedCounterTest
13 | {
14 | /**
15 | * Checks the configuration validation
16 | * Also covers https://github.com/Azure/device-simulation-dotnet/issues/122
17 | */
18 | [Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
19 | public void ItDoesNotAllowLowCounterRate()
20 | {
21 | Assert.Throws(() => new BadCounter1(new Mock().Object));
22 | Assert.Throws(() => new BadCounter2(new Mock().Object));
23 | }
24 |
25 | class BadCounter1 : RatedCounter
26 | {
27 | public BadCounter1(ILogger logger)
28 | : base(1, 999, "BadCounter1", logger)
29 | {
30 | }
31 | }
32 |
33 | class BadCounter2 : RatedCounter
34 | {
35 | public BadCounter2(ILogger logger)
36 | : base(0, 99999, "BadCounter2", logger)
37 | {
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Services.Test/DataStructures/InstanceTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System;
4 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.DataStructures;
5 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Diagnostics;
6 | using Moq;
7 | using Xunit;
8 |
9 | namespace Services.Test.DataStructures
10 | {
11 | public class InstanceTest
12 | {
13 | private Instance target;
14 | private readonly Mock mockLogger;
15 |
16 | public InstanceTest()
17 | {
18 | this.mockLogger = new Mock();
19 | this.target = new Instance(this.mockLogger.Object);
20 | }
21 |
22 | [Fact]
23 | public void ItThrowsIfInitOnceIsCalledAfterItIsInitialized()
24 | {
25 | // Arrange
26 | this.target = new Instance(this.mockLogger.Object);
27 | this.target.InitOnce();
28 | this.target.InitComplete();
29 |
30 | // Act, Assert
31 | Assert.Throws(
32 | () => this.target.InitOnce());
33 | }
34 |
35 | [Fact]
36 | public void ItDoesNotThrowIfInitOnceIsCalledBeforeItIsInitialized()
37 | {
38 | // Arrange
39 | this.target = new Instance(this.mockLogger.Object);
40 |
41 | // Act
42 | this.target.InitOnce();
43 | }
44 |
45 | [Fact]
46 | public void ItThrowsIfInitRequiredIsCalledBeforeInitialization()
47 | {
48 | // Arrange
49 | this.target = new Instance(this.mockLogger.Object);
50 |
51 | // Act, Assert
52 | Assert.Throws(
53 | () => this.target.InitRequired());
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Services.Test/DataStructures/ListExtensionsTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.DataStructures;
5 | using Xunit;
6 |
7 | namespace Services.Test.DataStructures
8 | {
9 | public class ListExtensionsTest
10 | {
11 | [Fact]
12 | void ItShufflesAList()
13 | {
14 | // Arrange
15 | var unshuffled = new List() { 1, 2, 3, 4, 5 };
16 |
17 | // Act
18 | var shuffled = new List(unshuffled);
19 | shuffled.Shuffle();
20 |
21 | // Assert
22 | Assert.Equal(unshuffled.Count, shuffled.Count);
23 | Assert.True(shuffled.Count > 0);
24 | var matches = 0;
25 | var cursor = unshuffled.Count;
26 | while (cursor-- > 1)
27 | {
28 | if (unshuffled[cursor] == shuffled[cursor])
29 | {
30 | matches++;
31 | }
32 | }
33 |
34 | Assert.True(matches < unshuffled.Count);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Services.Test/IntegrationTests/README.md:
--------------------------------------------------------------------------------
1 | Integration Tests
2 | =================
3 |
4 | ## Guidelines
5 |
6 | * Store here functional and integration tests, e.g. tests which require network
7 | access, storage read/write operations, etc.
8 | * Functional and Integration tests typically requires confuiguration settings,
9 | which should be provided similarly to the entry point application.
10 |
11 | ## Conventions
12 |
13 | * For each scenario create a test class with "Test" suffix.
14 | * Flag all the tests with `[Fact, Trait(Constants.Type, Constants.IntegrationTest)]`
15 |
--------------------------------------------------------------------------------
/Services.Test/IotHubMetricsTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.AzureManagementAdapter;
4 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.IotHub;
5 | using Moq;
6 | using Services.Test.helpers;
7 | using Xunit;
8 |
9 | namespace Services.Test
10 | {
11 | public class IotHubMetricsTest
12 | {
13 | private readonly Mock azureManagementAdapterClient;
14 | private readonly IotHubMetrics target;
15 |
16 | public IotHubMetricsTest()
17 | {
18 | this.azureManagementAdapterClient = new Mock();
19 | this.target = new IotHubMetrics(this.azureManagementAdapterClient.Object);
20 | }
21 |
22 | [Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
23 | public void ItInvokesAzureManagementAdapterOnceWhenQueryIothubMetrics()
24 | {
25 | // Act
26 | this.target.GetIothubMetricsAsync(It.IsAny())
27 | .Wait(Constants.TEST_TIMEOUT);
28 |
29 | // Assert
30 | this.azureManagementAdapterClient.Verify(
31 | x => x.PostAsync(It.IsAny()),
32 | Times.Once);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Services.Test/README.md:
--------------------------------------------------------------------------------
1 | Unit Tests and Integration Tests
2 | ================================
3 |
4 | ## Guidelines
5 |
6 |
7 |
8 | ## Conventions
9 |
10 | * For each class create a test class with "Test" suffix.
11 | * Flag all the tests with a type, e.g. `[Fact, Trait(Constants.Type, Constants.UnitTest)]`
12 | * Store Integration Tests under `IntegrationTests/` and use
13 | the `[Fact, Trait(Constants.Type, Constants.IntegrationTest)]` attribute
14 |
--------------------------------------------------------------------------------
/Services.Test/Services.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | latest
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Services.Test/Storage/ConfigTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Storage;
4 | using Services.Test.helpers;
5 | using Xunit;
6 |
7 | namespace Services.Test.Storage
8 | {
9 | public class ConfigTest
10 | {
11 | [Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
12 | public void ItDoesntHaveADefaultStorageType()
13 | {
14 | // Act
15 | var target = new Config();
16 |
17 | // Assert
18 | Assert.Equal(Type.Unknown, target.StorageType);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Services.Test/helpers/Constants.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | namespace Services.Test.helpers
4 | {
5 | public static class Constants
6 | {
7 | // Use this to kill unit tests not supposed to run async code
8 | public const int TEST_TIMEOUT = 5000;
9 |
10 | // Use these flags to allow running a subset of tests from the test explorer and the command line.
11 | public const string TYPE = "Type";
12 | public const string UNIT_TEST = "UnitTest";
13 | public const string INTEGRATION_TEST = "IntegrationTest";
14 |
15 | // Use these flags to allow running a subset of tests from the test explorer and the command line.
16 | public const string SPEED = "Speed";
17 | public const string SLOW_TEST = "SlowTest";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Services.Test/helpers/SomeException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System;
4 |
5 | namespace Services.Test.helpers
6 | {
7 | public class SomeException : Exception
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Services.Test/helpers/TaskExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System.Threading.Tasks;
4 | using Xunit.Sdk;
5 |
6 | namespace Services.Test.helpers
7 | {
8 | /**
9 | * Use this class when testing asynchronous code, to avoid tests
10 | * running forever, e.g. in case threads don't end as expected.
11 | *
12 | * Example:
13 | *
14 | * this.target.SomeMethodAsync().CompleteOrTimeout();
15 | *
16 | * var result = this.target.SomeMethodAsync().CompleteOrTimeout().Result;
17 | */
18 | public static class TaskExtensions
19 | {
20 | // Wait for the task to complete or timeout
21 | public static Task CompleteOrTimeout(this Task t)
22 | {
23 | var complete = t.Wait(Constants.TEST_TIMEOUT);
24 | if (!complete)
25 | {
26 | throw new TestTimeoutException(Constants.TEST_TIMEOUT);
27 | }
28 |
29 | return t;
30 | }
31 |
32 | // Wait for the task to complete or timeout
33 | public static Task CompleteOrTimeout(this Task t)
34 | {
35 | var complete = t.Wait(Constants.TEST_TIMEOUT);
36 | if (!complete)
37 | {
38 | throw new TestTimeoutException(Constants.TEST_TIMEOUT);
39 | }
40 |
41 | return t;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Services/AzureManagementAdapter/AadTokenModel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 |
6 | namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.AzureManagementAdapter
7 | {
8 | public class AadTokenModel
9 | {
10 | [JsonProperty("token_type", NullValueHandling = NullValueHandling.Ignore)]
11 | public string TokenType { get; set; }
12 |
13 | [JsonProperty("expires_on", NullValueHandling = NullValueHandling.Ignore)]
14 | public string ExpiresOn { get; set; }
15 |
16 | [JsonProperty("resource", NullValueHandling = NullValueHandling.Ignore)]
17 | public string Resource { get; set; }
18 |
19 | [JsonProperty("access_token", NullValueHandling = NullValueHandling.Ignore)]
20 | public string AccessToken { get; set; }
21 |
22 | [JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
23 | public string Error { get; set; }
24 |
25 | [JsonProperty("error_description", NullValueHandling = NullValueHandling.Ignore)]
26 | public string ErrorDescription { get; set; }
27 |
28 | [JsonProperty("error_codes", NullValueHandling = NullValueHandling.Ignore)]
29 | public List ErrorCodes { get; set; }
30 |
31 | [JsonProperty("trace_id", NullValueHandling = NullValueHandling.Ignore)]
32 | public string TraceId { get; set; }
33 |
34 | [JsonProperty("correlation_id", NullValueHandling = NullValueHandling.Ignore)]
35 | public string CorrelationId { get; set; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Services/AzureManagementAdapter/AutoScaleSettingsModel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 |
6 | namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.AzureManagementAdapter
7 | {
8 | public class AutoScaleSettingsCreateOrUpdateRequestModel
9 | {
10 | [JsonProperty("location")]
11 | public string Location { get; set; }
12 |
13 | [JsonProperty(PropertyName = "properties")]
14 | public Properties Properties { get; set; }
15 | }
16 |
17 | public class Properties
18 | {
19 | [JsonProperty("enabled")]
20 | public bool Enabled { get; set; }
21 |
22 | [JsonProperty("targetResourceUri")]
23 | public string TargetResourceUri { get; set; }
24 |
25 | [JsonProperty("profiles")]
26 | public List Profiles { get; set; }
27 | }
28 |
29 | public class Profile
30 | {
31 | [JsonProperty("name")]
32 | public string Name { get; set; }
33 |
34 | [JsonProperty("capacity")]
35 | public Capacity Capacity { get; set; }
36 |
37 | [JsonProperty("rules")]
38 | public List