Я пытаюсь покрыть метод RequestAsyn c модульными тестами.
private readonly SemaphoreSlim lockRequest = new SemaphoreSlim(1, 1);
public async Task<object> RequestAsync(string key, CancellationToken cancellationToken)
{
Logger.Info("EnterRequestDataAsync for address" + key);
await this.lockRequest.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
return GetValueFromDataBaseAsync(key);
}
finally
{
this.lockRequest.Release();
if (this.lockRequest.CurrentCount == 1)
{
Logger.Info("Inside if statement after address " + key);
await this.memory.StartPollingAsync(this);
}
Logger.Info("ExitRequestDataAsync for address: " + key);
}
}
Если точнее, я бы проверил это поведение блокировки в блоке finally. Чтобы убедиться, что StartPollingAsyn c начинает выполняться только после завершения всех других запросов.
[Test]
public async Task TestRequestAsyncPendingRequests()
{
// Arrange
this.memoryMock = new Mock<IMemory>();
int someValue1 = 1;
int someValue2 = 2;
await this.store.SetAsync(nameof(someValue1), someValue1, CancellationToken.None);
await this.store.SetAsync(nameof(someValue2), someValue2, CancellationToken.None);
// Act
Task.Run(async () => this.store.RequestAsync(nameof(someValue1), CancellationToken.None));
Task.Run(async () => this.store.RequestAsync(nameof(someValue2), CancellationToken.None));
// Assert
this.memoryMock.Verify(memory => memory.StartPollingAsync(this.store, It.IsAny<string>()), Times.Once());
}
Но когда я запускаю этот код, у меня другое поведение. В случае, когда я запускаю этот тест локально на моей машине, я получаю этот вывод:
2020-03-26 11:21:54.5821|INFO|EnterRequestAsync for address: someValue1
2020-03-26 11:21:54.5821|INFO|EnterRequestAsync for address: someValue2
2020-03-26 11:21:54.5919|INFO|ExitRequestAsync for address: someValue1
2020-03-26 11:21:54.5919|INFO|Inside if statement after address someValue2
2020-03-26 11:21:54.5919|INFO|ExitRequestAsync for address: someValue2
или (редко)
2020-03-26 11:55:52.0509|INFO|EnterRequestAsync for address: someValue2
2020-03-26 11:55:52.1191|INFO|EnterRequestAsync for address: someValue1
2020-03-26 11:55:52.1191|INFO|Inside if statement after address someValue1
2020-03-26 11:55:52.1520|INFO|ExitRequestAsync for address: someValue1
2020-03-26 11:55:52.1191|INFO|Inside if statement after address someValue2
2020-03-26 11:55:52.1520|INFO|ExitRequestAsync for address: someValue2
Но когда я пу sh этот тест в Дженкинс, Я получил другой вывод:
2020-03-25 13:12:43.8707|INFO|EnterRequestAsync for address: someValue1
2020-03-25 13:12:43.8707|INFO|Inside if statement after address someValue1
2020-03-25 13:12:43.8707|INFO|EnterRequestAsync for address: someValue2
2020-03-25 13:12:43.8707|INFO|Inside if statement after address someValue2
2020-03-25 13:12:43.8707|INFO|ExitRequestAsync for address: someValue1
2020-03-25 13:12:43.8707|INFO|ExitRequestAsync for address: someValue2
Кажется, что он работает синхронно.
Почему это происходит? Есть ли случай, чтобы исправить это, чтобы получить такое же поведение в любом месте?