TEST_F(TestRpcStub, test_init)
{
  ObMergerRpcStub stub;
  EXPECT_TRUE(OB_SUCCESS != stub.init(NULL, NULL));

  ThreadSpecificBuffer buffer;
  ObClientManager client_manager;
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));
  
  EXPECT_TRUE(OB_SUCCESS != stub.init(&buffer, &client_manager));
}
TEST_F(TestTimerTask, test_timer_fetch)
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;
  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  int64_t timeout = 1000000;
  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  ObServer merge_server;
  ObMergerRpcProxy proxy(1, timeout, root_server, merge_server);

  EXPECT_TRUE(OB_SUCCESS != proxy.init(NULL, NULL, NULL));
  EXPECT_TRUE(OB_SUCCESS != proxy.init(&stub, NULL, NULL));

  ObMergerSchemaManager * schema = new ObMergerSchemaManager;
  EXPECT_TRUE(NULL != schema);
  ObSchemaManagerV2 temp(200);
  EXPECT_TRUE(OB_SUCCESS == schema->init(false, temp));

  ObTabletLocationCache * location = new ObMergerTabletLocationCache;
  EXPECT_TRUE(NULL != location);
  EXPECT_TRUE(OB_SUCCESS == proxy.init(&stub, schema, location));

  // not start root server
  ObMergerSchemaTask task;
  task.init(&proxy, schema);
  ObTimer timer;
  EXPECT_TRUE(OB_SUCCESS == timer.init());
  task.set_version(1024, 1025);
  EXPECT_TRUE(OB_SUCCESS == timer.schedule(task, 2000 * 1000, false));
  EXPECT_TRUE(200 == schema->get_latest_version());

  // start root server
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  root_server_thread.start(&test_root_server, NULL); 
  sleep(5);

  // wait timer task processed 
  EXPECT_TRUE(1025 == schema->get_latest_version());
  timer.destroy();

  transport.stop();
  server.stop();
  sleep(5);
}
TEST_F(TestRpcStub, test_scan_root_table) 
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;

  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  // self server 
  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  // scan root error
  char * string = "test_table";
  uint64_t root_table = 0;
  uint64_t table_id = 100;
  ObString row_key;
  row_key.assign(string, strlen(string));
  ObScanner scanner;
  EXPECT_TRUE(OB_SUCCESS != stub.fetch_tablet_location(timeout, root_server, root_table, table_id, row_key, scanner));

  // start root server
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  root_server_thread.start(&test_root_server, NULL); 
  sleep(2);

  // root table id = 0
  root_table = 0;
  EXPECT_TRUE(OB_SUCCESS == stub.fetch_tablet_location(timeout, root_server, root_table, table_id, row_key, scanner));
  
  transport.stop();
  server.stop();
  sleep(10);
}
TEST_F(TestRpcStub, test_find_server) 
{
  // client thread one
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  // 2 & 3 (io transport thread)
  transport.start();
  ObClientManager client_manager;
  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  // register error
  ObServer update_server;
  EXPECT_TRUE(OB_SUCCESS != stub.find_server(timeout, root_server, update_server));

  // server thread
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  // 4(queue) & 5 & 6(io transport) & 7(main)
  root_server_thread.start(&test_root_server, NULL); 
  sleep(2);

  EXPECT_TRUE(OB_SUCCESS == stub.find_server(timeout, root_server, update_server));
  EXPECT_TRUE(MockUpdateServer::UPDATE_SERVER_PORT == update_server.get_port());
  
  EXPECT_TRUE(OB_SUCCESS == stub.find_server(timeout, root_server, update_server));
  EXPECT_TRUE(MockUpdateServer::UPDATE_SERVER_PORT == update_server.get_port());
  
  transport.stop();
  server.stop();
  sleep(10);
}
TEST_F(TestRpcStub, test_fetch_schema) 
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;

  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  // self server 
  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  // start root server
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  root_server_thread.start(&test_root_server, NULL); 
  sleep(2); 

  ObSchemaManagerV2 manager;
  // wrong version
  int64_t timestamp = 1023;
  EXPECT_TRUE(OB_SUCCESS != stub.fetch_schema(timeout, root_server, timestamp, manager));

  timestamp = 1024;
  EXPECT_TRUE(OB_SUCCESS == stub.fetch_schema(timeout, root_server, timestamp, manager));
  EXPECT_TRUE(manager.get_version() == 1025);
  
  transport.stop();
  server.stop();
  sleep(10);
}
TEST_F(TestSchemaProxy, test_get)
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;

  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);
  ObMergerRootRpcProxy root_proxy(0, timeout, root_server);

  // not init
  const ObSchemaManagerV2 * schema = NULL;
  ObMergerSchemaManager * manager = new ObMergerSchemaManager;
  EXPECT_TRUE(NULL != manager);
  int64_t timestamp = ObMergerSchemaProxy::LOCAL_NEWEST;
  ObMergerSchemaProxy proxy(&root_proxy, manager);
  EXPECT_TRUE(OB_SUCCESS == proxy.get_schema(timestamp, &schema));
  EXPECT_TRUE(schema == NULL);
  
  timestamp = 1001;
  EXPECT_TRUE(OB_SUCCESS != proxy.get_schema(timestamp, &schema));

  timestamp = ObMergerSchemaProxy::LOCAL_NEWEST;
  EXPECT_TRUE(OB_SUCCESS == root_proxy.init(&stub));
  EXPECT_TRUE(OB_SUCCESS == proxy.get_schema(timestamp, &schema));
  EXPECT_TRUE(schema == NULL);

  // init schema manger
  ObSchemaManagerV2 sample(1022);
  EXPECT_TRUE(OB_SUCCESS == manager->init(sample));

  EXPECT_TRUE(OB_SUCCESS == proxy.get_schema(timestamp, &schema));
  EXPECT_TRUE(NULL != schema);
  EXPECT_TRUE(schema->get_version() == 1022);
  EXPECT_TRUE(OB_SUCCESS == proxy.release_schema(schema));
  
  // server not start
  timestamp = 1024;
  EXPECT_TRUE(OB_SUCCESS != proxy.get_schema(timestamp, &schema));
  
  // start root server
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  root_server_thread.start(&test_root_server, NULL); 
  sleep(2);
  
  // not exist but server exist
  timestamp = 1024;
  EXPECT_TRUE(OB_SUCCESS == proxy.get_schema(timestamp, &schema));
  EXPECT_TRUE(NULL != schema);
  EXPECT_TRUE(schema->get_version() == 1025);
  EXPECT_TRUE(OB_SUCCESS == proxy.release_schema(schema));

  // get server newest for init
  timestamp = 100;
  // add schema failed
  EXPECT_TRUE(OB_SUCCESS != proxy.get_schema(timestamp, &schema));
  
  // local version
  timestamp = ObMergerSchemaProxy::LOCAL_NEWEST;
  EXPECT_TRUE(OB_SUCCESS == proxy.get_schema(timestamp, &schema));
  EXPECT_TRUE(NULL != schema);
  EXPECT_TRUE(schema->get_version() == 1025);
  EXPECT_TRUE(OB_SUCCESS == proxy.release_schema(schema));
  
  if (manager)
  {
    delete manager;
    manager = NULL;
  }

  transport.stop();
  server.stop();
  sleep(5);
}
// multi-thread schema test
TEST_F(TestSchemaProxy, test_multi_schema)
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;

  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  ObServer update_server;
  update_server.set_ipv4_addr(addr, MockUpdateServer::UPDATE_SERVER_PORT);
  
  ObServer merge_server;
  merge_server.set_ipv4_addr(addr, 10256);
  ObMergerRootRpcProxy root_proxy(0, timeout, root_server);
  EXPECT_TRUE(OB_SUCCESS == root_proxy.init(&stub));

  ObMergerSchemaManager * manager = new ObMergerSchemaManager;
  EXPECT_TRUE(NULL != manager);
  ObSchemaManagerV2 sample(1022);
  EXPECT_TRUE(OB_SUCCESS == manager->init(sample));
  
  ObMergerSchemaProxy proxy(&root_proxy, manager);
  // start root server
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  root_server_thread.start(&test_root_server, NULL); 
  sleep(2);
  
  const int MAX_THREAD_COUNT = 15;
  pthread_t threads[MAX_THREAD_COUNT];
  for (int i = 0; i < MAX_THREAD_COUNT; ++i)
  {
    int ret = pthread_create(&threads[i], NULL, fetch_schema, &proxy);
    if (ret != OB_SUCCESS)
    {
      break;
    }
  }

  for (int i = 0; i < MAX_THREAD_COUNT; ++i)
  {
    pthread_join(threads[i], NULL);
  }
  
  if (NULL != manager)
  {
    delete manager;
    manager = NULL;
  }
  transport.stop();
  server.stop();
  sleep(5);
}
TEST_F(TestMergerVersionProxy, test_version)
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;
  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  int64_t timeout = 1000000;
  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  ObServer merge_server;
  ObMergerRpcProxy proxy(1, timeout, root_server, merge_server);
  ObServer update_server;
  update_server.set_ipv4_addr(addr, MockUpdateServer::UPDATE_SERVER_PORT);

  proxy.set_master_ups(update_server);
  EXPECT_TRUE(OB_SUCCESS != proxy.init(NULL, NULL, NULL));
  EXPECT_TRUE(OB_SUCCESS != proxy.init(&stub, NULL, NULL));

  ObMergerSchemaManager * schema = new ObMergerSchemaManager;
  EXPECT_TRUE(NULL != schema);
  ObSchemaManagerV2 temp(200);
  EXPECT_TRUE(OB_SUCCESS == schema->init(false, temp));

  ObTabletLocationCache * location = new ObMergerTabletLocationCache;
  EXPECT_TRUE(NULL != location);
  EXPECT_TRUE(OB_SUCCESS == proxy.init(&stub, schema, location));

  int64_t version_timeout = 1000 * 1000 * 2L;
  ObMergerVersionProxy version_proxy(version_timeout);
  int64_t version = 0;

  // not init
  EXPECT_TRUE(OB_SUCCESS != version_proxy.get_version(version));
  EXPECT_TRUE(OB_SUCCESS != version_proxy.init(NULL));
  EXPECT_TRUE(OB_SUCCESS == version_proxy.init(&proxy));
  // not run server
  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(version));
  EXPECT_TRUE(-1 == version);

  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(version));
  EXPECT_TRUE(-1 == version);

  // start mock server
  MockUpdateServer server;
  MockServerRunner test_update_server(server);
  tbsys::CThread update_server_thread;
  update_server_thread.start(&test_update_server, NULL); 

  sleep(2);

  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(version));
  EXPECT_TRUE(-1 != version);

  int64_t new_version = 0;
  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version == version);

  usleep(static_cast<useconds_t>(version_timeout * 2));
  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version != version);

  version = new_version;
  new_version = 0;
  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version == version);

  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version == version);

  // cache timeout
  usleep(static_cast<useconds_t>(version_timeout * 2));
  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version != version);
  server.stop();
  version = new_version;
  new_version = 0;
  // server stoped
  usleep(static_cast<useconds_t>(version_timeout * 2));
  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version == version);

  EXPECT_TRUE(OB_SUCCESS == version_proxy.get_version(new_version));
  EXPECT_TRUE(new_version == version);

  transport.stop();
}
TEST_F(TestTimerTask, test_fetch_schema)
{
  /*
  const char * test = "test";
  printf("ret[%d]\n", memcmp(NULL, test, 0));
  printf("ret[%d]\n", memcmp(test, NULL, 0));
  */

  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;
  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  int64_t timeout = 100000;
  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);

  ObServer merge_server;
  ObMergerRpcProxy proxy(1, timeout, root_server, merge_server);

  EXPECT_TRUE(OB_SUCCESS != proxy.init(NULL, NULL, NULL));
  EXPECT_TRUE(OB_SUCCESS != proxy.init(&stub, NULL, NULL));

  ObMergerSchemaManager * schema = new ObMergerSchemaManager;
  EXPECT_TRUE(NULL != schema);
  ObSchemaManagerV2 temp(200);
  EXPECT_TRUE(OB_SUCCESS == schema->init(false, temp));

  ObTabletLocationCache * location = new ObMergerTabletLocationCache;
  EXPECT_TRUE(NULL != location);
  EXPECT_TRUE(OB_SUCCESS == proxy.init(&stub, schema, location));

  // not start root server
  ObMergerSchemaTask task;
  task.init(&proxy, schema);
  task.runTimerTask();
  EXPECT_TRUE(200 == schema->get_latest_version());

  // stat failed
  ObMergerSchemaTask task1;
  task1.init(NULL, NULL);
  task1.runTimerTask();
  EXPECT_TRUE(200 == schema->get_latest_version());

  // start root server
  MockRootServer server;
  MockServerRunner test_root_server(server);
  tbsys::CThread root_server_thread;
  root_server_thread.start(&test_root_server, NULL); 
  sleep(2);

  task.set_version(1024, 1025);
  task.runTimerTask();
  // root server returned
  EXPECT_TRUE(1025 == schema->get_latest_version());

  transport.stop();
  server.stop();
  sleep(5);
}
TEST_F(TestObRpcScan, test_single_table_scan)
{
  /// 0. start packet handler thread
  CThread packet_hanlder_thread;
  packet_hanlder_thread.start(&handler, NULL);

  /// 1. setup transport
  /// 2. setup servers (root, ups, CSes)
  /// 3. setup scan request (location list, scan range)

  TBSYS_LOG(INFO, "( 1 )");
  tbnet::Transport * transport = new tbnet::Transport();
  tbnet::DefaultPacketStreamer * streamer = new tbnet::DefaultPacketStreamer();
  ObPacketFactory * factory = new ObPacketFactory();
  streamer->setPacketFactory(factory);
  ObClientManager client_manager;
  client_manager.initialize(transport, streamer);
  transport->start();
#if 0
  EXPECT_CALL(client_manager, post_request(_,_,_,_,_,_,_))
    .Times(AtLeast(1))
    .WillRepeatedly(Invoke(callback_func));
  EXPECT_CALL(client_manager, handlePacket(_,_))
    .Times(AtLeast(1))
    .WillOnce(Return(OB_SUCCESS))
    .WillOnce(Return((tbnet::IPacketHandler::HPRetCode)0));
#endif

  TBSYS_LOG(INFO, "( 2 )");
  ObServer update_server;
  ObServer root_server;
  ObServer merge_server;
  update_server.set_ipv4_addr(addr, MockUpdateServer::UPDATE_SERVER_PORT);
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);
  ObMergerRpcProxy proxy(3, timeout, root_server, merge_server);

  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  stub.init(&buffer, &client_manager);
  ObMergerRootRpcProxy rpc(0, timeout, root_server);
  EXPECT_TRUE(OB_SUCCESS == rpc.init(&stub));

  merge_server.set_ipv4_addr(addr, 10256);
  ObMergerTabletLocationCache * location = new ObMergerTabletLocationCache;
  location->init(50000 * 5, 1000, 100000);

  TBSYS_LOG(INFO, "( 3 )");
  // start root server
  MockRootServer root;
  tbsys::CThread root_server_thread;
  MockServerRunner test_root_server(root);
  root_server_thread.start(&test_root_server, NULL);

  /// (4) do it!
  MockObMergerAsyncRpcStub async;
  async.init(&buffer, &client_manager);
  ObMergerLocationCacheProxy location_proxy(root_server, &rpc, location);
  ObRpcScan scan;
  ObRowkeyInfo rowkey_info;
  ObRowkeyColumn column;
  column.length_ = 4;
  column.column_id_ = 102;
  column.type_ = ObIntType;
  rowkey_info.add_column(column);
