Как исправить многопоточный модульный тест, который вешает нашу сборку TeamCity? - PullRequest
2 голосов
/ 04 ноября 2011

Мы столкнулись с проблемой, состоящей в том, что один из наших модульных тестов несколько раз в день проваливался во время КИ в TeamCity.Мы используем MSTest и RhinoMocks.Почти невозможно воспроизвести его на компьютере разработчика (возможно, из-за 1 процессора на компьютере разработчика, я не знаю).

[TestMethod]
[TestCategory("UnitTest")]
[ExpectedException(typeof(AggregateException))]
public void TestRiskDataStagingThrowAggregateException()
{
    DataStagingThrowException(typeof(DeskRiskDataPump));
}

protected void DataStagingThrowException(Type dataPumpType)
{
    // set expectations
    foreach (IUploader uploader in StubUploaders)
    {
        uploader.Expect(x => x.Upload(StubDataProvider)).Repeat.Once().Throw(new Exception("BANG!!!"));
    }

    Repository.ReplayAll();

    IDataPump datapump = new DataPumpFactory().GetDataPump(dataPumpType, StubDataProvider, StubUploaders, StubDistributor);

    // Execute
    // the test can hang here!!!
    datapump.Execute();

    Repository.VerifyAll();
}

StubDataProvider = Repository.Stub<IEnumerable<TRecord>>();
StubUploaders = new List<IUploader>();
StubDistributor = Repository.Stub<IDataDistributor>();

StubUploaders.Add(Repository.Stub<IUploader>());
StubUploaders.Add(Repository.Stub<IUploader>());
StubUploaders.Add(Repository.Stub<IUploader>());

Класс, который реализует IDataPump, немного завершен, и я 'я боюсь опубликовать это здесь :) В общем, он реализует шаблон Producer-Consumer и запускает несколько процессов в разных потоках, что-то вроде этого

Task[] tasks = new Task[4];

// Start adding to the queue
tasks[0] = Task.Factory.StartNew(Produce);

// Start draining the queue in parallel
tasks[1] = Task.Factory.StartNew(ConsumeCreditRisk);
tasks[2] = Task.Factory.StartNew(ConsumeTrancheRisk);
tasks[3] = Task.Factory.StartNew(ConsumeRatesRisk);

// Wait to complete
try
{
    Task.WaitAll(tasks);
}
catch (AggregateException e)
{
    .....
    throw;
}

private void ConsumeCreditRisk()
{
    _creditRiskUploader.Upload(_creditRiskBuffer.GetConsumingEnumerable());
}

В нашем случае загрузчики - это заглушки, которые предполагают выдать исключение,и это должно быть поймано как совокупное исключение.Но по логам иногда зависает на заглушке метод Upload.

Есть ли у вас какие-либо предположения, что может вызвать проблему?

1 Ответ

1 голос
/ 24 ноября 2011

На самом деле вам нужно предоставить тайм-аут для любых многопоточных тестов, чтобы предотвратить блокировку сборки. Это обходной путь.

...