Multi-thread testing for web-service
|
|
Среда, 17 Июня 2009 г. 16:49
+ в цитатник
В работе постоянно приходится тестировать с помощью NUnit различные web-службы. Но я делаю не банальный одиночный вызов или серию последовательных вызовов, а создаю серию потоков вплоть до максимально разрешенного на текущей машине, каждый из которых по команде начинает делать запрос в web-службу. В случае, если на сервере IIS разрешено более одного процесса, для обслуживания ApplicationPool, то это может выявить неожиданные блокировки ресурсов, которые нужно уметь отлавливать.
Эмитация такого многопоточного обращения к одному сервису сделана как показано ниже:
Copy Source | Copy HTML- public class MainTests
- {
- //количество ошибок по результату выполнения
- public static int iErrors = 0;
-
- private static ManualResetEvent[] resetEvents;
-
- /// <summary>
- /// Запускаем одновременно NumThreads потоков
- /// </summary>
- /// <param name="NumThreads">Число потоков</param>
- public void QueueFewRequests(int NumThreads, AskTo whereto)
- {
- ManualResetEvent oStart = new ManualResetEvent(false);
- Debug.WriteLine("-------------QueueFewRequests = " + NumThreads.ToString() + " " + whereto.ToString() + "----------");
- resetEvents = new ManualResetEvent[NumThreads];
- for (int i = 0; i < NumThreads; i++)
- {
- resetEvents[i] = new ManualResetEvent(false);
- if (!ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(MakeSingleSearch),
- new ThreadParam()
- {
- number = i,
- oEvent = resetEvents[i],
- oWhenStart = oStart,
- askto = whereto
- }))
- {
- MainTests.iErrors++;
- System.Diagnostics.Debug.WriteLine("Cant Queue request!");
- break;
- }
- }
- //let it go!
- oStart.Set();
- if (NumThreads < 64)
- {
- ManualResetEvent.WaitAll(resetEvents);
- }
- else
- {
- //если элементов меньше 64, то можно использовать ManualResetEvent.WaitAll(resetEvents);
- Array.ForEach(resetEvents, new Action<ManualResetEvent>(WaitFinish));
- }
- Assert.AreEqual(0, MainTests.iErrors);
- }
-
- private void WaitFinish(ManualResetEvent oEvent)
- {
- oEvent.WaitOne();
- }
-
- /// <summary>
- /// Передаем один запрос в службу
- /// </summary>
- /// <param name="stateInfo"></param>
- static void MakeSingleSearch(Object stateInfo)
- {
- Random rand = new Random(DateTime.Now.Millisecond + ((ThreadParam)stateInfo).number);
-
- if (stateInfo != null)
- {
- //дождемся команды начала работы
- ((ThreadParam)stateInfo).oWhenStart.WaitOne();
- int iRand = (int)Math.Floor(rand.NextDouble() * 1000)+100;
- try
- {
- DSTLCode dCode;
- PerformanceTimer timer = new PerformanceTimer();
- timer.StartTimer();
- //определимся с запросом
- AskTo whatwedo = ((ThreadParam)stateInfo).askto;
- switch (whatwedo)
- {
- ...
- }
- Debug.WriteLine("Thread " +
- ((ThreadParam)stateInfo).number + " - " + dCode.ToString() + " " +
- " for '" + iRand.ToString() + "' successed in " + timer.StopTimer().ToString() + " sec");
-
-
- }
- catch(Exception e1)
- {
- iErrors++;
- Debug.WriteLine("Thread " +
- ((ThreadParam)stateInfo).number + " - Ошибка обработки: " + e1.Message);
- }
- finally
- {
- //передаем информацию о том, что мы завершили работу
- ((ThreadParam)stateInfo).oEvent.Set();
- }
- }
- }
- }
Соответственно, для тестирования нужно использовать следующие строки:
Copy Source | Copy HTML- /// <summary>
- /// Проверим, доступны ли сервисы и работают ли они как положено
- /// </summary>
- [TestFixture]
- public class WebTests : MainTests
- {
-
- [Test]
- public void SingleSearch()
- {
- QueueFewRequests(1, AskTo.SM_QUEUE);
- }
-
- [Test]
- public void MultiSearch_Max()
- {
- int workers;
- int currs;
- ThreadPool.GetMaxThreads(out workers,out currs);
- QueueFewRequests(workers, AskTo.SM_QUEUE);
- }
-
- }
Метки:
code
s-c.me
-
Запись понравилась
-
0
Процитировали
-
0
Сохранили
-