#if 0
  ObSqlExpression p, p_end;
  ExprItem item_a, item_op, item_const;
  bool is_cond = false;
  /* 101 <= column <= 107 */
  item_a.type_ = T_REF_COLUMN;
  item_a.value_.cell_.tid = 123;
  item_a.value_.cell_.cid = 102;
  item_op.type_ = T_OP_LT;
  item_op.value_.int_ = 2;  /* 2 operands */
  item_const.type_ = T_INT;
  item_const.value_.int_ = 107;
  ASSERT_EQ(OB_SUCCESS, p.add_expr_item(item_a));
  ASSERT_EQ(OB_SUCCESS, p.add_expr_item(item_const));
  ASSERT_EQ(OB_SUCCESS, p.add_expr_item(item_op));
  ASSERT_EQ(OB_SUCCESS, p.add_expr_item_end());
  ASSERT_EQ(OB_SUCCESS, p.is_simple_condition(is_cond));
  ASSERT_EQ(true, is_cond);


  item_a.type_ = T_REF_COLUMN;
  item_a.value_.cell_.tid = 123;
  item_a.value_.cell_.cid = 102;
  item_op.type_ = T_OP_GE;
  item_op.value_.int_ = 2;  /* 2 operands */
  item_const.type_ = T_INT;
  item_const.value_.int_ = 101;
  ASSERT_EQ(OB_SUCCESS, p_end.add_expr_item(item_a));
  ASSERT_EQ(OB_SUCCESS, p_end.add_expr_item(item_const));
  ASSERT_EQ(OB_SUCCESS, p_end.add_expr_item(item_op));
  ASSERT_EQ(OB_SUCCESS, p_end.add_expr_item_end());
  ASSERT_EQ(OB_SUCCESS, p_end.is_simple_condition(is_cond));
  ASSERT_EQ(true, is_cond);

  scan.add_filter(p);
  scan.add_filter(p_end);
