Skip to content
This repository was archived by the owner on Oct 11, 2023. It is now read-only.

Commit 942b2d5

Browse files
ap-git-hubsaixiaohui
authored andcommitted
Replay file APIs (#333)
* Replay file APIs * update settings * PR comments * update owners * typo * Update DeviceModelScriptsTest.cs
1 parent e2af381 commit 942b2d5

21 files changed

+583
-54
lines changed

Services.Test/DeviceModelScriptsTest.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ public void ItCreatesDeviceModelScriptInStorage()
4949
// Arrange
5050
var id = Guid.NewGuid().ToString();
5151
var eTag = Guid.NewGuid().ToString();
52-
var deviceModelScript = new DeviceModelScript { Id = id, ETag = eTag };
52+
var deviceModelScript = new DataFile { Id = id, ETag = eTag };
5353

5454
this.storage
5555
.Setup(x => x.UpdateAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
5656
.ReturnsAsync(this.BuildValueApiModel(deviceModelScript));
5757

5858
// Act
59-
DeviceModelScript result = this.target.InsertAsync(deviceModelScript).Result;
59+
DataFile result = this.target.InsertAsync(deviceModelScript).Result;
6060

6161
// Assert
6262
Assert.NotNull(result);
@@ -73,10 +73,10 @@ public void DeviceModelScriptsCanBeUpserted()
7373
// Arrange
7474
var id = Guid.NewGuid().ToString();
7575

76-
var deviceModelScript = new DeviceModelScript { Id = id, ETag = "oldEtag" };
76+
var deviceModelScript = new DataFile { Id = id, ETag = "oldEtag" };
7777
this.TheScriptExists(id, deviceModelScript);
7878

79-
var updatedSimulationScript = new DeviceModelScript { Id = id, ETag = "newETag" };
79+
var updatedSimulationScript = new DataFile { Id = id, ETag = "newETag" };
8080
this.storage
8181
.Setup(x => x.UpdateAsync(
8282
STORAGE_COLLECTION,
@@ -94,7 +94,7 @@ public void DeviceModelScriptsCanBeUpserted()
9494
this.storage.Verify(x => x.UpdateAsync(
9595
STORAGE_COLLECTION,
9696
id,
97-
It.Is<string>(json => JsonConvert.DeserializeObject<DeviceModelScript>(json).Id == id && !json.Contains("ETag")),
97+
It.Is<string>(json => JsonConvert.DeserializeObject<DataFile>(json).Id == id && !json.Contains("ETag")),
9898
"oldEtag"), Times.Once());
9999

100100
Assert.Equal(updatedSimulationScript.Id, deviceModelScript.Id);
@@ -107,7 +107,7 @@ public void ItCreatesDeviceModelScriptWhenSimulationScriptNotFoundInUpserting()
107107
{
108108
// Arrange
109109
var id = Guid.NewGuid().ToString();
110-
var deviceModelScript = new DeviceModelScript { Id = id, ETag = "Etag" };
110+
var deviceModelScript = new DataFile { Id = id, ETag = "Etag" };
111111
this.TheScriptDoesntExist(id);
112112
this.storage
113113
.Setup(x => x.UpdateAsync(
@@ -133,11 +133,11 @@ public void ItThrowsConflictingResourceExceptionIfEtagDoesNotMatchInUpserting()
133133
{
134134
// Arrange
135135
var id = Guid.NewGuid().ToString();
136-
var deviceModelScriptInStorage = new DeviceModelScript { Id = id, ETag = "ETag" };
136+
var deviceModelScriptInStorage = new DataFile { Id = id, ETag = "ETag" };
137137
this.TheScriptExists(id, deviceModelScriptInStorage);
138138

139139
// Act & Assert
140-
var deviceModelScript = new DeviceModelScript { Id = id, ETag = "not-matching-Etag" };
140+
var deviceModelScript = new DataFile { Id = id, ETag = "not-matching-Etag" };
141141
Assert.ThrowsAsync<ConflictingResourceException>(
142142
async () => await this.target.UpsertAsync(deviceModelScript))
143143
.Wait(Constants.TEST_TIMEOUT);
@@ -147,7 +147,7 @@ public void ItThrowsConflictingResourceExceptionIfEtagDoesNotMatchInUpserting()
147147
public void ItThrowsExceptionWhenInsertDeviceModelScriptFailed()
148148
{
149149
// Arrange
150-
var deviceModelScript = new DeviceModelScript { Id = "id", ETag = "Etag" };
150+
var deviceModelScript = new DataFile { Id = "id", ETag = "Etag" };
151151
this.storage
152152
.Setup(x => x.UpdateAsync(
153153
It.IsAny<string>(),
@@ -166,7 +166,7 @@ public void ItThrowsExceptionWhenInsertDeviceModelScriptFailed()
166166
public void ItFailsToUpsertWhenUnableToFetchScriptFromStorage()
167167
{
168168
// Arrange
169-
var deviceModelScript = new DeviceModelScript { Id = "id", ETag = "Etag" };
169+
var deviceModelScript = new DataFile { Id = "id", ETag = "Etag" };
170170
this.storage
171171
.Setup(x => x.GetAsync(It.IsAny<string>(), It.IsAny<string>()))
172172
.ThrowsAsync(new SomeException());
@@ -182,7 +182,7 @@ public void ItFailsToUpsertWhenStorageUpdateFails()
182182
{
183183
// Arrange
184184
var id = Guid.NewGuid().ToString();
185-
var deviceModelScript = new DeviceModelScript { Id = id, ETag = "Etag" };
185+
var deviceModelScript = new DataFile { Id = id, ETag = "Etag" };
186186
this.TheScriptExists(id, deviceModelScript);
187187

188188
this.storage
@@ -203,7 +203,7 @@ public void ItFailsToUpsertWhenStorageUpdateFails()
203203
public void ItThrowsExternalDependencyExceptionWhenFailedFetchingDeviceModelScriptInStorage()
204204
{
205205
// Arrange
206-
var deviceModelScript = new DeviceModelScript { Id = "id", ETag = "Etag" };
206+
var deviceModelScript = new DataFile { Id = "id", ETag = "Etag" };
207207

208208
// Act
209209
var ex = Record.Exception(() => this.target.UpsertAsync(deviceModelScript).Result);
@@ -268,7 +268,7 @@ private void SetupAListOfInvalidDeviceModelScriptsInStorage()
268268
var list = new ValueListApiModel();
269269
var value = new ValueApiModel
270270
{
271-
Key = "key",
271+
Key = "key1",
272272
Data = "{ 'invalid': json",
273273
ETag = "etag"
274274
};
@@ -286,14 +286,14 @@ private void TheScriptDoesntExist(string id)
286286
.Throws<ResourceNotFoundException>();
287287
}
288288

289-
private void TheScriptExists(string id, DeviceModelScript deviceModelScript)
289+
private void TheScriptExists(string id, DataFile deviceModelScript)
290290
{
291291
this.storage
292292
.Setup(x => x.GetAsync(STORAGE_COLLECTION, id))
293293
.ReturnsAsync(this.BuildValueApiModel(deviceModelScript));
294294
}
295295

296-
private ValueApiModel BuildValueApiModel(DeviceModelScript deviceModelScript)
296+
private ValueApiModel BuildValueApiModel(DataFile deviceModelScript)
297297
{
298298
return new ValueApiModel
299299
{
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services;
4+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Diagnostics;
5+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Exceptions;
6+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models;
7+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Runtime;
8+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Storage;
9+
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Storage.CosmosDbSql;
10+
using Moq;
11+
using Newtonsoft.Json;
12+
using Services.Test.helpers;
13+
using System;
14+
using Xunit;
15+
16+
namespace Services.Test
17+
{
18+
public class ReplayFileServiceTest
19+
{
20+
private const string REPLAY_FILES = "replayFiles";
21+
22+
private readonly Mock<ILogger> log;
23+
private readonly Mock<IServicesConfig> config;
24+
private readonly Mock<IEngines> enginesFactory;
25+
private readonly Mock<IEngine> replayFilesStorage;
26+
private readonly Mock<ILogger> logger;
27+
private readonly ReplayFileService target;
28+
29+
public ReplayFileServiceTest()
30+
{
31+
this.log = new Mock<ILogger>();
32+
this.config = new Mock<IServicesConfig>();
33+
this.enginesFactory = new Mock<IEngines>();
34+
35+
this.replayFilesStorage = new Mock<IEngine>();
36+
this.replayFilesStorage.Setup(x => x.BuildRecord(It.IsAny<string>(), It.IsAny<string>()))
37+
.Returns((string id, string json) => new DataRecord { Id = id, Data = json });
38+
this.replayFilesStorage.Setup(x => x.BuildRecord(It.IsAny<string>()))
39+
.Returns((string id) => new DataRecord { Id = id });
40+
41+
this.config.SetupGet(x => x.ReplayFilesStorage)
42+
.Returns(new Config { CosmosDbSqlCollection = REPLAY_FILES });
43+
44+
this.enginesFactory
45+
.Setup(x => x.Build(It.Is<Config>(c => c.CosmosDbSqlCollection == REPLAY_FILES)))
46+
.Returns(this.replayFilesStorage.Object);
47+
48+
this.target = new ReplayFileService(
49+
this.config.Object,
50+
this.enginesFactory.Object,
51+
this.replayFilesStorage.Object,
52+
this.log.Object);
53+
}
54+
55+
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
56+
public void ItCreatesReplayFileInStorage()
57+
{
58+
// Arrange
59+
var id = Guid.NewGuid().ToString();
60+
var replayFile = new DataFile { Id = id, Content = "1, 2, 3", ETag = "tag" };
61+
62+
this.replayFilesStorage
63+
.Setup(x => x.CreateAsync(It.IsAny<IDataRecord>()))
64+
.ReturnsAsync(new DataRecord { Id = id, Data = JsonConvert.SerializeObject(replayFile) });
65+
66+
// Act
67+
DataFile result = this.target.InsertAsync(replayFile).Result;
68+
69+
// Assert
70+
Assert.NotNull(result);
71+
Assert.Equal(replayFile.Id, result.Id);
72+
Assert.Equal(replayFile.Content, result.Content);
73+
74+
this.replayFilesStorage.Verify(
75+
x => x.CreateAsync(It.Is<IDataRecord>(n => n.GetId() == id)), Times.Once());
76+
}
77+
78+
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
79+
public void ItThrowsExceptionWhenCreateReplayFileFails()
80+
{
81+
// Arrange
82+
DataFile replayFile = new DataFile();
83+
replayFile.Content = "1, 2, 3, 4, 5";
84+
85+
this.replayFilesStorage
86+
.Setup(x => x.CreateAsync(It.IsAny<IDataRecord>()))
87+
.ThrowsAsync(new SomeException());
88+
89+
// Act & Assert
90+
Assert.ThrowsAsync<ExternalDependencyException>(
91+
async () => await this.target.InsertAsync(replayFile))
92+
.Wait(Constants.TEST_TIMEOUT);
93+
}
94+
95+
96+
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
97+
public void ItThrowsExceptionWhenDeleteReplayFileFailes()
98+
{
99+
// Arrange
100+
this.replayFilesStorage
101+
.Setup(x => x.DeleteAsync(It.IsAny<string>()))
102+
.ThrowsAsync(new SomeException());
103+
104+
// Act & Assert
105+
Assert.ThrowsAsync<ExternalDependencyException>(
106+
async () => await this.target.DeleteAsync("Id"))
107+
.Wait(Constants.TEST_TIMEOUT);
108+
}
109+
110+
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
111+
public void ItFailsToGetReplayFileWhenGetAsyncFails()
112+
{
113+
// Arrange
114+
this.replayFilesStorage
115+
.Setup(x => x.GetAsync(It.IsAny<string>()))
116+
.ThrowsAsync(new SomeException());
117+
118+
// Act & Assert
119+
Assert.ThrowsAsync<ExternalDependencyException>(
120+
async () => await this.target.GetAsync("Id"))
121+
.Wait(Constants.TEST_TIMEOUT);
122+
}
123+
124+
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
125+
public void ItThrowsExceptionForInvalidId()
126+
{
127+
// Act & Assert
128+
Assert.ThrowsAsync<InvalidInputException>(
129+
async () => await this.target.GetAsync(string.Empty))
130+
.Wait(Constants.TEST_TIMEOUT);
131+
}
132+
}
133+
}

Services/DeviceModelScripts.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@ public interface IDeviceModelScripts
1717
/// <summary>
1818
/// Get list of device model scripts.
1919
/// </summary>
20-
Task<IEnumerable<DeviceModelScript>> GetListAsync();
20+
Task<IEnumerable<DataFile>> GetListAsync();
2121

2222
/// <summary>
2323
/// Get a device model script.
2424
/// </summary>
25-
Task<DeviceModelScript> GetAsync(string id);
25+
Task<DataFile> GetAsync(string id);
2626

2727
/// <summary>
2828
/// Create a device model script.
2929
/// </summary>
30-
Task<DeviceModelScript> InsertAsync(DeviceModelScript deviceModelScript);
30+
Task<DataFile> InsertAsync(DataFile deviceModelScript);
3131

3232
/// <summary>
3333
/// Create or replace a device model script.
3434
/// </summary>
35-
Task<DeviceModelScript> UpsertAsync(DeviceModelScript deviceModelScript);
35+
Task<DataFile> UpsertAsync(DataFile deviceModelScript);
3636

3737
/// <summary>
3838
/// Delete a device model script.
@@ -74,7 +74,7 @@ public async Task DeleteAsync(string id)
7474
/// <summary>
7575
/// Get a device model script.
7676
/// </summary>
77-
public async Task<DeviceModelScript> GetAsync(string id)
77+
public async Task<DataFile> GetAsync(string id)
7878
{
7979
if (string.IsNullOrEmpty(id))
8080
{
@@ -99,7 +99,7 @@ public async Task<DeviceModelScript> GetAsync(string id)
9999

100100
try
101101
{
102-
var deviceModelScript = JsonConvert.DeserializeObject<DeviceModelScript>(item.Data);
102+
var deviceModelScript = JsonConvert.DeserializeObject<DataFile>(item.Data);
103103
deviceModelScript.ETag = item.ETag;
104104
return deviceModelScript;
105105
}
@@ -113,7 +113,7 @@ public async Task<DeviceModelScript> GetAsync(string id)
113113
/// <summary>
114114
/// Get list of device model scripts.
115115
/// </summary>
116-
public async Task<IEnumerable<DeviceModelScript>> GetListAsync()
116+
public async Task<IEnumerable<DataFile>> GetListAsync()
117117
{
118118
ValueListApiModel data;
119119

@@ -129,13 +129,13 @@ public async Task<IEnumerable<DeviceModelScript>> GetListAsync()
129129

130130
try
131131
{
132-
var results = new List<DeviceModelScript>();
132+
var results = new List<DataFile>();
133133
foreach (var item in data.Items)
134134
{
135-
var deviceModelScript = JsonConvert.DeserializeObject<DeviceModelScript>(item.Data);
135+
var deviceModelScript = JsonConvert.DeserializeObject<DataFile>(item.Data);
136136
deviceModelScript.ETag = item.ETag;
137137
deviceModelScript.Type = ScriptInterpreter.JAVASCRIPT_SCRIPT;
138-
deviceModelScript.Path = DeviceModelScript.DeviceModelScriptPath.Storage;
138+
deviceModelScript.Path = DataFile.FilePath.Storage;
139139
results.Add(deviceModelScript);
140140
}
141141

@@ -151,7 +151,7 @@ public async Task<IEnumerable<DeviceModelScript>> GetListAsync()
151151
/// <summary>
152152
/// Create a device model script.
153153
/// </summary>
154-
public async Task<DeviceModelScript> InsertAsync(DeviceModelScript deviceModelScript)
154+
public async Task<DataFile> InsertAsync(DataFile deviceModelScript)
155155
{
156156
deviceModelScript.Created = DateTimeOffset.UtcNow;
157157
deviceModelScript.Modified = deviceModelScript.Created;
@@ -188,7 +188,7 @@ public async Task<DeviceModelScript> InsertAsync(DeviceModelScript deviceModelSc
188188
/// <summary>
189189
/// Create or replace a device model script.
190190
/// </summary>
191-
public async Task<DeviceModelScript> UpsertAsync(DeviceModelScript deviceModelScript)
191+
public async Task<DataFile> UpsertAsync(DataFile deviceModelScript)
192192
{
193193
var id = deviceModelScript.Id;
194194
var eTag = deviceModelScript.ETag;
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,35 @@
22

33
using System;
44
using System.Runtime.Serialization;
5-
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Simulation;
65
using Newtonsoft.Json;
76
using Newtonsoft.Json.Converters;
87

98
namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models
109
{
11-
public class DeviceModelScript
10+
public class DataFile
1211
{
1312
[JsonIgnore]
1413
public string ETag { get; set; }
1514
public string Id { get; set; }
1615
public string Name { get; set; }
1716
public string Type { get; set; }
1817
public string Content { get; set; }
19-
public DeviceModelScriptPath Path { get; set; }
18+
public FilePath Path { get; set; }
2019
public DateTimeOffset Created { get; set; }
2120
public DateTimeOffset Modified { get; set; }
2221

23-
public DeviceModelScript()
22+
public DataFile()
2423
{
2524
this.ETag = string.Empty;
2625
this.Id = string.Empty;
27-
this.Type = ScriptInterpreter.JAVASCRIPT_SCRIPT;
26+
this.Type = string.Empty;
2827
this.Content = string.Empty;
29-
this.Path = DeviceModelScriptPath.Storage;
28+
this.Path = FilePath.Storage;
3029
this.Name = string.Empty;
3130
}
3231

3332
[JsonConverter(typeof(StringEnumConverter))]
34-
public enum DeviceModelScriptPath
33+
public enum FilePath
3534
{
3635
[EnumMember(Value = "Undefined")]
3736
Undefined = 0,

0 commit comments

Comments
 (0)