6
6
using System . Collections . Generic ;
7
7
using System . IO ;
8
8
using System . Linq ;
9
+ using System . Net ;
9
10
using System . Security . Cryptography ;
10
11
using System . Threading ;
11
12
using System . Threading . Tasks ;
13
+ using Azure ;
12
14
using Microsoft . Azure . WebJobs . Extensions . Http ;
13
15
using Microsoft . Azure . WebJobs . Logging ;
14
16
using Microsoft . Azure . WebJobs . Script . Diagnostics ;
@@ -500,6 +502,27 @@ public async Task AddOrUpdateFunctionSecrets_WithFunctionNameAndNoSecret_Generat
500
502
}
501
503
502
504
[ Fact ]
505
+ public async Task AddOrUpdateFunctionSecret_WhenStorageWriteError_ThrowsException ( )
506
+ {
507
+ using ( var directory = new TempDirectory ( ) )
508
+ {
509
+ CreateTestSecrets ( directory . Path ) ;
510
+
511
+ KeyOperationResult result ;
512
+
513
+ ISecretsRepository repository = new TestSecretsRepository ( false , true ) ;
514
+ using var secretManager = CreateSecretManager ( directory . Path , simulateWriteConversion : false , secretsRepository : repository ) ;
515
+ try
516
+ {
517
+ result = await secretManager . AddOrUpdateFunctionSecretAsync ( "function-key-3" , "9876" , "TestFunction" , ScriptSecretsType . Function ) ;
518
+ }
519
+ catch ( RequestFailedException ex )
520
+ {
521
+ Assert . Equal ( ex . Status , ( int ) HttpStatusCode . InternalServerError ) ;
522
+ }
523
+ }
524
+ }
525
+
503
526
public async Task AddOrUpdateFunctionSecret_ClearsCache_WhenFunctionSecretAdded ( )
504
527
{
505
528
using ( var directory = new TempDirectory ( ) )
@@ -1136,7 +1159,7 @@ private Mock<IKeyValueConverterFactory> GetConverterFactoryMock(bool simulateWri
1136
1159
return mockValueConverterFactory ;
1137
1160
}
1138
1161
1139
- private SecretManager CreateSecretManager ( string secretsPath , ILogger logger = null , IMetricsLogger metricsLogger = null , IKeyValueConverterFactory keyConverterFactory = null , bool createHostSecretsIfMissing = false , bool simulateWriteConversion = true , bool setStaleValue = true )
1162
+ private SecretManager CreateSecretManager ( string secretsPath , ILogger logger = null , IMetricsLogger metricsLogger = null , IKeyValueConverterFactory keyConverterFactory = null , bool createHostSecretsIfMissing = false , bool simulateWriteConversion = true , bool setStaleValue = true , ISecretsRepository secretsRepository = null )
1140
1163
{
1141
1164
logger = logger ?? _logger ;
1142
1165
metricsLogger = metricsLogger ?? new TestMetricsLogger ( ) ;
@@ -1147,7 +1170,7 @@ private SecretManager CreateSecretManager(string secretsPath, ILogger logger = n
1147
1170
keyConverterFactory = mockValueConverterFactory . Object ;
1148
1171
}
1149
1172
1150
- ISecretsRepository repository = new FileSystemSecretsRepository ( secretsPath , logger , _testEnvironment ) ;
1173
+ ISecretsRepository repository = secretsRepository ?? new FileSystemSecretsRepository ( secretsPath , logger , _testEnvironment ) ;
1151
1174
var secretManager = new SecretManager ( repository , keyConverterFactory , logger , metricsLogger , _hostNameProvider , _startupContextProvider ) ;
1152
1175
1153
1176
if ( createHostSecretsIfMissing )
@@ -1216,12 +1239,19 @@ private class TestSecretsRepository : ISecretsRepository
1216
1239
private int _writeCount = 0 ;
1217
1240
private Random _rand = new Random ( ) ;
1218
1241
private bool _enforceSerialWrites = false ;
1242
+ private bool _forceWriteErrors = false ;
1219
1243
1220
1244
public TestSecretsRepository ( bool enforceSerialWrites )
1221
1245
{
1222
1246
_enforceSerialWrites = enforceSerialWrites ;
1223
1247
}
1224
1248
1249
+ public TestSecretsRepository ( bool enforceSerialWrites , bool forceWriteErrors )
1250
+ : this ( enforceSerialWrites )
1251
+ {
1252
+ _forceWriteErrors = forceWriteErrors ;
1253
+ }
1254
+
1225
1255
public event EventHandler < SecretsChangedEventArgs > SecretsChanged ;
1226
1256
1227
1257
public ConcurrentDictionary < string , ScriptSecrets > FunctionSecrets { get ; } = new ConcurrentDictionary < string , ScriptSecrets > ( StringComparer . OrdinalIgnoreCase ) ;
@@ -1260,6 +1290,11 @@ public Task<ScriptSecrets> ReadAsync(ScriptSecretsType type, string functionName
1260
1290
1261
1291
public async Task WriteAsync ( ScriptSecretsType type , string functionName , ScriptSecrets secrets )
1262
1292
{
1293
+ if ( _forceWriteErrors )
1294
+ {
1295
+ throw new RequestFailedException ( ( int ) HttpStatusCode . InternalServerError , "Error" ) ;
1296
+ }
1297
+
1263
1298
if ( _enforceSerialWrites && _writeCount > 1 )
1264
1299
{
1265
1300
throw new Exception ( "Concurrent writes detected!" ) ;
0 commit comments