439 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			439 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * Copyright (c) 2021 OceanBase
 | 
						|
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
						|
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
						|
 * You may obtain a copy of Mulan PubL v2 at:
 | 
						|
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
						|
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
 * See the Mulan PubL v2 for more details.
 | 
						|
 */
 | 
						|
 | 
						|
#define USING_LOG_PREFIX COMMON
 | 
						|
 | 
						|
#include <gtest/gtest.h>
 | 
						|
#include <gmock/gmock.h>
 | 
						|
#include "share/ob_debug_sync.h"
 | 
						|
#include "lib/string/ob_sql_string.h"
 | 
						|
#include "lib/container/ob_array.h"
 | 
						|
#include "lib/container/ob_array_iterator.h"
 | 
						|
#include "rpc/mock_ob_common_rpc_proxy.h"
 | 
						|
#include "share/config/ob_server_config.h"
 | 
						|
#include <pthread.h>
 | 
						|
 | 
						|
namespace oceanbase
 | 
						|
{
 | 
						|
namespace common
 | 
						|
{
 | 
						|
using namespace obrpc;
 | 
						|
using testing::_;
 | 
						|
using testing::Return;
 | 
						|
 | 
						|
TEST(common, ObDebugSyncAction)
 | 
						|
{
 | 
						|
  ObDebugSyncAction a;
 | 
						|
  ASSERT_FALSE(a.is_valid());
 | 
						|
 | 
						|
  a.sync_point_ = NOW;
 | 
						|
  a.execute_ = 1;
 | 
						|
  ASSERT_FALSE(a.is_valid());
 | 
						|
  a.signal_ = "a";
 | 
						|
  ASSERT_TRUE(a.is_valid());
 | 
						|
  a.wait_ = "b";
 | 
						|
  ASSERT_TRUE(a.is_valid());
 | 
						|
  a.execute_ = 0;
 | 
						|
  ASSERT_FALSE(a.is_valid());
 | 
						|
  a.execute_ = 1;
 | 
						|
  ASSERT_TRUE(a.is_valid());
 | 
						|
  a.signal_ = "";
 | 
						|
  ASSERT_TRUE(a.is_valid());
 | 
						|
 | 
						|
  a.timeout_ = 1024;
 | 
						|
  a.no_clear_ = true;
 | 
						|
  a.signal_ = "signal";
 | 
						|
 | 
						|
  int64_t len = a.get_serialize_size();
 | 
						|
  char buf[len];
 | 
						|
  LOG_INFO("action serialize size", K(len));
 | 
						|
  int64_t pos = 0;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, a.serialize(buf, len, pos));
 | 
						|
  ASSERT_EQ(pos, len);
 | 
						|
  pos = 0;
 | 
						|
 | 
						|
  ObDebugSyncAction b;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, b.deserialize(buf, len, pos));
 | 
						|
 | 
						|
  ASSERT_EQ(a.sync_point_, b.sync_point_);
 | 
						|
  ASSERT_EQ(a.timeout_, b.timeout_);
 | 
						|
  ASSERT_EQ(a.signal_, b.signal_);
 | 
						|
  ASSERT_EQ(a.wait_, b.wait_);
 | 
						|
  ASSERT_EQ(a.no_clear_, b.no_clear_);
 | 
						|
}
 | 
						|
 | 
						|
