go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/tests/history_replication_task.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package tests
    26  
    27  import (
    28  	"math/rand"
    29  	"testing"
    30  
    31  	"github.com/stretchr/testify/require"
    32  	"github.com/stretchr/testify/suite"
    33  
    34  	"go.temporal.io/server/common/persistence/sql/sqlplugin"
    35  	"go.temporal.io/server/common/shuffle"
    36  )
    37  
    38  type (
    39  	historyHistoryReplicationTaskSuite struct {
    40  		suite.Suite
    41  		*require.Assertions
    42  
    43  		store sqlplugin.HistoryReplicationTask
    44  	}
    45  )
    46  
    47  const (
    48  	testHistoryReplicationTaskEncoding = "random encoding"
    49  )
    50  
    51  var (
    52  	testHistoryReplicationTaskData = []byte("random history replication task data")
    53  )
    54  
    55  func NewHistoryReplicationTaskSuite(
    56  	t *testing.T,
    57  	store sqlplugin.HistoryReplicationTask,
    58  ) *historyHistoryReplicationTaskSuite {
    59  	return &historyHistoryReplicationTaskSuite{
    60  		Assertions: require.New(t),
    61  		store:      store,
    62  	}
    63  }
    64  
    65  func (s *historyHistoryReplicationTaskSuite) SetupSuite() {
    66  
    67  }
    68  
    69  func (s *historyHistoryReplicationTaskSuite) TearDownSuite() {
    70  
    71  }
    72  
    73  func (s *historyHistoryReplicationTaskSuite) SetupTest() {
    74  	s.Assertions = require.New(s.T())
    75  }
    76  
    77  func (s *historyHistoryReplicationTaskSuite) TearDownTest() {
    78  
    79  }
    80  
    81  func (s *historyHistoryReplicationTaskSuite) TestInsert_Single_Success() {
    82  	shardID := rand.Int31()
    83  	taskID := int64(1)
    84  
    85  	task := s.newRandomReplicationTaskRow(shardID, taskID)
    86  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task})
    87  	s.NoError(err)
    88  	rowsAffected, err := result.RowsAffected()
    89  	s.NoError(err)
    90  	s.Equal(1, int(rowsAffected))
    91  }
    92  
    93  func (s *historyHistoryReplicationTaskSuite) TestInsert_Multiple_Success() {
    94  	shardID := rand.Int31()
    95  	taskID := int64(1)
    96  
    97  	task1 := s.newRandomReplicationTaskRow(shardID, taskID)
    98  	taskID++
    99  	task2 := s.newRandomReplicationTaskRow(shardID, taskID)
   100  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task1, task2})
   101  	s.NoError(err)
   102  	rowsAffected, err := result.RowsAffected()
   103  	s.NoError(err)
   104  	s.Equal(2, int(rowsAffected))
   105  }
   106  
   107  func (s *historyHistoryReplicationTaskSuite) TestInsert_Single_Fail_Duplicate() {
   108  	shardID := rand.Int31()
   109  	taskID := int64(1)
   110  
   111  	task := s.newRandomReplicationTaskRow(shardID, taskID)
   112  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task})
   113  	s.NoError(err)
   114  	rowsAffected, err := result.RowsAffected()
   115  	s.NoError(err)
   116  	s.Equal(1, int(rowsAffected))
   117  
   118  	task = s.newRandomReplicationTaskRow(shardID, taskID)
   119  	_, err = s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task})
   120  	s.Error(err) // TODO persistence layer should do proper error translation
   121  }
   122  
   123  func (s *historyHistoryReplicationTaskSuite) TestInsert_Multiple_Fail_Duplicate() {
   124  	shardID := rand.Int31()
   125  	taskID := int64(1)
   126  
   127  	task1 := s.newRandomReplicationTaskRow(shardID, taskID)
   128  	taskID++
   129  	task2 := s.newRandomReplicationTaskRow(shardID, taskID)
   130  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task1, task2})
   131  	s.NoError(err)
   132  	rowsAffected, err := result.RowsAffected()
   133  	s.NoError(err)
   134  	s.Equal(2, int(rowsAffected))
   135  
   136  	task2 = s.newRandomReplicationTaskRow(shardID, taskID)
   137  	taskID++
   138  	task3 := s.newRandomReplicationTaskRow(shardID, taskID)
   139  	_, err = s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task2, task3})
   140  	s.Error(err) // TODO persistence layer should do proper error translation
   141  }
   142  
   143  func (s *historyHistoryReplicationTaskSuite) TestInsertSelect_Single() {
   144  	shardID := rand.Int31()
   145  	taskID := int64(1)
   146  
   147  	task := s.newRandomReplicationTaskRow(shardID, taskID)
   148  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task})
   149  	s.NoError(err)
   150  	rowsAffected, err := result.RowsAffected()
   151  	s.NoError(err)
   152  	s.Equal(1, int(rowsAffected))
   153  
   154  	rangeFilter := sqlplugin.ReplicationTasksRangeFilter{
   155  		ShardID:            shardID,
   156  		InclusiveMinTaskID: taskID,
   157  		ExclusiveMaxTaskID: taskID + 1,
   158  		PageSize:           1,
   159  	}
   160  	rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), rangeFilter)
   161  	s.NoError(err)
   162  	for index := range rows {
   163  		rows[index].ShardID = shardID
   164  	}
   165  	s.Equal([]sqlplugin.ReplicationTasksRow{task}, rows)
   166  }
   167  
   168  func (s *historyHistoryReplicationTaskSuite) TestInsertSelect_Multiple() {
   169  	numTasks := 20
   170  	pageSize := numTasks * 2
   171  
   172  	shardID := rand.Int31()
   173  	minTaskID := int64(1)
   174  	taskID := minTaskID
   175  	maxTaskID := taskID + int64(numTasks)
   176  
   177  	var tasks []sqlplugin.ReplicationTasksRow
   178  	for i := 0; i < numTasks; i++ {
   179  		task := s.newRandomReplicationTaskRow(shardID, taskID)
   180  		taskID++
   181  		tasks = append(tasks, task)
   182  	}
   183  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), tasks)
   184  	s.NoError(err)
   185  	rowsAffected, err := result.RowsAffected()
   186  	s.NoError(err)
   187  	s.Equal(numTasks, int(rowsAffected))
   188  
   189  	filter := sqlplugin.ReplicationTasksRangeFilter{
   190  		ShardID:            shardID,
   191  		InclusiveMinTaskID: minTaskID,
   192  		ExclusiveMaxTaskID: maxTaskID,
   193  		PageSize:           pageSize,
   194  	}
   195  	rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), filter)
   196  	s.NoError(err)
   197  	for index := range rows {
   198  		rows[index].ShardID = shardID
   199  	}
   200  	s.Equal(tasks, rows)
   201  }
   202  
   203  func (s *historyHistoryReplicationTaskSuite) TestDeleteSelect_Single() {
   204  	shardID := rand.Int31()
   205  	taskID := int64(1)
   206  
   207  	filter := sqlplugin.ReplicationTasksFilter{
   208  		ShardID: shardID,
   209  		TaskID:  taskID,
   210  	}
   211  	result, err := s.store.DeleteFromReplicationTasks(newExecutionContext(), filter)
   212  	s.NoError(err)
   213  	rowsAffected, err := result.RowsAffected()
   214  	s.NoError(err)
   215  	s.Equal(0, int(rowsAffected))
   216  
   217  	rangeFilter := sqlplugin.ReplicationTasksRangeFilter{
   218  		ShardID:            shardID,
   219  		InclusiveMinTaskID: taskID,
   220  		ExclusiveMaxTaskID: taskID + 1,
   221  		PageSize:           1,
   222  	}
   223  	rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), rangeFilter)
   224  	s.NoError(err)
   225  	for index := range rows {
   226  		rows[index].ShardID = shardID
   227  	}
   228  	s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows)
   229  }
   230  
   231  func (s *historyHistoryReplicationTaskSuite) TestDeleteSelect_Multiple() {
   232  	shardID := rand.Int31()
   233  	minTaskID := int64(1)
   234  	maxTaskID := int64(101)
   235  
   236  	filter := sqlplugin.ReplicationTasksRangeFilter{
   237  		ShardID:            shardID,
   238  		InclusiveMinTaskID: minTaskID,
   239  		ExclusiveMaxTaskID: maxTaskID,
   240  		PageSize:           0,
   241  	}
   242  	result, err := s.store.RangeDeleteFromReplicationTasks(newExecutionContext(), filter)
   243  	s.NoError(err)
   244  	rowsAffected, err := result.RowsAffected()
   245  	s.NoError(err)
   246  	s.Equal(0, int(rowsAffected))
   247  
   248  	rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), filter)
   249  	s.NoError(err)
   250  	for index := range rows {
   251  		rows[index].ShardID = shardID
   252  	}
   253  	s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows)
   254  }
   255  
   256  func (s *historyHistoryReplicationTaskSuite) TestInsertDeleteSelect_Single() {
   257  	shardID := rand.Int31()
   258  	taskID := int64(1)
   259  
   260  	task := s.newRandomReplicationTaskRow(shardID, taskID)
   261  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task})
   262  	s.NoError(err)
   263  	rowsAffected, err := result.RowsAffected()
   264  	s.NoError(err)
   265  	s.Equal(1, int(rowsAffected))
   266  
   267  	filter := sqlplugin.ReplicationTasksFilter{
   268  		ShardID: shardID,
   269  		TaskID:  taskID,
   270  	}
   271  	result, err = s.store.DeleteFromReplicationTasks(newExecutionContext(), filter)
   272  	s.NoError(err)
   273  	rowsAffected, err = result.RowsAffected()
   274  	s.NoError(err)
   275  	s.Equal(1, int(rowsAffected))
   276  
   277  	rangeFilter := sqlplugin.ReplicationTasksRangeFilter{
   278  		ShardID:            shardID,
   279  		InclusiveMinTaskID: taskID,
   280  		ExclusiveMaxTaskID: taskID + 1,
   281  		PageSize:           1,
   282  	}
   283  	rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), rangeFilter)
   284  	s.NoError(err)
   285  	for index := range rows {
   286  		rows[index].ShardID = shardID
   287  	}
   288  	s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows)
   289  }
   290  
   291  func (s *historyHistoryReplicationTaskSuite) TestInsertDeleteSelect_Multiple() {
   292  	numTasks := 20
   293  	pageSize := numTasks * 2
   294  
   295  	shardID := rand.Int31()
   296  	minTaskID := int64(1)
   297  	taskID := minTaskID
   298  	maxTaskID := taskID + int64(numTasks)
   299  
   300  	var tasks []sqlplugin.ReplicationTasksRow
   301  	for i := 0; i < numTasks; i++ {
   302  		task := s.newRandomReplicationTaskRow(shardID, taskID)
   303  		taskID++
   304  		tasks = append(tasks, task)
   305  	}
   306  	result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), tasks)
   307  	s.NoError(err)
   308  	rowsAffected, err := result.RowsAffected()
   309  	s.NoError(err)
   310  	s.Equal(numTasks, int(rowsAffected))
   311  
   312  	filter := sqlplugin.ReplicationTasksRangeFilter{
   313  		ShardID:            shardID,
   314  		InclusiveMinTaskID: minTaskID,
   315  		ExclusiveMaxTaskID: maxTaskID,
   316  		PageSize:           pageSize,
   317  	}
   318  	result, err = s.store.RangeDeleteFromReplicationTasks(newExecutionContext(), filter)
   319  	s.NoError(err)
   320  	rowsAffected, err = result.RowsAffected()
   321  	s.NoError(err)
   322  	s.Equal(numTasks, int(rowsAffected))
   323  
   324  	rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), filter)
   325  	s.NoError(err)
   326  	for index := range rows {
   327  		rows[index].ShardID = shardID
   328  	}
   329  	s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows)
   330  }
   331  
   332  func (s *historyHistoryReplicationTaskSuite) newRandomReplicationTaskRow(
   333  	shardID int32,
   334  	taskID int64,
   335  ) sqlplugin.ReplicationTasksRow {
   336  	return sqlplugin.ReplicationTasksRow{
   337  		ShardID:      shardID,
   338  		TaskID:       taskID,
   339  		Data:         shuffle.Bytes(testHistoryReplicationTaskData),
   340  		DataEncoding: testHistoryReplicationTaskEncoding,
   341  	}
   342  }