#endif
  scan.set_table(test::ObFakeTable::TABLE_ID);
  scan.set_rowkey_info(rowkey_info);
  scan.add_output_column(ExprGen::create_expr_by_id(1));

  EXPECT_CALL(async, scan(_,_,_,_))
    .Times(AtLeast(1))
    .WillRepeatedly(Invoke(callback_scan_async));

  EXPECT_CALL(async, get_session_next(_,_,_,_,_))
    .Times(AtLeast(1))
    .WillRepeatedly(Invoke(callback_session_async));




  ASSERT_TRUE(OB_SUCCESS == scan.init(&location_proxy, &async));
  ASSERT_TRUE(OB_SUCCESS == scan.open());

  const ObRow * cur_row = NULL;
  while(1)
  {
    int ret = OB_SUCCESS;

    TBSYS_LOG(INFO, "get_next_row() - begin");
    if (OB_ITER_END == (ret = scan.get_next_row(cur_row)))
    {
      TBSYS_LOG(INFO, "get_next_row() - iter_end");
      break;
    }
    else if (OB_SUCCESS != ret)
    {
      TBSYS_LOG(WARN, "get next row failed. ret=%d", ret);
      break;
    }
    /*TBSYS_LOG(DEBUG, "[id:%lu][key:%.*s][obj:dumped bellow]", cur_row->table_id_, cur_row->row_key_.length(),
      cur_row->row_key_.ptr());
      cur_row->value_.dump();
      */
    if (NULL != cur_row)
    {
      TBSYS_LOG(INFO, "row info:[SEE_DEBUG_LEVEL]");
      cur_row->dump();
    }
    else
    {
      TBSYS_LOG(WARN, "no current row");
    }
    TBSYS_LOG(INFO, "get_next_row() - end");
  }
  TBSYS_LOG(INFO, "scannnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnning - terminatet");
  //sleep(10);

  scan.close();

  usleep(1000 * 1000 * 2);
  TBSYS_LOG(INFO, "( request sent )");
  transport->stop();
  test_root_server.~MockServerRunner();
  root_server_thread.join();
}
TEST_F(TestRpcStub, test_scan_servers) 
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;

  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  ObMergerTabletLocationList list;
  
	ObServer chunk_server;
  chunk_server.set_ipv4_addr(addr, MockChunkServer::CHUNK_SERVER_PORT);

  ObTabletLocation addr;
  //addr.tablet_id_ = 100;
  addr.chunkserver_ = chunk_server;

  list.add(addr); 
  list.add(addr); 
  list.add(addr); 

  // start root server
  MockChunkServer server;
  MockServerRunner test_chunk_server(server);
  tbsys::CThread chunk_server_thread;
  chunk_server_thread.start(&test_chunk_server, NULL); 
  sleep(2); 

  ObScanParam param;
  ObCellInfo cell;
  ObRange range;
  ObString name;
  ObScanner scanner;

  param.set(1, name, range);
  EXPECT_TRUE(OB_SUCCESS == stub.scan(timeout, chunk_server, param, scanner));
  EXPECT_TRUE(!scanner.is_empty());
  
  uint64_t count = 0;
  ObScannerIterator iter;
  for (iter = scanner.begin(); iter != scanner.end(); ++iter)
  {
    EXPECT_TRUE(OB_SUCCESS == iter.get_cell(cell));
    //EXPECT_TRUE(cell.column_id_ == count);
    printf("client:%.*s\n", cell.row_key_.length(), cell.row_key_.ptr());
    ++count;
  }
  // return 10 cells
  EXPECT_TRUE(count == 10);
	ObMergerTabletLocation succ_addr;
  bool update = false;
  EXPECT_TRUE(OB_SUCCESS == stub.scan(timeout, list, param, succ_addr, scanner, update));
  EXPECT_TRUE(!scanner.is_empty());
  EXPECT_TRUE(update == false);
  for (iter = scanner.begin(); iter != scanner.end(); ++iter)
  {
    EXPECT_TRUE(OB_SUCCESS == iter.get_cell(cell));
    printf("client:%.*s\n", cell.row_key_.length(), cell.row_key_.ptr());
  }
  
  transport.stop();
  server.stop();
  sleep(10);
}
TEST_F(TestGetRequestEvent, test_get)
{
  ObMergerRpcStub stub;
  ThreadSpecificBuffer buffer;
  ObPacketFactory factory;
  tbnet::Transport transport;
  tbnet::DefaultPacketStreamer streamer; 
  streamer.setPacketFactory(&factory);
  transport.start();
  ObClientManager client_manager;

  EXPECT_TRUE(OB_SUCCESS == client_manager.initialize(&transport, &streamer));
  EXPECT_TRUE(OB_SUCCESS == stub.init(&buffer, &client_manager));

  ObServer root_server;
  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);
  ObServer update_server;
  update_server.set_ipv4_addr(addr, MockUpdateServer::UPDATE_SERVER_PORT);
  
  ObServer merge_server;
  merge_server.set_ipv4_addr(addr, 10256);
  ObMergerRpcProxy proxy(3, timeout, update_server);

  root_server.set_ipv4_addr(addr, MockRootServer::ROOT_SERVER_PORT);
  ObMergerRootRpcProxy rpc(0, timeout, root_server);
  EXPECT_TRUE(OB_SUCCESS == rpc.init(&stub));
  
  ObTabletLocationCache * location = new ObMergerTabletLocationCache;
  EXPECT_TRUE(NULL != location);
  EXPECT_TRUE(OB_SUCCESS == location->init(50000 * 5, 1000, 10000));
  
  ObMergerLocationCacheProxy cache(merge_server, &rpc, location);

  // init tablet cache 
  char temp[256] = "";
  char temp_end[256] = "";
  ObServer server;
  const uint64_t START_ROW = 100L;
  const uint64_t MAX_ROW = 300L;
  for (uint64_t i = START_ROW; i < MAX_ROW - 100; i += 100)
  {
    server.set_ipv4_addr(addr, MockChunkServer::CHUNK_SERVER_PORT);
    ObTabletLocation addr(i, server);

    ObTabletLocationList list;
    EXPECT_TRUE(OB_SUCCESS == list.add(addr));
    EXPECT_TRUE(OB_SUCCESS == list.add(addr));
    EXPECT_TRUE(OB_SUCCESS == list.add(addr));

    snprintf(temp, 100, "row_%lu", i);
    snprintf(temp_end, 100, "row_%lu", i + 100);
    ObString start_key(100, strlen(temp), temp);
    ObString end_key(100, strlen(temp_end), temp_end);

    ObRange range;
    range.table_id_ = 234;
    range.start_key_ = start_key;
    range.end_key_ = end_key;
    list.set_timestamp(tbsys::CTimeUtil::getTime()); 
    EXPECT_TRUE(OB_SUCCESS == location->set(range, list));
  }

  ObMergerTabletLocation succ_addr;
  ObTabletLocationList list;
  EXPECT_TRUE(OB_SUCCESS == proxy.init(&stub, &cache, NULL));

  // start root server
  MockRootServer root;
  tbsys::CThread root_server_thread;
  MockServerRunner test_root_server(root);
  root_server_thread.start(&test_root_server, NULL); 

  // start chunk server
  MockChunkServer chunk;
  tbsys::CThread chunk_server_thread;
  MockServerRunner test_chunk_server(chunk);
  chunk_server_thread.start(&test_chunk_server, NULL); 
  sleep(2);

  ObMergerAsyncRpcStub async;
  ObMergerLocationCacheProxy location_proxy(root_server, &rpc, location);
  ObGetRequestEvent request(&location_proxy, &async);
  
  ObGetParam get_param;
  ObCellInfo cell;
  ObString row_key;
  snprintf(temp, 100, "row_101");
  row_key.assign(temp, strlen(temp));
  cell.table_id_ = 234;
  cell.column_id_ = 111;
  cell.row_key_ = row_key;
  // add same cells
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  EXPECT_TRUE(OB_SUCCESS == get_param.add_cell(cell));
  
  // not init
  EXPECT_TRUE(OB_SUCCESS != request.set_request_param(get_param, timeout));
  EXPECT_TRUE(OB_SUCCESS != request.wait(timeout));
  
  EXPECT_TRUE(OB_SUCCESS == async.init(&buffer, &client_manager));
  EXPECT_TRUE(OB_SUCCESS == request.init(100, 10));
  EXPECT_TRUE(OB_SUCCESS == request.set_request_param(get_param, timeout));
  EXPECT_TRUE(OB_SUCCESS == request.wait(timeout));
  
  uint64_t count = 0;
  ObScannerIterator iter;
  ObCellInfo * cell_info = NULL;
  int ret = OB_SUCCESS;
  while (OB_ITER_END != (ret = request.next_cell()))
  {
    EXPECT_TRUE(OB_SUCCESS == ret);
    EXPECT_TRUE(OB_SUCCESS == request.get_cell(&cell_info));
    EXPECT_TRUE(cell_info != NULL);
    printf("client:%.*s\n", cell_info->row_key_.length(), cell_info->row_key_.ptr());
    ++count;
  }
  EXPECT_TRUE(OB_SUCCESS == request.reset());

  root.stop();
  chunk.stop();
  sleep(3);
  transport.stop();

  if (location != NULL)
  {
    delete location;
    location = NULL;
  }
}