TEST(common, ObDSActionArray)
 | 
						|
{
 | 
						|
  ObDSActionArray aa;
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
  ASSERT_FALSE(aa.is_active(NOW));
 | 
						|
 | 
						|
  ObDebugSyncAction a;
 | 
						|
  a.sync_point_ = NOW;
 | 
						|
  a.execute_ = 2;
 | 
						|
  a.wait_ = "abc";
 | 
						|
  a.timeout_ = 1024000;
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  ASSERT_TRUE(aa.is_active(NOW));
 | 
						|
 | 
						|
  ObDebugSyncAction b;
 | 
						|
  aa.copy_action(NOW, b);
 | 
						|
  ASSERT_EQ(a.get_serialize_size(), b.get_serialize_size());
 | 
						|
 | 
						|
  // fetch to empty
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.fetch_action(NOW, b));
 | 
						|
  ASSERT_FALSE(aa.is_empty());
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.fetch_action(NOW, b));
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
  ASSERT_EQ(OB_ENTRY_NOT_EXIST, aa.fetch_action(NOW, b));
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.fetch_action(NOW, b));
 | 
						|
  // over write
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.fetch_action(NOW, b));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.fetch_action(NOW, b));
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  ASSERT_FALSE(aa.is_empty());
 | 
						|
 | 
						|
  aa.clear(NOW);
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  aa.clear_all();
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
 | 
						|
  ObDSActionArray ba;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ba.add_action(a));
 | 
						|
 | 
						|
  const static int64_t BUF_SIZE = 1024;
 | 
						|
  char buf[BUF_SIZE];
 | 
						|
  int64_t len = aa.get_serialize_size();
 | 
						|
  LOG_INFO("empty debug sync array actions overhead", K(len));
 | 
						|
  int64_t pos = 0;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.serialize(buf, len, pos));
 | 
						|
  ASSERT_EQ(pos, len);
 | 
						|
 | 
						|
  pos = 0;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ba.deserialize(buf, len, pos));
 | 
						|
  ASSERT_TRUE(ba.is_empty());
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  a.sync_point_ = MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT;
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  len = aa.get_serialize_size();
 | 
						|
 | 
						|
  pos = 0;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.serialize(buf, len, pos));
 | 
						|
  ASSERT_EQ(pos, len);
 | 
						|
 | 
						|
  pos = 0;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ba.deserialize(buf, len, pos));
 | 
						|
  ASSERT_EQ(pos, len);
 | 
						|
 | 
						|
  ASSERT_TRUE(ba.is_active(NOW));
 | 
						|
  ASSERT_TRUE(ba.is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  // const action array will always be empty
 | 
						|
  const bool is_const = true;
 | 
						|
  ObDSActionArray ca(is_const);
 | 
						|
  pos = 0;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ca.deserialize(buf, len, pos));
 | 
						|
  ASSERT_EQ(pos, len);
 | 
						|
 | 
						|
  ASSERT_FALSE(ca.is_active(NOW));
 | 
						|
  ASSERT_FALSE(ca.is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  ASSERT_TRUE(ca.is_empty());
 | 
						|
}
 | 
						|
 | 
						|
TEST(common, ObDSSessionActions)
 | 
						|
{
 | 
						|
  ObMalloc allocator;
 | 
						|
  ObDSSessionActions sa;
 | 
						|
 | 
						|
  ObDebugSyncAction a;
 | 
						|
  a.sync_point_ = NOW;
 | 
						|
  a.signal_ = "abc";
 | 
						|
  a.execute_ = 1024;
 | 
						|
 | 
						|
  ASSERT_NE(OB_SUCCESS, sa.add_action(a));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, sa.init(1024, allocator));
 | 
						|
 | 
						|
  ASSERT_TRUE(sa.is_inited());
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, sa.add_action(a));
 | 
						|
  ObDSActionArray aa;
 | 
						|
  sa.to_thread_local(aa);
 | 
						|
  ASSERT_FALSE(aa.is_empty());
 | 
						|
  ASSERT_TRUE(aa.is_active(NOW));
 | 
						|
 | 
						|
  aa.clear_all();
 | 
						|
  sa.get_thread_local_result(aa);
 | 
						|
  sa.to_thread_local(aa);
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, sa.add_action(a));
 | 
						|
  a.sync_point_ = MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, aa.add_action(a));
 | 
						|
  sa.to_thread_local(aa);
 | 
						|
  ASSERT_TRUE(aa.is_active(NOW));
 | 
						|
  ASSERT_FALSE(aa.is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, sa.add_action(a));
 | 
						|
  sa.clear(NOW);
 | 
						|
  sa.to_thread_local(aa);
 | 
						|
  ASSERT_FALSE(aa.is_active(NOW));
 | 
						|
  ASSERT_TRUE(aa.is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  sa.clear_all();
 | 
						|
  sa.to_thread_local(aa);
 | 
						|
  ASSERT_TRUE(aa.is_empty());
 | 
						|
}
 | 
						|
 | 
						|
class Timer
 | 
						|
{
 | 
						|
public:
 | 
						|
  Timer() { begin_ = ::oceanbase::common::ObTimeUtility::current_time(); }
 | 
						|
  int64_t used() const { return ::oceanbase::common::ObTimeUtility::current_time() - begin_; }
 | 
						|
public:
 | 
						|
  int64_t begin_;
 | 
						|
};
 | 
						|
 | 
						|
static ObDSEventControl global_event_control; // avoid large stack object
 | 
						|
#define WAIT_TIME 200000
 | 
						|
#define WAIT_TIME_SAFE (WAIT_TIME * 9 / 10)
 | 
						|
 | 
						|
