3513 lines
		
	
	
		
			102 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			3513 lines
		
	
	
		
			102 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 RS
 | 
						|
 | 
						|
#include <gtest/gtest.h>
 | 
						|
#include <gmock/gmock.h>
 | 
						|
#include <time.h>
 | 
						|
#include "share/backup/ob_tenant_archive_round.h"
 | 
						|
#include "share/backup/ob_archive_checkpoint.h"
 | 
						|
#include "share/backup/ob_tenant_archive_mgr.h"
 | 
						|
 | 
						|
using namespace oceanbase;
 | 
						|
using namespace common;
 | 
						|
using namespace share;
 | 
						|
 | 
						|
class ArchiveCheckpointerTest : public testing::Test
 | 
						|
{
 | 
						|
public:
 | 
						|
  ArchiveCheckpointerTest() {}
 | 
						|
  virtual ~ArchiveCheckpointerTest(){}
 | 
						|
  virtual void SetUp() {};
 | 
						|
  virtual void TearDown() {}
 | 
						|
  virtual void TestBody() {}
 | 
						|
 | 
						|
  const uint64_t TENANT_ID    = 1002UL;
 | 
						|
  const int64_t DEST_ID       = 1001L;
 | 
						|
  const int64_t DEST_NO       = 0L;
 | 
						|
  const int64_t ROUND_ID      = 1L;
 | 
						|
  const int64_t ONE_MINUTE    = 60 * 1000 * 1000L;
 | 
						|
 | 
						|
  // return unit: us
 | 
						|
  int64_t convert_timestr_2_timestamp(const ObString &time_str)
 | 
						|
  {
 | 
						|
    const int64_t ONE_SECOND_US = 1000 * 1000;
 | 
						|
    struct tm timeinfo;
 | 
						|
    memset(&timeinfo, 0, sizeof(timeinfo));
 | 
						|
    strptime(time_str.ptr(), "%Y-%m-%d %H:%M:%S", &timeinfo);
 | 
						|
    time_t timestamp = mktime(&timeinfo);
 | 
						|
    return timestamp * ONE_SECOND_US;
 | 
						|
  }
 | 
						|
 | 
						|
  uint64_t convert_timestr_2_scn(const ObString &time_str)
 | 
						|
  {
 | 
						|
    int64_t ts = convert_timestr_2_timestamp(time_str);
 | 
						|
    return static_cast<uint64_t>(ts) * 1000;
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_basic_round(ObTenantArchiveRoundAttr &round)
 | 
						|
  {
 | 
						|
    round.key_.tenant_id_ = TENANT_ID;
 | 
						|
    round.key_.dest_no_ = DEST_NO;
 | 
						|
    round.incarnation_ = OB_START_INCARNATION;
 | 
						|
    round.dest_id_ = DEST_ID;
 | 
						|
    round.round_id_ = ROUND_ID;
 | 
						|
    // round.state_
 | 
						|
    round.start_scn_ = share::SCN::min_scn();
 | 
						|
    round.checkpoint_scn_ = share::SCN::min_scn();
 | 
						|
    round.max_scn_ = share::SCN::min_scn();
 | 
						|
    // round.compatible_
 | 
						|
    round.base_piece_id_ = 1;
 | 
						|
    round.used_piece_id_ = 1;
 | 
						|
    round.piece_switch_interval_ = ONE_MINUTE;
 | 
						|
    
 | 
						|
 | 
						|
    round.frozen_input_bytes_ = 0;
 | 
						|
    round.frozen_output_bytes_ = 0;
 | 
						|
    round.active_input_bytes_ = 0;
 | 
						|
    round.active_output_bytes_ = 0;
 | 
						|
    round.deleted_input_bytes_ = 0;
 | 
						|
    round.deleted_output_bytes_ = 0;
 | 
						|
 | 
						|
    round.path_.assign("file:///obbackup/archive");
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_prepare_round(ObTenantArchiveRoundAttr &round)
 | 
						|
  {
 | 
						|
    fill_basic_round(round);
 | 
						|
    round.state_.set_prepare();
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_beginning_round(ObTenantArchiveRoundAttr &round, const ObString &start_time)
 | 
						|
  {
 | 
						|
    fill_basic_round(round);
 | 
						|
 | 
						|
    uint64_t start_scn = convert_timestr_2_scn(start_time);
 | 
						|
 | 
						|
    round.start_scn_.convert_for_inner_table_field(start_scn);
 | 
						|
    round.checkpoint_scn_.convert_for_inner_table_field(start_scn);
 | 
						|
    round.max_scn_.convert_for_inner_table_field(start_scn);
 | 
						|
 | 
						|
    round.state_.set_beginning();
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_round(
 | 
						|
      const ObArchiveRoundState& state,
 | 
						|
      const ObString &start_time,
 | 
						|
      const ObString &checkpoint_time,
 | 
						|
      const ObString &max_time,
 | 
						|
      const int64_t used_piece_id,
 | 
						|
      const int64_t frozen_input_bytes,
 | 
						|
      const int64_t frozen_output_bytes,
 | 
						|
      const int64_t active_input_bytes,
 | 
						|
      const int64_t active_output_bytes,
 | 
						|
      const int64_t deleted_input_bytes,
 | 
						|
      const int64_t deleted_output_bytes,
 | 
						|
      ObTenantArchiveRoundAttr &round)
 | 
						|
  {
 | 
						|
    fill_beginning_round(round, start_time);
 | 
						|
 | 
						|
    round.state_ = state;
 | 
						|
    round.checkpoint_scn_.convert_for_logservice(convert_timestr_2_scn(checkpoint_time));
 | 
						|
    round.max_scn_.convert_for_logservice(convert_timestr_2_scn(max_time));
 | 
						|
    round.used_piece_id_ = used_piece_id;
 | 
						|
 | 
						|
    round.frozen_input_bytes_ = frozen_input_bytes;
 | 
						|
    round.frozen_output_bytes_ = frozen_output_bytes;
 | 
						|
    round.active_input_bytes_ = active_input_bytes;
 | 
						|
    round.active_output_bytes_ = active_output_bytes;
 | 
						|
    round.deleted_input_bytes_ = deleted_input_bytes;
 | 
						|
    round.deleted_output_bytes_ = deleted_output_bytes;
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_new_round(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObArchiveRoundState& state,
 | 
						|
      const ObString &checkpoint_time,
 | 
						|
      const ObString &max_time,
 | 
						|
      const int64_t used_piece_id,
 | 
						|
      const int64_t frozen_input_bytes,
 | 
						|
      const int64_t frozen_output_bytes,
 | 
						|
      const int64_t active_input_bytes,
 | 
						|
      const int64_t active_output_bytes,
 | 
						|
      const int64_t deleted_input_bytes,
 | 
						|
      const int64_t deleted_output_bytes,
 | 
						|
      ObTenantArchiveRoundAttr &new_round)
 | 
						|
  {
 | 
						|
    new_round.deep_copy_from(old_round);
 | 
						|
 | 
						|
    new_round.state_ = state;
 | 
						|
    new_round.checkpoint_scn_.convert_for_logservice(convert_timestr_2_scn(checkpoint_time));
 | 
						|
    new_round.max_scn_.convert_for_logservice(convert_timestr_2_scn(max_time));
 | 
						|
    new_round.used_piece_id_ = used_piece_id;
 | 
						|
 | 
						|
    new_round.frozen_input_bytes_ = frozen_input_bytes;
 | 
						|
    new_round.frozen_output_bytes_ = frozen_output_bytes;
 | 
						|
    new_round.active_input_bytes_ = active_input_bytes;
 | 
						|
    new_round.active_output_bytes_ = active_output_bytes;
 | 
						|
    new_round.deleted_input_bytes_ = deleted_input_bytes;
 | 
						|
    new_round.deleted_output_bytes_ = deleted_output_bytes;
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_piece(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round,
 | 
						|
      const int64_t piece_id,
 | 
						|
      const ObString &checkpoint_time,
 | 
						|
      const ObString &max_time,
 | 
						|
      const int64_t input_bytes,
 | 
						|
      const int64_t output_bytes,
 | 
						|
      const ObArchivePieceStatus &status,
 | 
						|
      const ObBackupFileStatus::STATUS file_status,
 | 
						|
      ObTenantArchivePieceAttr &piece)
 | 
						|
  {
 | 
						|
    piece.key_.tenant_id_ = old_round.key_.tenant_id_;
 | 
						|
    piece.key_.dest_id_ = old_round.dest_id_;
 | 
						|
    piece.key_.round_id_ = old_round.round_id_;
 | 
						|
    piece.key_.piece_id_ = piece_id;
 | 
						|
    piece.incarnation_ = old_round.incarnation_;
 | 
						|
    piece.dest_no_ = old_round.key_.dest_no_;
 | 
						|
 | 
						|
    ObTenantArchiveMgr::decide_piece_start_scn(old_round.start_scn_, old_round.base_piece_id_, old_round.piece_switch_interval_, piece_id, piece.start_scn_);
 | 
						|
    piece.checkpoint_scn_.convert_for_logservice(convert_timestr_2_scn(checkpoint_time));
 | 
						|
    piece.max_scn_.convert_for_logservice(convert_timestr_2_scn(max_time));
 | 
						|
    ObTenantArchiveMgr::decide_piece_end_scn(old_round.start_scn_, old_round.base_piece_id_, old_round.piece_switch_interval_, piece_id, piece.end_scn_);
 | 
						|
 | 
						|
    piece.input_bytes_ = input_bytes;
 | 
						|
    piece.output_bytes_ = output_bytes;
 | 
						|
    piece.status_ = status;
 | 
						|
    piece.file_status_ = file_status;
 | 
						|
 | 
						|
    piece.path_ = old_round.path_;
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_not_archive_ls(ObLSDestRoundSummary &summary, const int64_t ls_id)
 | 
						|
  {
 | 
						|
    int ret = OB_SUCCESS;
 | 
						|
    ObArchiveLSPieceSummary piece_summary;
 | 
						|
    piece_summary.tenant_id_ = TENANT_ID;
 | 
						|
    piece_summary.ls_id_ = ObLSID(ls_id);
 | 
						|
    piece_summary.is_archiving_ = false;
 | 
						|
    piece_summary.is_deleted_ = true;
 | 
						|
    piece_summary.round_id_ = 0;
 | 
						|
 | 
						|
    ret = summary.add_one_piece(piece_summary);
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_archive_ls_piece(
 | 
						|
      const int64_t ls_id,
 | 
						|
      const bool is_deleted,
 | 
						|
      const int64_t piece_id,
 | 
						|
      const ObArchiveRoundState& state,
 | 
						|
      const ObString &start_time,
 | 
						|
      const ObString &checkpoint_time,
 | 
						|
      const uint64_t min_lsn,
 | 
						|
      const uint64_t max_lsn,
 | 
						|
      const int64_t input_bytes,
 | 
						|
      const int64_t output_bytes,
 | 
						|
      ObArchiveLSPieceSummary &piece_summary)
 | 
						|
  {
 | 
						|
    piece_summary.tenant_id_ = TENANT_ID;
 | 
						|
    piece_summary.ls_id_ = ObLSID(ls_id);
 | 
						|
    piece_summary.is_archiving_ = true;
 | 
						|
    piece_summary.is_deleted_ = is_deleted;
 | 
						|
 | 
						|
    piece_summary.dest_id_ = DEST_ID;
 | 
						|
    piece_summary.round_id_ = ROUND_ID;
 | 
						|
    piece_summary.piece_id_ = piece_id;
 | 
						|
    piece_summary.incarnation_ = OB_START_INCARNATION;
 | 
						|
    piece_summary.state_ = state;
 | 
						|
 | 
						|
    piece_summary.start_scn_.convert_for_logservice(convert_timestr_2_scn(start_time));
 | 
						|
    piece_summary.checkpoint_scn_.convert_for_logservice(convert_timestr_2_scn(checkpoint_time));
 | 
						|
    piece_summary.min_lsn_ = min_lsn;
 | 
						|
    piece_summary.max_lsn_ = max_lsn;
 | 
						|
    piece_summary.input_bytes_ = input_bytes;
 | 
						|
    piece_summary.output_bytes_ = output_bytes;
 | 
						|
  }
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::GeneratedLSPiece gen_checkpoint_ls_piece(
 | 
						|
      const int64_t ls_id,
 | 
						|
      const ObString &start_time,
 | 
						|
      const ObString &checkpoint_time,
 | 
						|
      const uint64_t min_lsn,
 | 
						|
      const uint64_t max_lsn,
 | 
						|
      const int64_t input_bytes,
 | 
						|
      const int64_t output_bytes)
 | 
						|
  {
 | 
						|
    ObDestRoundCheckpointer::GeneratedLSPiece piece;
 | 
						|
    piece.ls_id_ = ObLSID(ls_id);
 | 
						|
    piece.start_scn_.convert_for_logservice(convert_timestr_2_scn(start_time));
 | 
						|
    piece.checkpoint_scn_.convert_for_logservice(convert_timestr_2_scn(checkpoint_time));
 | 
						|
    piece.min_lsn_ = min_lsn;
 | 
						|
    piece.max_lsn_ = max_lsn;
 | 
						|
    piece.input_bytes_ = input_bytes;
 | 
						|
    piece.output_bytes_ = output_bytes;
 | 
						|
    return piece;
 | 
						|
  }
 | 
						|
 | 
						|
  void fill_basic_round_summary(ObDestRoundSummary &summary)
 | 
						|
  {
 | 
						|
    summary.tenant_id_ = TENANT_ID;
 | 
						|
    summary.dest_id_ = DEST_ID;
 | 
						|
    summary.round_id_ = ROUND_ID;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  void fill_empty_summary(ObDestRoundSummary &summary)
 | 
						|
  {
 | 
						|
    fill_basic_round_summary(summary);
 | 
						|
 | 
						|
    ObLSDestRoundSummary ls_summary1;
 | 
						|
    fill_not_archive_ls(ls_summary1, 1001);
 | 
						|
 | 
						|
    ObLSDestRoundSummary ls_summary2;
 | 
						|
    fill_not_archive_ls(ls_summary2, 1002);
 | 
						|
 | 
						|
    summary.add_ls_dest_round_summary(ls_summary1);
 | 
						|
    summary.add_ls_dest_round_summary(ls_summary2);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  int compare_two_rounds(const ObTenantArchiveRoundAttr &round1, const ObTenantArchiveRoundAttr &round2)
 | 
						|
  {
 | 
						|
    #define CMP_VALUE(field)  \
 | 
						|
    if (OB_SUCC(ret)) { \
 | 
						|
      if (round1.field##_ != round2.field##_) { \
 | 
						|
        ret = OB_ERR_UNEXPECTED;  \
 | 
						|
        LOG_WARN("not equal", K(ret), K_(round1.field), K_(round2.field)); \
 | 
						|
      } \
 | 
						|
    }
 | 
						|
 | 
						|
    int ret = OB_SUCCESS;
 | 
						|
    CMP_VALUE(key);
 | 
						|
    CMP_VALUE(incarnation);
 | 
						|
    CMP_VALUE(dest_id);
 | 
						|
    CMP_VALUE(round_id);
 | 
						|
    CMP_VALUE(state);
 | 
						|
    CMP_VALUE(start_scn);
 | 
						|
    CMP_VALUE(checkpoint_scn);
 | 
						|
    CMP_VALUE(max_scn);
 | 
						|
    CMP_VALUE(compatible);
 | 
						|
    CMP_VALUE(base_piece_id);
 | 
						|
    CMP_VALUE(used_piece_id);
 | 
						|
    CMP_VALUE(piece_switch_interval);
 | 
						|
    CMP_VALUE(frozen_input_bytes);
 | 
						|
    CMP_VALUE(frozen_output_bytes);
 | 
						|
    CMP_VALUE(active_input_bytes);
 | 
						|
    CMP_VALUE(active_output_bytes);
 | 
						|
    CMP_VALUE(deleted_input_bytes);
 | 
						|
    CMP_VALUE(deleted_output_bytes);
 | 
						|
    CMP_VALUE(path);
 | 
						|
 | 
						|
    #undef CMP_VALUE
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  int compare_two_pieces(const ObTenantArchivePieceAttr &piece1, const ObTenantArchivePieceAttr &piece2)
 | 
						|
  {
 | 
						|
    #define CMP_VALUE(field)  \
 | 
						|
    if (OB_SUCC(ret)) { \
 | 
						|
      if (piece1.field##_ != piece2.field##_) { \
 | 
						|
        ret = OB_ERR_UNEXPECTED;  \
 | 
						|
        LOG_WARN("not equal", K(ret), K_(piece1.field), K_(piece2.field)); \
 | 
						|
      } \
 | 
						|
    }
 | 
						|
 | 
						|
    int ret = OB_SUCCESS;
 | 
						|
    CMP_VALUE(key);
 | 
						|
    CMP_VALUE(incarnation);
 | 
						|
    CMP_VALUE(dest_no);
 | 
						|
    CMP_VALUE(start_scn);
 | 
						|
    CMP_VALUE(checkpoint_scn);
 | 
						|
    CMP_VALUE(max_scn);
 | 
						|
    CMP_VALUE(end_scn);
 | 
						|
    CMP_VALUE(compatible);
 | 
						|
    CMP_VALUE(input_bytes);
 | 
						|
    CMP_VALUE(output_bytes);
 | 
						|
    CMP_VALUE(status);
 | 
						|
    CMP_VALUE(file_status);
 | 
						|
    CMP_VALUE(path);
 | 
						|
 | 
						|
    #undef CMP_VALUE
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  int compare_two_checkpoint_pieces(const ObDestRoundCheckpointer::GeneratedPiece &piece1, const ObDestRoundCheckpointer::GeneratedPiece &piece2)
 | 
						|
  {
 | 
						|
    #define CMP_VALUE(field)  \
 | 
						|
    if (OB_SUCC(ret)) { \
 | 
						|
      if (ls_piece1.field##_ != ls_piece2.field##_) { \
 | 
						|
        ret = OB_ERR_UNEXPECTED;  \
 | 
						|
        LOG_WARN("not equal", K(ret), K_(ls_piece1.field), K_(ls_piece2.field)); \
 | 
						|
      } \
 | 
						|
    }
 | 
						|
 | 
						|
    int ret = OB_SUCCESS;
 | 
						|
    if (OB_FAIL(compare_two_pieces(piece1.piece_info_, piece2.piece_info_))) {
 | 
						|
      LOG_WARN("piece not equal", K(ret), K_(piece1.piece_info), K_(piece2.piece_info));
 | 
						|
    }
 | 
						|
 | 
						|
    if (OB_SUCC(ret)) {
 | 
						|
      if (piece1.ls_piece_list_.count() != piece2.ls_piece_list_.count()) {
 | 
						|
        ret = OB_ERR_UNEXPECTED;
 | 
						|
        LOG_WARN("invalid ls piece list count", K(ret), K_(piece1.ls_piece_list), K_(piece2.ls_piece_list));
 | 
						|
      } else {
 | 
						|
        for (int64_t i = 0; OB_SUCC(ret) && i < piece1.ls_piece_list_.count(); i++) {
 | 
						|
          const ObDestRoundCheckpointer::GeneratedLSPiece &ls_piece1 = piece1.ls_piece_list_.at(i);
 | 
						|
 | 
						|
          const ObDestRoundCheckpointer::GeneratedLSPiece *find_piece;
 | 
						|
          int64_t j = 0;
 | 
						|
          for (; j < piece2.ls_piece_list_.count(); j++) {
 | 
						|
            const ObDestRoundCheckpointer::GeneratedLSPiece &ls_piece = piece2.ls_piece_list_.at(i);
 | 
						|
            if (ls_piece1.ls_id_ == ls_piece.ls_id_) {
 | 
						|
              find_piece = &ls_piece;
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          if (j == piece2.ls_piece_list_.count()) {
 | 
						|
            ret = OB_ERR_UNEXPECTED;
 | 
						|
            LOG_WARN("cannot find ls piece", K(ret), K(ls_piece1), K_(piece2.ls_piece_list));
 | 
						|
          } else {
 | 
						|
            const ObDestRoundCheckpointer::GeneratedLSPiece &ls_piece2 = *find_piece;
 | 
						|
            CMP_VALUE(ls_id);
 | 
						|
            CMP_VALUE(start_scn);
 | 
						|
            CMP_VALUE(checkpoint_scn);
 | 
						|
            CMP_VALUE(min_lsn);
 | 
						|
            CMP_VALUE(max_lsn);
 | 
						|
            CMP_VALUE(input_bytes);
 | 
						|
            CMP_VALUE(output_bytes);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    #undef CMP_VALUE
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
static int64_t g_call_cnt = 0;
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_prepare)
 | 
						|
{
 | 
						|
  class MockRoundHandler final : public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      // should not come here
 | 
						|
      g_call_cnt++;
 | 
						|
      return OB_ERR_UNEXPECTED; 
 | 
						|
    }
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        // should not come here
 | 
						|
        g_call_cnt++;
 | 
						|
        return OB_ERR_UNEXPECTED; 
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        // should not come here
 | 
						|
        g_call_cnt++;
 | 
						|
        return OB_ERR_UNEXPECTED; 
 | 
						|
      };
 | 
						|
 | 
						|
  // old round's status is PREPARE,checkpoint is not allowed.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_prepare_round(old_round);
 | 
						|
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  fill_empty_summary(summary);
 | 
						|
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN scn;
 | 
						|
  (void)scn.convert_for_logservice(1000);
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_beginning_01)
 | 
						|
{
 | 
						|
  // old round's status is BEGINNING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_beginning_round(old_round, "2022-01-01 00:00:30");
 | 
						|
 | 
						|
  // 2 log streams, one is archiving, the other has not started archive.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 has not started archive.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  fill_not_archive_ls(ls_1001, 1001);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // As long as one log stream is not archived, the status will not advance.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      // should not come here.
 | 
						|
      g_call_cnt++;
 | 
						|
      return OB_ERR_UNEXPECTED; 
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        // should not come here.
 | 
						|
        g_call_cnt++;
 | 
						|
        return OB_ERR_UNEXPECTED;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        // should not come here.
 | 
						|
        g_call_cnt++;
 | 
						|
        return OB_ERR_UNEXPECTED;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:50"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_beginning_02)
 | 
						|
{
 | 
						|
  // old round's status is BEGINNING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_beginning_round(old_round, "2022-01-01 00:00:30");
 | 
						|
 | 
						|
  // 2 log streams, one is archiving, the other is INTERRUPTED.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is INTERRUPTED.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::interrupted(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // As long as one log stream is interrupted, the round's status will turn to INTERRUPTED.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::interrupted(),
 | 
						|
        "2022-01-01 00:00:30",
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        1,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:30",
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          100,
 | 
						|
          10,
 | 
						|
          ObArchivePieceStatus::active(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          0);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::interrupted(),
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          1,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          100,
 | 
						|
          10,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:50"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_beginning_03)
 | 
						|
{
 | 
						|
  // old round's status is BEGINNING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_beginning_round(old_round, "2022-01-01 00:00:30");
 | 
						|
 | 
						|
  // 2 log streams are archiving.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // All log streams are archiving, status turn to DOING.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::doing(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        1,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          ObArchivePieceStatus::active(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          0,
 | 
						|
          2000,
 | 
						|
          200,
 | 
						|
          20);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::doing(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          1,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:45"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_01)
 | 
						|
{
 | 
						|
  // old round's status is DOING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:35",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams are archiving.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // All log streams are archiving, the next status is DOING.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::doing(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        1,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          ObArchivePieceStatus::active(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          0,
 | 
						|
          2000,
 | 
						|
          200,
 | 
						|
          20);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::doing(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          1,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:45"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_02)
 | 
						|
{
 | 
						|
  // old round's status is DOING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:00:35",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams are archiving.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1/* piece id */,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00"/* start time */,
 | 
						|
    "2022-01-01 00:01:00"/* checkpoint time*/,
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1/* piece id */,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00"/* start time */,
 | 
						|
    "2022-01-01 00:01:00"/* checkpoint time*/,
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  
 | 
						|
  ObArchiveLSPieceSummary piece_1002_2;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    2/* piece id */,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:01:00"/* start time */,
 | 
						|
    "2022-01-01 00:01:30"/* checkpoint time*/,
 | 
						|
    1000,
 | 
						|
    2000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_2);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_2), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // All log streams are archiving, the next status is DOING.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::doing(),
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        "2022-01-01 00:01:30",
 | 
						|
        2,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        400,
 | 
						|
        40,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece_1;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        "2022-01-01 00:01:00",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece_1);
 | 
						|
      
 | 
						|
      ObTenantArchivePieceAttr expect_piece_2;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        2, 
 | 
						|
        "2022-01-01 00:01:00",
 | 
						|
        "2022-01-01 00:01:30",
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
        expect_piece_2);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 2) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_1 = pieces.at(0);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_1, expect_piece_1))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_1), K(expect_piece_1));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_2 = pieces.at(1);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_2, expect_piece_2))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_2), K(expect_piece_2));
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        if (piece.piece_info_.key_.piece_id_ == 1) {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            1, 
 | 
						|
            "2022-01-01 00:00:50",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            300,
 | 
						|
            30,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
            1001,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            0,
 | 
						|
            2000,
 | 
						|
            200,
 | 
						|
            20);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            0,
 | 
						|
            1000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
          
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        } else {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            2, 
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:01:30",
 | 
						|
            100,
 | 
						|
            10,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:01:30",
 | 
						|
            1000,
 | 
						|
            2000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
           expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        }
 | 
						|
        
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::doing(),
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          "2022-01-01 00:01:30",
 | 
						|
          2,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          400,
 | 
						|
          40,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:50"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 4);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_03)
 | 
						|
{
 | 
						|
  // old round's status is DOING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:00:35",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams are archiving.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:01:00",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  
 | 
						|
  ObArchiveLSPieceSummary piece_1001_2;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    2,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:01:00",
 | 
						|
    "2022-01-01 00:01:30",
 | 
						|
    2000,
 | 
						|
    4000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_2);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_2), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:01:00",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  
 | 
						|
  ObArchiveLSPieceSummary piece_1002_2;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    2,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:01:00",
 | 
						|
    "2022-01-01 00:02:00",
 | 
						|
    1000,
 | 
						|
    2000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_2);
 | 
						|
  
 | 
						|
  ObArchiveLSPieceSummary piece_1002_3;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    3,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:02:00",
 | 
						|
    "2022-01-01 00:02:30",
 | 
						|
    2000,
 | 
						|
    3000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_3);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_2), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_3), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // All log streams are archiving, the next status is DOING.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::doing(),
 | 
						|
        "2022-01-01 00:01:30",
 | 
						|
        "2022-01-01 00:02:30",
 | 
						|
        3,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        400,
 | 
						|
        40,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece_1;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:01:00",
 | 
						|
        "2022-01-01 00:01:00",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::frozen(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece_1);
 | 
						|
      
 | 
						|
      ObTenantArchivePieceAttr expect_piece_2;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        2, 
 | 
						|
        "2022-01-01 00:01:30",
 | 
						|
        "2022-01-01 00:02:00",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece_2);
 | 
						|
      
 | 
						|
      ObTenantArchivePieceAttr expect_piece_3;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        3, 
 | 
						|
        "2022-01-01 00:02:00",
 | 
						|
        "2022-01-01 00:02:30",
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
        expect_piece_3);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 3) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_1 = pieces.at(0);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_1, expect_piece_1))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_1), K(expect_piece_1));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_2 = pieces.at(1);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_2, expect_piece_2))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_2), K(expect_piece_2));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_3 = pieces.at(2);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_3, expect_piece_3))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_3), K(expect_piece_3));
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        if (piece.piece_info_.key_.piece_id_ == 1) {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            1, 
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            300,
 | 
						|
            30,
 | 
						|
            ObArchivePieceStatus::frozen(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
            1001,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            0,
 | 
						|
            2000,
 | 
						|
            200,
 | 
						|
            20);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            0,
 | 
						|
            1000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
          
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        } else if (piece.piece_info_.key_.piece_id_ == 2) {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            2, 
 | 
						|
            "2022-01-01 00:01:30",
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            300,
 | 
						|
            30,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
            1001,
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:01:30",
 | 
						|
            2000,
 | 
						|
            4000,
 | 
						|
            200,
 | 
						|
            20);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            1000,
 | 
						|
            2000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        } else {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            3, 
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            "2022-01-01 00:02:30",
 | 
						|
            100,
 | 
						|
            10,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            "2022-01-01 00:02:30",
 | 
						|
            2000,
 | 
						|
            3000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        }
 | 
						|
        
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::doing(),
 | 
						|
          "2022-01-01 00:01:30",
 | 
						|
          "2022-01-01 00:02:30",
 | 
						|
          3,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          400,
 | 
						|
          40,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:03:00"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 5);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_04)
 | 
						|
{
 | 
						|
  // old round's status is DOING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:35",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams, one is archiving, the other has not started archive.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream is created after DOING status.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  fill_not_archive_ls(ls_1001, 1001);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // As long as one log stream is not archived, the status will retain.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      // should not come here.
 | 
						|
      g_call_cnt++;
 | 
						|
      return OB_ERR_UNEXPECTED; 
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        // should not come here.
 | 
						|
        g_call_cnt++;
 | 
						|
        return OB_ERR_UNEXPECTED;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        // should not come here.
 | 
						|
        g_call_cnt++;
 | 
						|
        return OB_ERR_UNEXPECTED;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:45"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_05)
 | 
						|
{
 | 
						|
  // old round's status is DOING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:35",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams, one is archiving, the other is INTERRUPTED.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is INTERRUPTED.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::interrupted(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:55",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // As long as one log stream is INTERRUPTED, the next status is INTERRUPTED.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::interrupted(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        1,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          ObArchivePieceStatus::active(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          0,
 | 
						|
          2000,
 | 
						|
          200,
 | 
						|
          20);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::interrupted(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          1,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:40"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
// Some log stream is deleted during archive.
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_06)
 | 
						|
{
 | 
						|
  // old round's status is DOING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing()/* status */,
 | 
						|
    "2022-01-01 00:00:30"/* start_time */,
 | 
						|
    "2022-01-01 00:00:35"/* checkpoint_time */,
 | 
						|
    "2022-01-01 00:00:40"/* max_time */,
 | 
						|
    1/* used_piece_id */,
 | 
						|
    0/* frozen_input_bytes */,
 | 
						|
    0/* frozen_output_bytes */,
 | 
						|
    100/* active_input_bytes */,
 | 
						|
    10/* active_output_bytes */,
 | 
						|
    0/* deleted_input_bytes */,
 | 
						|
    0/* deleted_output_bytes */,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 3 log streams, one is deleted.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001/* ls_id */,
 | 
						|
    false/* is_deleted */,
 | 
						|
    1/* piece_id */,
 | 
						|
    ObArchiveRoundState::doing()/* state */,
 | 
						|
    "2022-01-01 00:00:30"/* start_time */,
 | 
						|
    "2022-01-01 00:00:50"/* checkpoint_time */,
 | 
						|
    0/* min_lsn */,
 | 
						|
    2000/* max_lsn */,
 | 
						|
    200/* input_bytes */,
 | 
						|
    20/* output_bytes */,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002/* ls_id */,
 | 
						|
    false/* is_deleted */,
 | 
						|
    1/* piece_id */,
 | 
						|
    ObArchiveRoundState::doing()/* state */,
 | 
						|
    "2022-01-01 00:00:30"/* start_time */,
 | 
						|
    "2022-01-01 00:00:55"/* checkpoint_time */,
 | 
						|
    0/* min_lsn */,
 | 
						|
    1000/* max_lsn */,
 | 
						|
    100/* input_bytes */,
 | 
						|
    10/* output_bytes */,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1003 is deleted.
 | 
						|
  ObLSDestRoundSummary ls_1003;
 | 
						|
  ObArchiveLSPieceSummary piece_1003_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1003/* ls_id */,
 | 
						|
    true/* is_deleted */,
 | 
						|
    1/* piece_id */,
 | 
						|
    ObArchiveRoundState::doing()/* state */,
 | 
						|
    "2022-01-01 00:00:30"/* start_time */,
 | 
						|
    "2022-01-01 00:00:40"/* checkpoint_time */,
 | 
						|
    0/* min_lsn */,
 | 
						|
    1000/* max_lsn */,
 | 
						|
    100/* input_bytes */,
 | 
						|
    10/* output_bytes */,
 | 
						|
    piece_1003_1);
 | 
						|
  ASSERT_EQ(ls_1003.add_one_piece(piece_1003_1), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1003), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round,
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round,
 | 
						|
        ObArchiveRoundState::doing()/* state */,
 | 
						|
        "2022-01-01 00:00:50"/* checkpoint_time */,
 | 
						|
        "2022-01-01 00:00:55"/* max_time */,
 | 
						|
        1/* used_piece_id */,
 | 
						|
        0/* frozen_input_bytes */,
 | 
						|
        0/* frozen_output_bytes */,
 | 
						|
        400/* active_input_bytes */,
 | 
						|
        40/* active_output_bytes */,
 | 
						|
        0/* deleted_input_bytes */,
 | 
						|
        0/* deleted_output_bytes */,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round,
 | 
						|
        1/* piece_id */,
 | 
						|
        "2022-01-01 00:00:50"/* checkpoint_time */,
 | 
						|
        "2022-01-01 00:00:55"/* max_time */,
 | 
						|
        400/* input_bytes */,
 | 
						|
        40/* output_bytes */,
 | 
						|
        ObArchivePieceStatus::active()/* status */,
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE/* file_status */,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb =
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece)
 | 
						|
      {
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round,
 | 
						|
          1/* piece_id */,
 | 
						|
          "2022-01-01 00:00:50"/* checkpoint_time */,
 | 
						|
          "2022-01-01 00:00:55"/* max_time */,
 | 
						|
          400/* input_bytes */,
 | 
						|
          40/* output_bytes */,
 | 
						|
          ObArchivePieceStatus::active()/* status */,
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE/* file_status */,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001/* ls_id */,
 | 
						|
          "2022-01-01 00:00:30"/* start_time */,
 | 
						|
          "2022-01-01 00:00:50"/* checkpoint_time */,
 | 
						|
          0/* min_lsn */,
 | 
						|
          2000/* max_lsn */,
 | 
						|
          200/* input_bytes */,
 | 
						|
          20/* output_bytes */);
 | 
						|
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002/* ls_id */,
 | 
						|
          "2022-01-01 00:00:30"/* start_time */,
 | 
						|
          "2022-01-01 00:00:55"/* checkpoint_time */,
 | 
						|
          0/* min_lsn */,
 | 
						|
          1000/* max_lsn */,
 | 
						|
          100/* input_bytes */,
 | 
						|
          10/* output_bytes */);
 | 
						|
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1003 = test.gen_checkpoint_ls_piece(
 | 
						|
          1003/* ls_id */,
 | 
						|
          "2022-01-01 00:00:30"/* start_time */,
 | 
						|
          "2022-01-01 00:00:40"/* checkpoint_time */,
 | 
						|
          0/* min_lsn */,
 | 
						|
          1000/* max_lsn */,
 | 
						|
          100/* input_bytes */,
 | 
						|
          10/* output_bytes */);
 | 
						|
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1003);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb =
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round)
 | 
						|
      {
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round,
 | 
						|
          ObArchiveRoundState::doing()/* state */,
 | 
						|
          "2022-01-01 00:00:50"/* checkpoint_time */,
 | 
						|
          "2022-01-01 00:00:55"/* max_time */,
 | 
						|
          1/* used_piece_id */,
 | 
						|
          0/* frozen_input_bytes */,
 | 
						|
          0/* frozen_output_bytes */,
 | 
						|
          400/* active_input_bytes */,
 | 
						|
          40/* active_output_bytes */,
 | 
						|
          0/* deleted_input_bytes */,
 | 
						|
          0/* deleted_output_bytes */,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:59"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_doing_07)
 | 
						|
{
 | 
						|
  // old round's status is DOING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",   /* start time */
 | 
						|
    "2022-01-01 00:00:20",   /* checkpoint time */
 | 
						|
    "2022-01-01 00:00:30",   /* max time */
 | 
						|
    1,                       /* used piece id */
 | 
						|
    0,                       /* frozen_input_bytes */
 | 
						|
    0,                       /* frozen_output_bytes */
 | 
						|
    100,                     /* active_input_bytes */
 | 
						|
    10,                      /* active_output_bytes */
 | 
						|
    0,                       /* deleted_input_bytes */
 | 
						|
    0,                       /* deleted_output_bytes */
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams are archiving.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001,                           /* ls id */
 | 
						|
    false,                          /* is deleted */
 | 
						|
    1,                              /* piece id */
 | 
						|
    ObArchiveRoundState::doing(),   /* state */
 | 
						|
    "2022-01-01 00:00:00",          /* start time */
 | 
						|
    "2022-01-01 00:00:50",          /* checkpoint time */
 | 
						|
    0,                              /* min_lsn */
 | 
						|
    2000,                           /* max_lsn */
 | 
						|
    200,                            /* input_bytes */
 | 
						|
    20,                             /* output_bytes */
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002,                           /* ls id */
 | 
						|
    false,                          /* is deleted */
 | 
						|
    1,                              /* piece id */
 | 
						|
    ObArchiveRoundState::doing(),   /* state */
 | 
						|
    "2022-01-01 00:00:00",          /* start time */
 | 
						|
    "2022-01-01 00:00:40",          /* checkpoint time */
 | 
						|
    0,                              /* min_lsn */
 | 
						|
    1000,                           /* max_lsn */
 | 
						|
    100,                            /* input_bytes */
 | 
						|
    10,                             /* output_bytes */
 | 
						|
    piece_1002_1);
 | 
						|
 | 
						|
  ObArchiveLSPieceSummary piece_1002_2;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002,                           /* ls id */
 | 
						|
    false,                          /* is deleted */
 | 
						|
    2,                              /* piece id */
 | 
						|
    ObArchiveRoundState::doing(),   /* state */
 | 
						|
    "2022-01-01 00:01:00",          /* start time */
 | 
						|
    "2022-01-01 00:01:30",          /* checkpoint time */
 | 
						|
    1000,                           /* min_lsn */
 | 
						|
    2000,                           /* max_lsn */
 | 
						|
    100,                            /* input_bytes */
 | 
						|
    10,                             /* output_bytes */
 | 
						|
    piece_1002_2);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_2), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // All log streams are archiving, the next status is DOING.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round,
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round,
 | 
						|
        ObArchiveRoundState::doing(),   /* state */
 | 
						|
        "2022-01-01 00:00:40",          /* checkpoint_time */
 | 
						|
        "2022-01-01 00:01:30",          /* max_time */
 | 
						|
        2,                              /* used_piece_id */
 | 
						|
        0,                              /* frozen_input_bytes */
 | 
						|
        0,                              /* frozen_output_bytes */
 | 
						|
        400,                            /* active_input_bytes */
 | 
						|
        40,                             /* active_output_bytes */
 | 
						|
        0,                              /* deleted_input_bytes */
 | 
						|
        0,                              /* deleted_output_bytes */
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece_1;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round,
 | 
						|
        1,                                                    /* piece id */
 | 
						|
        "2022-01-01 00:00:40",                                /* checkpoint time */
 | 
						|
        "2022-01-01 00:00:50",                                /* max time */
 | 
						|
        300,                                                  /* input_bytes */
 | 
						|
        30,                                                   /* output_bytes */
 | 
						|
        ObArchivePieceStatus::active(),                       /* piece status */
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,    /* file status */
 | 
						|
        expect_piece_1);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece_2;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round,
 | 
						|
        2,                                                    /* piece id */
 | 
						|
        "2022-01-01 00:01:00",                                /* checkpoint time */
 | 
						|
        "2022-01-01 00:01:30",                                /* max time */
 | 
						|
        100,                                                  /* input_bytes */
 | 
						|
        10,                                                   /* output_bytes */
 | 
						|
        ObArchivePieceStatus::active(),                       /* piece status */
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,   /* file status */
 | 
						|
        expect_piece_2);
 | 
						|
 | 
						|
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 2) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_1 = pieces.at(0);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_1, expect_piece_1))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_1), K(expect_piece_1));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_2 = pieces.at(1);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_2, expect_piece_2))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_2), K(expect_piece_2));
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb =
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece)
 | 
						|
      {
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        if (piece.piece_info_.key_.piece_id_ == 1) {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round,
 | 
						|
            1,
 | 
						|
            "2022-01-01 00:00:40",
 | 
						|
            "2022-01-01 00:00:50",
 | 
						|
            300,
 | 
						|
            30,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
            1001,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:00:50",
 | 
						|
            0,
 | 
						|
            2000,
 | 
						|
            200,
 | 
						|
            20);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:00:40",
 | 
						|
            0,
 | 
						|
            1000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        } else {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round,
 | 
						|
            2,
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:01:30",
 | 
						|
            100,
 | 
						|
            10,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:01:30",
 | 
						|
            1000,
 | 
						|
            2000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
           expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        }
 | 
						|
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb =
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round)
 | 
						|
      {
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round,
 | 
						|
          ObArchiveRoundState::doing(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:01:30",
 | 
						|
          2,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          400,
 | 
						|
          40,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:45"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 4);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_stopping_01)
 | 
						|
{
 | 
						|
  // old round's status is STOPPING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::stopping(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams, one is archiving, the other is STOP.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is archiving.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is STOP.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::stop(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:55",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // checkpoint_scn will not advance after archive is STOPPPING. But, max_scn will always advance.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::stopping(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        1,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          ObArchivePieceStatus::active(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          0,
 | 
						|
          2000,
 | 
						|
          200,
 | 
						|
          20);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::stopping(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          1,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:02:00"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_stopping_02)
 | 
						|
{
 | 
						|
  // old round's status is STOPPING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::stopping(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams are STOP.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream is STOP.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::stop(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream is STOP.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::stop(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:55",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // All log streams are STOP, the next status is STOP.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::stop(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        1,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::frozen(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          ObArchivePieceStatus::frozen(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          0,
 | 
						|
          2000,
 | 
						|
          200,
 | 
						|
          20);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::stop(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          1,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:02:00"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_stopping_03)
 | 
						|
{
 | 
						|
  // old round's status is STOPPING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::stopping(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams, one is STOP, the other is created after STOPPING.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is created after STOPPING.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  fill_not_archive_ls(ls_1001, 1001);
 | 
						|
 | 
						|
  // log stream 1002 is STOP.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::stop(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:55",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // Although log stream 1001 has not archived, but is created after STOPPING. It will 
 | 
						|
  // not be considered.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::stop(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        1,
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        ObArchivePieceStatus::frozen(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          100,
 | 
						|
          10,
 | 
						|
          ObArchivePieceStatus::frozen(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::stop(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          1,
 | 
						|
          100,
 | 
						|
          10,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:02:00"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, in_stopping_04)
 | 
						|
{
 | 
						|
  // old round's status is STOPPING.
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::stopping(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams, one is STOP, the other is INTERRUPED.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is STOP.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::stop(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is INTERRUPTED.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::interrupted(),
 | 
						|
    "2022-01-01 00:00:30",
 | 
						|
    "2022-01-01 00:00:55",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  // Only all log streams have stopped archiving, the next status is STOP.
 | 
						|
  // Otherwise, it will be stuck in the STOPPING state.
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::stopping(),
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        1,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:40",
 | 
						|
        "2022-01-01 00:00:55",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 1) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        } else {
 | 
						|
          const ObTenantArchivePieceAttr &piece = pieces.at(0);
 | 
						|
          ret = test.compare_two_pieces(piece, expect_piece);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        test.fill_piece(
 | 
						|
          old_round, 
 | 
						|
          1, 
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          ObArchivePieceStatus::active(),
 | 
						|
          ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
          expect_piece.piece_info_);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
          1001,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          0,
 | 
						|
          2000,
 | 
						|
          200,
 | 
						|
          20);
 | 
						|
        
 | 
						|
        ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
          1002,
 | 
						|
          "2022-01-01 00:00:30",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          0,
 | 
						|
          1000,
 | 
						|
          100,
 | 
						|
          10);
 | 
						|
        
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
        expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::stopping(),
 | 
						|
          "2022-01-01 00:00:40",
 | 
						|
          "2022-01-01 00:00:55",
 | 
						|
          1,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          300,
 | 
						|
          30,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:40"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 3);
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(ArchiveCheckpointerTest, some_ls_interrupt_01)
 | 
						|
{
 | 
						|
  // old round's status is DOING
 | 
						|
  ObTenantArchiveRoundAttr old_round;
 | 
						|
  fill_round(
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:00:35",
 | 
						|
    "2022-01-01 00:00:40",
 | 
						|
    1,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    old_round);
 | 
						|
 | 
						|
  // 2 log streams, one is DOING, the other is INTERRUPED.
 | 
						|
  ObDestRoundSummary summary;
 | 
						|
  // log stream 1001 is DOING.
 | 
						|
  ObLSDestRoundSummary ls_1001;
 | 
						|
  ObArchiveLSPieceSummary piece_1001_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1001, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:00:50",
 | 
						|
    0,
 | 
						|
    2000,
 | 
						|
    200,
 | 
						|
    20,
 | 
						|
    piece_1001_1);
 | 
						|
  
 | 
						|
  ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS);
 | 
						|
 | 
						|
  // log stream 1002 is INTERRUPED.
 | 
						|
  ObLSDestRoundSummary ls_1002;
 | 
						|
  ObArchiveLSPieceSummary piece_1002_1;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    1,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:00:00",
 | 
						|
    "2022-01-01 00:01:00",
 | 
						|
    0,
 | 
						|
    1000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_1);
 | 
						|
  
 | 
						|
  ObArchiveLSPieceSummary piece_1002_2;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    2,
 | 
						|
    ObArchiveRoundState::doing(),
 | 
						|
    "2022-01-01 00:01:00",
 | 
						|
    "2022-01-01 00:02:00",
 | 
						|
    1000,
 | 
						|
    2000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_2);
 | 
						|
  
 | 
						|
  ObArchiveLSPieceSummary piece_1002_3;
 | 
						|
  fill_archive_ls_piece(
 | 
						|
    1002, 
 | 
						|
    false, 
 | 
						|
    3,
 | 
						|
    ObArchiveRoundState::interrupted(),
 | 
						|
    "2022-01-01 00:02:00",
 | 
						|
    "2022-01-01 00:02:30",
 | 
						|
    2000,
 | 
						|
    3000,
 | 
						|
    100,
 | 
						|
    10,
 | 
						|
    piece_1002_3);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_2), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(ls_1002.add_one_piece(piece_1002_3), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS);
 | 
						|
  ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS);
 | 
						|
 | 
						|
 | 
						|
  class MockRoundHandler final: public ObArchiveRoundHandler
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    int checkpoint_to(
 | 
						|
      const ObTenantArchiveRoundAttr &old_round, 
 | 
						|
      const ObTenantArchiveRoundAttr &new_round,
 | 
						|
      const common::ObIArray<ObTenantArchivePieceAttr> &pieces) override
 | 
						|
    {
 | 
						|
      int ret = OB_SUCCESS;
 | 
						|
      g_call_cnt++;
 | 
						|
      ArchiveCheckpointerTest test;
 | 
						|
      ObTenantArchiveRoundAttr expect_round;
 | 
						|
      test.fill_new_round(
 | 
						|
        old_round, 
 | 
						|
        ObArchiveRoundState::interrupted(),
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        "2022-01-01 00:02:30",
 | 
						|
        3,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        500,
 | 
						|
        50,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        expect_round);
 | 
						|
 | 
						|
      ObTenantArchivePieceAttr expect_piece_1;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        1, 
 | 
						|
        "2022-01-01 00:00:50",
 | 
						|
        "2022-01-01 00:01:00",
 | 
						|
        300,
 | 
						|
        30,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
        expect_piece_1);
 | 
						|
      
 | 
						|
      ObTenantArchivePieceAttr expect_piece_2;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        2, 
 | 
						|
        "2022-01-01 00:01:00",
 | 
						|
        "2022-01-01 00:02:00",
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
        expect_piece_2);
 | 
						|
      
 | 
						|
      ObTenantArchivePieceAttr expect_piece_3;
 | 
						|
      test.fill_piece(
 | 
						|
        old_round, 
 | 
						|
        3, 
 | 
						|
        "2022-01-01 00:02:00",
 | 
						|
        "2022-01-01 00:02:30",
 | 
						|
        100,
 | 
						|
        10,
 | 
						|
        ObArchivePieceStatus::active(),
 | 
						|
        ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
        expect_piece_3);
 | 
						|
 | 
						|
      
 | 
						|
      ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        if (pieces.count() != 3) {
 | 
						|
          ret = OB_ERR_UNEXPECTED;
 | 
						|
          LOG_WARN("invalid pieces count", K(ret), K(pieces));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_1 = pieces.at(0);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_1, expect_piece_1))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_1), K(expect_piece_1));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_2 = pieces.at(1);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_2, expect_piece_2))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_2), K(expect_piece_2));
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (OB_SUCC(ret)) {
 | 
						|
        const ObTenantArchivePieceAttr &piece_3 = pieces.at(2);
 | 
						|
        if (OB_FAIL(test.compare_two_pieces(piece_3, expect_piece_3))) {
 | 
						|
          LOG_WARN("not equal pieces", K(ret), K(piece_3), K(expect_piece_3));
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return ret;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObDestRoundCheckpointer::GeneratedPiece expect_piece;
 | 
						|
        if (piece.piece_info_.key_.piece_id_ == 1) {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            1, 
 | 
						|
            "2022-01-01 00:00:50",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            300,
 | 
						|
            30,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece(
 | 
						|
            1001,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:00:50",
 | 
						|
            0,
 | 
						|
            2000,
 | 
						|
            200,
 | 
						|
            20);
 | 
						|
          
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:00:00",
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            0,
 | 
						|
            1000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
          
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1001);
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        } else if (piece.piece_info_.key_.piece_id_ == 2) {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            2, 
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            100,
 | 
						|
            10,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:01:00",
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            1000,
 | 
						|
            2000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        } else {
 | 
						|
          test.fill_piece(
 | 
						|
            old_round, 
 | 
						|
            3, 
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            "2022-01-01 00:02:30",
 | 
						|
            100,
 | 
						|
            10,
 | 
						|
            ObArchivePieceStatus::active(),
 | 
						|
            ObBackupFileStatus::STATUS::BACKUP_FILE_INCOMPLETE,
 | 
						|
            expect_piece.piece_info_);
 | 
						|
 | 
						|
          ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece(
 | 
						|
            1002,
 | 
						|
            "2022-01-01 00:02:00",
 | 
						|
            "2022-01-01 00:02:30",
 | 
						|
            2000,
 | 
						|
            3000,
 | 
						|
            100,
 | 
						|
            10);
 | 
						|
 | 
						|
          expect_piece.ls_piece_list_.push_back(ls_piece_1002);
 | 
						|
        }
 | 
						|
        
 | 
						|
        ret = test.compare_two_checkpoint_pieces(piece, expect_piece);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  ObDestRoundCheckpointer::RoundCheckpointCb round_cb = 
 | 
						|
    [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) 
 | 
						|
      { 
 | 
						|
        int ret = OB_SUCCESS;
 | 
						|
        g_call_cnt++;
 | 
						|
        ArchiveCheckpointerTest test;
 | 
						|
        ObTenantArchiveRoundAttr expect_round;
 | 
						|
        test.fill_new_round(
 | 
						|
          old_round, 
 | 
						|
          ObArchiveRoundState::interrupted(),
 | 
						|
          "2022-01-01 00:00:50",
 | 
						|
          "2022-01-01 00:02:30",
 | 
						|
          3,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          500,
 | 
						|
          50,
 | 
						|
          0,
 | 
						|
          0,
 | 
						|
          expect_round);
 | 
						|
 | 
						|
        ret = test.compare_two_rounds(new_round, expect_round);
 | 
						|
        return ret;
 | 
						|
      };
 | 
						|
  
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  g_call_cnt = 0;
 | 
						|
  MockRoundHandler mock_handler;
 | 
						|
  ObDestRoundCheckpointer checkpointer;
 | 
						|
  share::SCN limit_scn;
 | 
						|
  (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:03:00"));
 | 
						|
  ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  ret = checkpointer.checkpoint(old_round, summary);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(g_call_cnt, 5);
 | 
						|
}
 | 
						|
 | 
						|
int main(int argc, char **argv)
 | 
						|
{
 | 
						|
  system("rm -f test_archive_checkpoint.log*");
 | 
						|
  ObLogger &logger = ObLogger::get_logger();
 | 
						|
  logger.set_file_name("test_archive_checkpoint.log", true);
 | 
						|
  logger.set_log_level(OB_LOG_LEVEL_DEBUG);
 | 
						|
 | 
						|
  testing::InitGoogleTest(&argc, argv);
 | 
						|
  return RUN_ALL_TESTS();
 | 
						|
}
 |