1/*
2 *  Copyright 2004 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#ifndef WEBRTC_BASE_GUNIT_H_
12#define WEBRTC_BASE_GUNIT_H_
13
14#include "webrtc/base/logging.h"
15#include "webrtc/base/thread.h"
16#if defined(GTEST_RELATIVE_PATH)
17#include "testing/gtest/include/gtest/gtest.h"
18#else
19#include "testing/base/public/gunit.h"
20#endif
21
22// Wait until "ex" is true, or "timeout" expires.
23#define WAIT(ex, timeout)                                                     \
24  for (uint32_t start = rtc::Time(); !(ex) && rtc::Time() < start + timeout;) \
25    rtc::Thread::Current()->ProcessMessages(1);
26
27// This returns the result of the test in res, so that we don't re-evaluate
28// the expression in the XXXX_WAIT macros below, since that causes problems
29// when the expression is only true the first time you check it.
30#define WAIT_(ex, timeout, res)                     \
31  do {                                              \
32    uint32_t start = rtc::Time();                   \
33    res = (ex);                                     \
34    while (!res && rtc::Time() < start + timeout) { \
35      rtc::Thread::Current()->ProcessMessages(1);   \
36      res = (ex);                                   \
37    }                                               \
38  } while (0)
39
40// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
41#define EXPECT_TRUE_WAIT(ex, timeout) \
42  do { \
43    bool res; \
44    WAIT_(ex, timeout, res); \
45    if (!res) EXPECT_TRUE(ex); \
46  } while (0)
47
48#define EXPECT_EQ_WAIT(v1, v2, timeout) \
49  do { \
50    bool res; \
51    WAIT_(v1 == v2, timeout, res); \
52    if (!res) EXPECT_EQ(v1, v2); \
53  } while (0)
54
55#define ASSERT_TRUE_WAIT(ex, timeout) \
56  do { \
57    bool res; \
58    WAIT_(ex, timeout, res); \
59    if (!res) ASSERT_TRUE(ex); \
60  } while (0)
61
62#define ASSERT_EQ_WAIT(v1, v2, timeout) \
63  do { \
64    bool res; \
65    WAIT_(v1 == v2, timeout, res); \
66    if (!res) ASSERT_EQ(v1, v2); \
67  } while (0)
68
69// Version with a "soft" timeout and a margin. This logs if the timeout is
70// exceeded, but it only fails if the expression still isn't true after the
71// margin time passes.
72#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
73  do { \
74    bool res; \
75    WAIT_(ex, timeout, res); \
76    if (res) { \
77      break; \
78    } \
79    LOG(LS_WARNING) << "Expression " << #ex << " still not true after " << \
80        timeout << "ms; waiting an additional " << margin << "ms"; \
81    WAIT_(ex, margin, res); \
82    if (!res) { \
83      EXPECT_TRUE(ex); \
84    } \
85  } while (0)
86
87#endif  // WEBRTC_BASE_GUNIT_H_
88