#define TO_STRING_(x) #x
 | 
						|
#define TO_STRING(x) "" TO_STRING_(x)
 | 
						|
 | 
						|
void *run_wait(void *arg)
 | 
						|
{
 | 
						|
  ObDSEventControl *ec = static_cast<ObDSEventControl *>(arg);
 | 
						|
  ec->wait("multi-thread-event", WAIT_TIME, true);
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
TEST(common, ObDSEventControl)
 | 
						|
{
 | 
						|
  ObDSEventControl &ec = global_event_control;
 | 
						|
  ASSERT_NE(OB_SUCCESS, ec.signal(""));
 | 
						|
 | 
						|
  ObSqlString event;
 | 
						|
  for (int64_t i = 0; i < ec.MAX_EVENT_CNT; ++i) {
 | 
						|
    ASSERT_EQ(OB_SUCCESS, event.assign_fmt("%ld", i));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ec.signal(event.ptr())) << "event: " << event.ptr() << std::endl;
 | 
						|
  }
 | 
						|
  ASSERT_NE(OB_SUCCESS, ec.signal("e"));
 | 
						|
  ec.clear_event();
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ec.signal("e"));
 | 
						|
  const bool DO_CLEAR = true;
 | 
						|
  const bool NO_CLEAR = false;
 | 
						|
 | 
						|
  {
 | 
						|
    Timer t;
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ec.wait("e", WAIT_TIME, NO_CLEAR));
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ec.signal("e"));
 | 
						|
  {
 | 
						|
    Timer t;
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ec.wait("e", WAIT_TIME, DO_CLEAR));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ec.wait("e", WAIT_TIME, DO_CLEAR));
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    Timer t;
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ec.wait("e", WAIT_TIME, DO_CLEAR));
 | 
						|
    ASSERT_GT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    Timer t;
 | 
						|
    ObArray<pthread_t> tids;
 | 
						|
    const int64_t MAX_THREAD_CNT = 10;
 | 
						|
    int64_t n = 0;
 | 
						|
    for (; n < MAX_THREAD_CNT / 2; ++n) {
 | 
						|
      ASSERT_EQ(OB_SUCCESS, ec.signal("multi-thread-event"));
 | 
						|
    }
 | 
						|
    for (int64_t i = 0; i < MAX_THREAD_CNT; ++i) {
 | 
						|
      pthread_t tid;
 | 
						|
      ASSERT_EQ(0, pthread_create(&tid, NULL, run_wait, &ec));
 | 
						|
      ASSERT_EQ(OB_SUCCESS, tids.push_back(tid));
 | 
						|
    }
 | 
						|
    for (; n < MAX_THREAD_CNT; ++n) {
 | 
						|
      ASSERT_EQ(OB_SUCCESS, ec.signal("multi-thread-event"));
 | 
						|
    }
 | 
						|
    for (int64_t i = 0; i < MAX_THREAD_CNT; ++i) {
 | 
						|
      pthread_join(tids.at(i), NULL);
 | 
						|
    }
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    Timer t;
 | 
						|
    pthread_t tid;
 | 
						|
    ASSERT_EQ(0, pthread_create(&tid, NULL, run_wait, &ec));
 | 
						|
    ec.stop();
 | 
						|
    pthread_join(tid, NULL);
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TEST(debug_sync, ObDebugSync)
 | 
						|
{
 | 
						|
  MockObCommonRpcProxy rpc;
 | 
						|
  GDS.set_rpc_proxy(&rpc);
 | 
						|
  ObMalloc allocator;
 | 
						|
  ObDSSessionActions sa;
 | 
						|
  ASSERT_EQ(OB_SUCCESS, sa.init(1024, allocator));
 | 
						|
 | 
						|
  GCONF.debug_sync_timeout.set_value("0");
 | 
						|
  ASSERT_FALSE(GCONF.is_debug_sync_enabled());
 | 
						|
  ASSERT_NE(&GDS.rpc_spread_actions(), GDS.thread_local_actions());
 | 
						|
 | 
						|
  // test debug sync parser
 | 
						|
  const bool L = false; // local
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  reset   ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  clear    ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("now  signal x", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  SIGNAL x-y    execute 1024 ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  NOW  signal x-y    execute 1024 ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  wait_for x-y ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("now  wait_for x-y  no_clear_event", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  wait_for x-y  no_clear_event execute 2 ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  wait_for x-y  timeout 1024 no_clear_event execute 2 ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  wait_for x-y  no_clear_event timeout 1024 execute 2 ", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  now  signal xxx wait_for x-y  timeout 0 no_clear_event execute 2 ", L, sa));
 | 
						|
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("  reset a", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("  signal b ", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("  not_exist_sync_point signal b ", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("now signal not-support-too-long-event-name-bigger-than-32-byte ", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("now signal xyz execute 0", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("now signal xyc unknow_parameters", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("now clear unknow_parameters", L, sa));
 | 
						|
  ASSERT_NE(OB_SUCCESS, GDS.add_debug_sync("now wait_for xyc unknow_parameters", L, sa));
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("  reset ", L, sa));
 | 
						|
 | 
						|
  GCONF.debug_sync_timeout.set_value("100000000");
 | 
						|
  ASSERT_TRUE(GCONF.is_debug_sync_enabled());
 | 
						|
  ASSERT_EQ(&GDS.rpc_spread_actions(), GDS.thread_local_actions());
 | 
						|
 | 
						|
  // test set to thread local and collect result
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("reset", L, sa));
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT signal xyz", L, sa));
 | 
						|
  ASSERT_TRUE(GDS.rpc_spread_actions().is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT clear", L, sa));
 | 
						|
  ASSERT_FALSE(GDS.rpc_spread_actions().is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT signal xyz", L, sa));
 | 
						|
  GDS.rpc_spread_actions().clear_all();
 | 
						|
  GDS.set_thread_local_actions(sa);
 | 
						|
  ASSERT_TRUE(GDS.rpc_spread_actions().is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  GDS.rpc_spread_actions().clear_all();
 | 
						|
  GDS.collect_result_actions(sa);
 | 
						|
  GDS.set_thread_local_actions(sa);
 | 
						|
  ASSERT_FALSE(GDS.rpc_spread_actions().is_active(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT));
 | 
						|
 | 
						|
  // test execute
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("reset", L, sa));
 | 
						|
  {
 | 
						|
    Timer t;
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("now wait_for xyz timeout " TO_STRING(WAIT_TIME), L, sa));
 | 
						|
    ASSERT_GT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
  ASSERT_TRUE(GDS.rpc_spread_actions().is_empty());
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT signal xyz execute 2", L, sa));
 | 
						|
  DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
  DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
  DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
 | 
						|
  ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT signal def wait_for xyz TIMEOUT " TO_STRING(WAIT_TIME) " execute 3", L, sa));
 | 
						|
 | 
						|
  {
 | 
						|
    // get xyz
 | 
						|
    Timer t;
 | 
						|
    DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
    DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    // timeout
 | 
						|
    Timer t;
 | 
						|
    DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
    ASSERT_GT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    // not active
 | 
						|
    Timer t;
 | 
						|
    DEBUG_SYNC(MAJOR_FREEZE_BEFORE_SYS_COORDINATE_COMMIT);
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    // get def
 | 
						|
    Timer t;
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("NOW wait_for def TIMEout " TO_STRING(WAIT_TIME), L, sa));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("NOW wait_for def TIMEout " TO_STRING(WAIT_TIME), L, sa));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("NOW wait_for def TIMEout " TO_STRING(WAIT_TIME), L, sa));
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    // timeout
 | 
						|
    Timer t;
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("NOW wait_for def TIMEout " TO_STRING(WAIT_TIME), L, sa));
 | 
						|
    ASSERT_GT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
 | 
						|
  // global actions
 | 
						|
  const bool G = true; // global
 | 
						|
  {
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("reset", L, sa));
 | 
						|
    EXPECT_CALL(rpc, broadcast_ds_action(_, _)).Times(3).WillRepeatedly(Return(OB_SUCCESS));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("reset", G, sa));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("now clear", G, sa));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("now signal x", G, sa));
 | 
						|
  }
 | 
						|
 | 
						|
  {
 | 
						|
    // mock rpc will not wait
 | 
						|
    Timer t;
 | 
						|
    EXPECT_CALL(rpc, broadcast_ds_action(_, _)).Times(2).WillRepeatedly(Return(OB_SUCCESS));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("reset", G, sa));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, GDS.add_debug_sync("NOW wait_for def TIMEout " TO_STRING(WAIT_TIME), G, sa));
 | 
						|
    ASSERT_LT(t.used(), WAIT_TIME_SAFE);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
}
 | 
						|
 | 
						|
int main(int argc, char **argv)
 | 
						|
{
 | 
						|
  ::testing::InitGoogleTest(&argc,argv);
 | 
						|
  return RUN_ALL_TESTS();
 | 
						|
}
 |