1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//       Some ideas of improvements:
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//       Break out common init and maybe terminate to separate function(s).
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//       How much trace should we have enabled?
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//       API error counter, to print info and return -1 if any error.
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include <assert.h>
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h>
18471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include <stdlib.h>
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h>
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <time.h>
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(_WIN32)
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <conio.h>
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org#include "webrtc/voice_engine/test/auto_test/voe_stress_test.h"
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
27aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
28143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org#include "webrtc/system_wrappers/interface/sleep.h"
29143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
30aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org#include "webrtc/test/channel_transport/include/channel_transport.h"
31aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
328510750bf2847dcdca26d914974c6d51d1e311a7pbos@webrtc.org#include "webrtc/voice_engine/test/auto_test/voe_test_defines.h"
33143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org#include "webrtc/voice_engine/voice_engine_defines.h"  // defines build macros
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace webrtc;
36aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.orgusing namespace test;
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace voetest {
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define VALIDATE_STRESS(expr)                                   \
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (expr)                                                   \
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {                                                           \
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Error at line: %i, %s \n", __LINE__, #expr);    \
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Error code: %i \n", base->LastError());  \
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef _WIN32
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Pause if supported
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define PAUSE_OR_SLEEP(x) PAUSE;
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Sleep a bit instead if pause not supported
52143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org#define PAUSE_OR_SLEEP(x) SleepMs(x);
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEStressTest::DoTest() {
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int test(-1);
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  while (test != 0) {
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    test = MenuSelection();
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    switch (test) {
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case 0:
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Quit stress test
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case 1:
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // All tests
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        StartStopTest();
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        CreateDeleteChannelsTest();
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        MultipleThreadsTest();
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case 2:
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        StartStopTest();
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case 3:
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        CreateDeleteChannelsTest();
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case 4:
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        MultipleThreadsTest();
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      default:
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Should not be possible
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Invalid selection! (Test code error)\n");
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        assert(false);
823b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org    }  // switch
833b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org  }  // while
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEStressTest::MenuSelection() {
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Select stress test\n\n");
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf(" (0)  Quit\n");
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf(" (1)  All\n");
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("- - - - - - - - - - - - - - - - - - - - - - - - \n");
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf(" (2)  Start/stop\n");
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf(" (3)  Create/delete channels\n");
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf(" (4)  Multiple threads\n");
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int maxMenuSelection = 4;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int selection(-1);
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  while ((selection < 0) || (selection > maxMenuSelection)) {
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf("\n: ");
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int retval = scanf("%d", &selection);
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((retval != 1) || (selection < 0) || (selection > maxMenuSelection)) {
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      printf("Invalid selection!\n");
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return selection;
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEStressTest::StartStopTest() {
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Running start/stop test\n");
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("\nNOTE: this thest will fail after a while if Core audio is used\n");
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("because MS returns AUDCLNT_E_CPUUSAGE_EXCEEDED (VoE Error 10013).\n");
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Get sub-API pointers
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VoEBase* base = _mgr.BasePtr();
122aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  VoENetwork* voe_network = _mgr.NetworkPtr();
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set trace
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetTraceFileName(
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         GetFilename("VoEStressTest_StartStop_trace.txt")));
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetDebugTraceFileName(
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         GetFilename("VoEStressTest_StartStop_trace_debug.txt")));
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetTraceFilter(kTraceStateInfo |
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         kTraceWarning | kTraceError |
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         kTraceCritical | kTraceApiCall |
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         kTraceMemory | kTraceInfo));
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->Init());
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->CreateChannel());
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///////////// Start test /////////////
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int numberOfLoops(2000);
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int loopSleep(200);
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int i(0);
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int markInterval(20);
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Running %d loops with %d ms sleep. Mark every %d loop. \n",
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         numberOfLoops, loopSleep, markInterval);
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Test will take approximately %d minutes. \n",
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         numberOfLoops * loopSleep / 1000 / 60 + 1);
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
148aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
149aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org      new VoiceChannelTransport(voe_network, 0));
150aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = 0; i < numberOfLoops; ++i) {
152aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org    voice_channel_transport->SetSendDestination("127.0.0.1", 4800);
153aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org    voice_channel_transport->SetLocalReceiver(4800);
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(base->StartReceive(0));
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(base->StartPlayout(0));
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(base->StartSend(0));
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!(i % markInterval))
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      MARK();
159143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org    SleepMs(loopSleep);
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(base->StopSend(0));
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(base->StopPlayout(0));
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(base->StopReceive(0));
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ANL();
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
166aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  VALIDATE_STRESS(voice_channel_transport->SetSendDestination("127.0.0.1",
167aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org                                                              4800));
168aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  VALIDATE_STRESS(voice_channel_transport->SetLocalReceiver(4800));
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->StartReceive(0));
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->StartPlayout(0));
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->StartSend(0));
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Verify that audio is good. \n");
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  PAUSE_OR_SLEEP(20000);
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->StopSend(0));
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->StopPlayout(0));
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->StopReceive(0));
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///////////// End test /////////////
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Terminate
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->DeleteChannel(0));
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->Terminate());
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Test finished \n");
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEStressTest::CreateDeleteChannelsTest() {
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Running create/delete channels test\n");
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Get sub-API pointers
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VoEBase* base = _mgr.BasePtr();
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set trace
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetTraceFileName(
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //          GetFilename("VoEStressTest_CreateChannels_trace.txt")));
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetDebugTraceFileName(
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //          GetFilename("VoEStressTest_CreateChannels_trace_debug.txt")));
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetTraceFilter(kTraceStateInfo |
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         kTraceWarning | kTraceError |
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         kTraceCritical | kTraceApiCall |
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //         kTraceMemory | kTraceInfo));
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->Init());
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///////////// Start test /////////////
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int numberOfLoops(10000);
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int loopSleep(10);
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int i(0);
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int markInterval(200);
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Running %d loops with %d ms sleep. Mark every %d loop. \n",
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         numberOfLoops, loopSleep, markInterval);
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Test will take approximately %d minutes. \n",
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         numberOfLoops * loopSleep / 1000 / 60 + 1);
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Some possible extensions include:
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Different sleep times (fixed or random) or zero.
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Start call on all or some channels.
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Two parts: first have a slight overweight to creating channels,
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       then to deleting. (To ensure we hit max channels and go to zero.)
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Make sure audio is OK after test has finished.
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set up, start with maxChannels/2 channels
229b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  const int maxChannels = 100;
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(maxChannels < 1); // Should always have at least one channel
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool* channelState = new bool[maxChannels];
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memset(channelState, 0, maxChannels * sizeof(bool));
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int channel(0);
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int noOfActiveChannels(0);
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = 0; i < (maxChannels / 2); ++i) {
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    channel = base->CreateChannel();
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VALIDATE_STRESS(channel < 0);
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (channel >= 0) {
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      channelState[channel] = true;
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ++noOfActiveChannels;
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  srand((unsigned int) time(NULL));
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool action(false);
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  double rnd(0.0);
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int res(0);
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Create/delete channels with slight
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = 0; i < numberOfLoops; ++i) {
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Randomize action (create or delete channel)
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    action = rand() <= (RAND_MAX / 2);
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (action) {
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (noOfActiveChannels < maxChannels) {
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Create new channel
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        channel = base->CreateChannel();
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        VALIDATE_STRESS(channel < 0);
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (channel >= 0) {
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          channelState[channel] = true;
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          ++noOfActiveChannels;
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    } else {
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (noOfActiveChannels > 0) {
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Delete random channel that's created [0, maxChannels - 1]
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        do {
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          rnd = static_cast<double> (rand());
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          channel = static_cast<int> (rnd /
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      (static_cast<double> (RAND_MAX) + 1.0f) *
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      maxChannels);
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        } while (!channelState[channel]); // Must find a created channel
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        res = base->DeleteChannel(channel);
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        VALIDATE_STRESS(0 != res);
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (0 == res) {
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          channelState[channel] = false;
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          --noOfActiveChannels;
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!(i % markInterval))
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      MARK();
283143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org    SleepMs(loopSleep);
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ANL();
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete[] channelState;
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///////////// End test /////////////
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Terminate
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->Terminate()); // Deletes all channels
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Test finished \n");
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEStressTest::MultipleThreadsTest() {
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Running multiple threads test\n");
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("------------------------------------------------\n");
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Get sub-API pointers
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VoEBase* base = _mgr.BasePtr();
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set trace
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetTraceFileName(
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //        GetFilename("VoEStressTest_MultipleThreads_trace.txt")));
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetDebugTraceFileName(
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //        GetFilename("VoEStressTest_MultipleThreads_trace_debug.txt")));
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //     VALIDATE_STRESS(base->SetTraceFilter(kTraceStateInfo |
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //        kTraceWarning | kTraceError |
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //        kTraceCritical | kTraceApiCall |
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //        kTraceMemory | kTraceInfo));
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Init
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->Init());
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->CreateChannel());
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///////////// Start test /////////////
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int numberOfLoops(10000);
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int loopSleep(0);
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int i(0);
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int markInterval(1000);
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Running %d loops with %d ms sleep. Mark every %d loop. \n",
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         numberOfLoops, loopSleep, markInterval);
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Test will take approximately %d minutes. \n",
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         numberOfLoops * loopSleep / 1000 / 60 + 1);
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  srand((unsigned int) time(NULL));
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int rnd(0);
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Start extra thread
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const char* threadName = "StressTest Extra API Thread";
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _ptrExtraApiThread = ThreadWrapper::CreateThread(RunExtraApi, this,
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                   kNormalPriority, threadName);
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  unsigned int id(0);
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(!_ptrExtraApiThread->Start(id));
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Some possible extensions include:
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Add more API calls to randomize
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       More threads
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Different sleep times (fixed or random).
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //       Make sure audio is OK after test has finished.
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Call random API functions here and in extra thread, ignore any error
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = 0; i < numberOfLoops; ++i) {
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This part should be equal to the marked part in the extra thread
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // --- BEGIN ---
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rnd = rand();
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (rnd < (RAND_MAX / 2)) {
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // Start playout
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      base->StartPlayout(0);
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    } else {
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // Stop playout
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      base->StopPlayout(0);
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // --- END ---
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!(i % markInterval))
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      MARK();
366143ce524d89eb802ca5dc1676352a9e2e3e12783andrew@webrtc.org    SleepMs(loopSleep);
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ANL();
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Stop extra thread
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(!_ptrExtraApiThread->Stop());
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete _ptrExtraApiThread;
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///////////// End test /////////////
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Terminate
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VALIDATE_STRESS(base->Terminate()); // Deletes all channels
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Test finished \n");
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Thread functions
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VoEStressTest::RunExtraApi(void* ptr) {
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return static_cast<VoEStressTest*> (ptr)->ProcessExtraApi();
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VoEStressTest::ProcessExtraApi() {
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Prepare
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VoEBase* base = _mgr.BasePtr();
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int rnd(0);
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Call random API function, ignore any error
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // This part should be equal to the marked part in the main thread
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // --- BEGIN ---
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  rnd = rand();
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (rnd < (RAND_MAX / 2)) {
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Start playout
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    base->StartPlayout(0);
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else {
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Stop playout
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    base->StopPlayout(0);
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // --- END ---
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
4123b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace voetest
413