1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
12
13#include <assert.h>
14#include <stdio.h>
15#include <string.h>
16
17#include "webrtc/engine_configurations.h"
18#include "webrtc/system_wrappers/include/event_wrapper.h"
19#include "webrtc/voice_engine/include/voe_neteq_stats.h"
20#include "webrtc/voice_engine/test/auto_test/automated_mode.h"
21#include "webrtc/voice_engine/test/auto_test/voe_cpu_test.h"
22#include "webrtc/voice_engine/test/auto_test/voe_stress_test.h"
23#include "webrtc/voice_engine/test/auto_test/voe_test_defines.h"
24#include "webrtc/voice_engine/voice_engine_defines.h"
25
26DEFINE_bool(include_timing_dependent_tests, true,
27            "If true, we will include tests / parts of tests that are known "
28            "to break in slow execution environments (such as valgrind).");
29DEFINE_bool(automated, false,
30            "If true, we'll run the automated tests we have in noninteractive "
31            "mode.");
32
33using namespace webrtc;
34
35namespace voetest {
36
37int dummy = 0;  // Dummy used in different functions to avoid warnings
38
39void SubAPIManager::DisplayStatus() const {
40  TEST_LOG("Supported sub APIs:\n\n");
41  if (_base)
42    TEST_LOG("  Base\n");
43  if (_codec)
44    TEST_LOG("  Codec\n");
45  if (_dtmf)
46    TEST_LOG("  Dtmf\n");
47  if (_externalMedia)
48    TEST_LOG("  ExternalMedia\n");
49  if (_file)
50    TEST_LOG("  File\n");
51  if (_hardware)
52    TEST_LOG("  Hardware\n");
53  if (_netEqStats)
54    TEST_LOG("  NetEqStats\n");
55  if (_network)
56    TEST_LOG("  Network\n");
57  if (_rtp_rtcp)
58    TEST_LOG("  RTP_RTCP\n");
59  if (_videoSync)
60    TEST_LOG("  VideoSync\n");
61  if (_volumeControl)
62    TEST_LOG("  VolumeControl\n");
63  if (_apm)
64    TEST_LOG("  AudioProcessing\n");
65  ANL();
66  TEST_LOG("Excluded sub APIs:\n\n");
67  if (!_base)
68    TEST_LOG("  Base\n");
69  if (!_codec)
70    TEST_LOG("  Codec\n");
71  if (!_dtmf)
72    TEST_LOG("  Dtmf\n");
73  if (!_externalMedia)
74    TEST_LOG("  ExternamMedia\n");
75  if (!_file)
76    TEST_LOG("  File\n");
77  if (!_hardware)
78    TEST_LOG("  Hardware\n");
79  if (!_netEqStats)
80    TEST_LOG("  NetEqStats\n");
81  if (!_network)
82    TEST_LOG("  Network\n");
83  if (!_rtp_rtcp)
84    TEST_LOG("  RTP_RTCP\n");
85  if (!_videoSync)
86    TEST_LOG("  VideoSync\n");
87  if (!_volumeControl)
88    TEST_LOG("  VolumeControl\n");
89  if (!_apm)
90    TEST_LOG("  AudioProcessing\n");
91  ANL();
92}
93
94VoETestManager::VoETestManager()
95    : initialized_(false),
96      voice_engine_(NULL),
97      voe_base_(0),
98      voe_codec_(0),
99      voe_dtmf_(0),
100      voe_xmedia_(0),
101      voe_file_(0),
102      voe_hardware_(0),
103      voe_network_(0),
104#ifdef WEBRTC_VOICE_ENGINE_NETEQ_STATS_API
105      voe_neteq_stats_(NULL),
106#endif
107      voe_rtp_rtcp_(0),
108      voe_vsync_(0),
109      voe_volume_control_(0),
110      voe_apm_(0) {
111}
112
113VoETestManager::~VoETestManager() {
114}
115
116bool VoETestManager::Init() {
117  if (initialized_)
118    return true;
119
120  voice_engine_ = VoiceEngine::Create();
121  if (!voice_engine_) {
122    TEST_LOG("Failed to create VoiceEngine\n");
123    return false;
124  }
125
126  return true;
127}
128
129void VoETestManager::GetInterfaces() {
130  if (voice_engine_) {
131    voe_base_ = VoEBase::GetInterface(voice_engine_);
132    voe_codec_ = VoECodec::GetInterface(voice_engine_);
133    voe_volume_control_ = VoEVolumeControl::GetInterface(voice_engine_);
134    voe_dtmf_ = VoEDtmf::GetInterface(voice_engine_);
135    voe_rtp_rtcp_ = VoERTP_RTCP::GetInterface(voice_engine_);
136    voe_apm_ = VoEAudioProcessing::GetInterface(voice_engine_);
137    voe_network_ = VoENetwork::GetInterface(voice_engine_);
138    voe_file_ = VoEFile::GetInterface(voice_engine_);
139#ifdef _TEST_VIDEO_SYNC_
140    voe_vsync_ = VoEVideoSync::GetInterface(voice_engine_);
141#endif
142    voe_hardware_ = VoEHardware::GetInterface(voice_engine_);
143    // Set the audio layer to use in all tests
144    if (voe_hardware_) {
145      int res = voe_hardware_->SetAudioDeviceLayer(TESTED_AUDIO_LAYER);
146      if (res < 0) {
147        printf("\nERROR: failed to set audio layer to use in "
148          "testing\n");
149      } else {
150        printf("\nAudio layer %d will be used in testing\n",
151               TESTED_AUDIO_LAYER);
152      }
153    }
154#ifdef _TEST_XMEDIA_
155    voe_xmedia_ = VoEExternalMedia::GetInterface(voice_engine_);
156#endif
157#ifdef WEBRTC_VOICE_ENGINE_NETEQ_STATS_API
158    voe_neteq_stats_ = VoENetEqStats::GetInterface(voice_engine_);
159#endif
160  }
161}
162
163int VoETestManager::ReleaseInterfaces() {
164  bool releaseOK(true);
165
166  if (voe_base_) {
167    voe_base_->Release();
168    voe_base_ = NULL;
169  }
170  if (voe_codec_) {
171    voe_codec_->Release();
172    voe_codec_ = NULL;
173  }
174  if (voe_volume_control_) {
175    voe_volume_control_->Release();
176    voe_volume_control_ = NULL;
177  }
178  if (voe_dtmf_) {
179    voe_dtmf_->Release();
180    voe_dtmf_ = NULL;
181  }
182  if (voe_rtp_rtcp_) {
183    voe_rtp_rtcp_->Release();
184    voe_rtp_rtcp_ = NULL;
185  }
186  if (voe_apm_) {
187    voe_apm_->Release();
188    voe_apm_ = NULL;
189  }
190  if (voe_network_) {
191    voe_network_->Release();
192    voe_network_ = NULL;
193  }
194  if (voe_file_) {
195    voe_file_->Release();
196    voe_file_ = NULL;
197  }
198#ifdef _TEST_VIDEO_SYNC_
199  if (voe_vsync_) {
200    voe_vsync_->Release();
201    voe_vsync_ = NULL;
202  }
203#endif
204  if (voe_hardware_) {
205    voe_hardware_->Release();
206    voe_hardware_ = NULL;
207  }
208#ifdef _TEST_XMEDIA_
209  if (voe_xmedia_) {
210    voe_xmedia_->Release();
211    voe_xmedia_ = NULL;
212  }
213#endif
214#ifdef WEBRTC_VOICE_ENGINE_NETEQ_STATS_API
215  if (voe_neteq_stats_) {
216    voe_neteq_stats_->Release();
217    voe_neteq_stats_ = NULL;
218  }
219#endif
220  if (false == VoiceEngine::Delete(voice_engine_)) {
221    TEST_LOG("\n\nVoiceEngine::Delete() failed. \n");
222    releaseOK = false;
223  }
224
225  return (releaseOK == true) ? 0 : -1;
226}
227
228int run_auto_test(TestType test_type) {
229  assert(test_type != Standard);
230
231  SubAPIManager api_manager;
232  api_manager.DisplayStatus();
233
234  ////////////////////////////////////
235  // Create VoiceEngine and sub API:s
236
237  voetest::VoETestManager test_manager;
238  if (!test_manager.Init()) {
239    return -1;
240  }
241  test_manager.GetInterfaces();
242
243  int result = -1;
244  if (test_type == Stress) {
245    VoEStressTest stressTest(test_manager);
246    result = stressTest.DoTest();
247  } else if (test_type == CPU) {
248    VoECpuTest cpuTest(test_manager);
249    result = cpuTest.DoTest();
250  } else {
251    // Should never end up here
252    assert(false);
253  }
254
255  //////////////////
256  // Release/Delete
257
258  int release_ok = test_manager.ReleaseInterfaces();
259
260  if ((0 == result) && (release_ok != -1)) {
261    TEST_LOG("\n\n*** All tests passed *** \n\n");
262  } else {
263    TEST_LOG("\n\n*** Test failed! *** \n");
264  }
265
266  return 0;
267}
268}  // namespace voetest
269
270int RunInManualMode() {
271  using namespace voetest;
272
273  SubAPIManager api_manager;
274  api_manager.DisplayStatus();
275
276  printf("----------------------------\n");
277  printf("Select type of test\n\n");
278  printf(" (0)  Quit\n");
279  printf(" (1)  Standard test\n");
280  printf(" (2)  [OBSOLETE: Extended test(s)...]\n");
281  printf(" (3)  Stress test(s)...\n");
282  printf(" (4)  [OBSOLETE: Unit test(s)...]\n");
283  printf(" (5)  CPU & memory reference test [Windows]...\n");
284  printf("\n: ");
285
286  int selection(0);
287  dummy = scanf("%d", &selection);
288
289  TestType test_type = Invalid;
290  switch (selection) {
291    case 0:
292      return 0;
293    case 1:
294      test_type = Standard;
295      break;
296    case 2:
297      break;
298    case 3:
299      test_type = Stress;
300      break;
301    case 4:
302      break;
303    case 5:
304      test_type = CPU;
305      break;
306    default:
307      TEST_LOG("Invalid selection!\n");
308      return 0;
309  }
310
311  if (test_type == Standard) {
312    TEST_LOG("\n\n+++ Running standard tests +++\n\n");
313
314    // Currently, all googletest-rewritten tests are in the "automated" suite.
315    return RunInAutomatedMode();
316  }
317
318  // Function that can be called from other entry functions.
319  return run_auto_test(test_type);
320}
321
322// ----------------------------------------------------------------------------
323//                                       main
324// ----------------------------------------------------------------------------
325
326#if !defined(WEBRTC_IOS)
327int main(int argc, char** argv) {
328  // This function and RunInAutomatedMode is defined in automated_mode.cc
329  // to avoid macro clashes with googletest (for instance ASSERT_TRUE).
330  InitializeGoogleTest(&argc, argv);
331  // AllowCommandLineParsing allows us to ignore flags passed on to us by
332  // Chromium build bots without having to explicitly disable them.
333  google::AllowCommandLineReparsing();
334  google::ParseCommandLineFlags(&argc, &argv, true);
335
336  if (FLAGS_automated) {
337    return RunInAutomatedMode();
338  }
339
340  return RunInManualMode();
341}
342#endif //#if !defined(WEBRTC_IOS)
343