go.temporal.io/server@v1.23.0/common/persistence/tests/util.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  	"time"
    30  
    31  	"github.com/brianvoe/gofakeit/v6"
    32  	"github.com/google/uuid"
    33  	commonpb "go.temporal.io/api/common/v1"
    34  	historypb "go.temporal.io/api/history/v1"
    35  	workflowpb "go.temporal.io/api/workflow/v1"
    36  	"google.golang.org/protobuf/types/known/durationpb"
    37  	"google.golang.org/protobuf/types/known/timestamppb"
    38  
    39  	enumspb "go.temporal.io/api/enums/v1"
    40  
    41  	enumsspb "go.temporal.io/server/api/enums/v1"
    42  	historyspb "go.temporal.io/server/api/history/v1"
    43  	persistencespb "go.temporal.io/server/api/persistence/v1"
    44  	p "go.temporal.io/server/common/persistence"
    45  	"go.temporal.io/server/common/shuffle"
    46  	"go.temporal.io/server/service/history/tasks"
    47  )
    48  
    49  func RandomShardInfo(
    50  	shardID int32,
    51  	rangeID int64,
    52  ) *persistencespb.ShardInfo {
    53  	var shardInfo persistencespb.ShardInfo
    54  	_ = gofakeit.Struct(&shardInfo)
    55  	shardInfo.ShardId = shardID
    56  	shardInfo.RangeId = rangeID
    57  	return &shardInfo
    58  }
    59  
    60  func RandomSnapshot(
    61  	namespaceID string,
    62  	workflowID string,
    63  	runID string,
    64  	lastWriteVersion int64,
    65  	state enumsspb.WorkflowExecutionState,
    66  	status enumspb.WorkflowExecutionStatus,
    67  	dbRecordVersion int64,
    68  ) *p.WorkflowSnapshot {
    69  	return &p.WorkflowSnapshot{
    70  		ExecutionInfo:  RandomExecutionInfo(namespaceID, workflowID, lastWriteVersion),
    71  		ExecutionState: RandomExecutionState(runID, state, status),
    72  
    73  		NextEventID: rand.Int63(),
    74  
    75  		ActivityInfos:       RandomInt64ActivityInfoMap(),
    76  		TimerInfos:          RandomStringTimerInfoMap(),
    77  		ChildExecutionInfos: RandomInt64ChildExecutionInfoMap(),
    78  		RequestCancelInfos:  RandomInt64RequestCancelInfoMap(),
    79  		SignalInfos:         RandomInt64SignalInfoMap(),
    80  		SignalRequestedIDs:  map[string]struct{}{uuid.New().String(): {}},
    81  
    82  		Tasks: map[tasks.Category][]tasks.Task{
    83  			tasks.CategoryTransfer:    {},
    84  			tasks.CategoryTimer:       {},
    85  			tasks.CategoryReplication: {},
    86  			tasks.CategoryVisibility:  {},
    87  		},
    88  
    89  		Condition:       rand.Int63(),
    90  		DBRecordVersion: dbRecordVersion,
    91  	}
    92  }
    93  
    94  func RandomMutation(
    95  	namespaceID string,
    96  	workflowID string,
    97  	runID string,
    98  	lastWriteVersion int64,
    99  	state enumsspb.WorkflowExecutionState,
   100  	status enumspb.WorkflowExecutionStatus,
   101  	dbRecordVersion int64,
   102  ) *p.WorkflowMutation {
   103  	mutation := &p.WorkflowMutation{
   104  		ExecutionInfo:  RandomExecutionInfo(namespaceID, workflowID, lastWriteVersion),
   105  		ExecutionState: RandomExecutionState(runID, state, status),
   106  
   107  		NextEventID: rand.Int63(),
   108  
   109  		UpsertActivityInfos:       RandomInt64ActivityInfoMap(),
   110  		DeleteActivityInfos:       map[int64]struct{}{rand.Int63(): {}},
   111  		UpsertTimerInfos:          RandomStringTimerInfoMap(),
   112  		DeleteTimerInfos:          map[string]struct{}{uuid.New().String(): {}},
   113  		UpsertChildExecutionInfos: RandomInt64ChildExecutionInfoMap(),
   114  		DeleteChildExecutionInfos: map[int64]struct{}{rand.Int63(): {}},
   115  		UpsertRequestCancelInfos:  RandomInt64RequestCancelInfoMap(),
   116  		DeleteRequestCancelInfos:  map[int64]struct{}{rand.Int63(): {}},
   117  		UpsertSignalInfos:         RandomInt64SignalInfoMap(),
   118  		DeleteSignalInfos:         map[int64]struct{}{rand.Int63(): {}},
   119  		UpsertSignalRequestedIDs:  map[string]struct{}{uuid.New().String(): {}},
   120  		DeleteSignalRequestedIDs:  map[string]struct{}{uuid.New().String(): {}},
   121  		// NewBufferedEvents: see below
   122  		// ClearBufferedEvents: see below
   123  
   124  		Tasks: map[tasks.Category][]tasks.Task{
   125  			tasks.CategoryTransfer:    {},
   126  			tasks.CategoryTimer:       {},
   127  			tasks.CategoryReplication: {},
   128  			tasks.CategoryVisibility:  {},
   129  		},
   130  
   131  		Condition:       rand.Int63(),
   132  		DBRecordVersion: dbRecordVersion,
   133  	}
   134  
   135  	switch rand.Int63() % 3 {
   136  	case 0:
   137  		mutation.ClearBufferedEvents = true
   138  		mutation.NewBufferedEvents = nil
   139  	case 1:
   140  		mutation.ClearBufferedEvents = false
   141  		mutation.NewBufferedEvents = nil
   142  	case 2:
   143  		mutation.ClearBufferedEvents = false
   144  		mutation.NewBufferedEvents = []*historypb.HistoryEvent{RandomHistoryEvent()}
   145  	default:
   146  		panic("broken test")
   147  	}
   148  	return mutation
   149  }
   150  
   151  func RandomExecutionInfo(
   152  	namespaceID string,
   153  	workflowID string,
   154  	lastWriteVersion int64,
   155  ) *persistencespb.WorkflowExecutionInfo {
   156  	var executionInfo persistencespb.WorkflowExecutionInfo
   157  	_ = gofakeit.Struct(&executionInfo)
   158  	executionInfo.NamespaceId = namespaceID
   159  	executionInfo.WorkflowId = workflowID
   160  	executionInfo.VersionHistories = RandomVersionHistory(lastWriteVersion)
   161  	return &executionInfo
   162  }
   163  
   164  func RandomExecutionState(
   165  	runID string,
   166  	state enumsspb.WorkflowExecutionState,
   167  	status enumspb.WorkflowExecutionStatus,
   168  ) *persistencespb.WorkflowExecutionState {
   169  	return &persistencespb.WorkflowExecutionState{
   170  		CreateRequestId: uuid.New().String(),
   171  		RunId:           runID,
   172  		State:           state,
   173  		Status:          status,
   174  	}
   175  }
   176  
   177  func RandomInt64ActivityInfoMap() map[int64]*persistencespb.ActivityInfo {
   178  	return map[int64]*persistencespb.ActivityInfo{
   179  		rand.Int63(): RandomActivityInfo(),
   180  	}
   181  }
   182  
   183  func RandomStringTimerInfoMap() map[string]*persistencespb.TimerInfo {
   184  	return map[string]*persistencespb.TimerInfo{
   185  		uuid.New().String(): RandomTimerInfo(),
   186  	}
   187  }
   188  
   189  func RandomInt64ChildExecutionInfoMap() map[int64]*persistencespb.ChildExecutionInfo {
   190  	return map[int64]*persistencespb.ChildExecutionInfo{
   191  		rand.Int63(): RandomChildExecutionInfo(),
   192  	}
   193  }
   194  
   195  func RandomInt64RequestCancelInfoMap() map[int64]*persistencespb.RequestCancelInfo {
   196  	return map[int64]*persistencespb.RequestCancelInfo{
   197  		rand.Int63(): RandomRequestCancelInfo(),
   198  	}
   199  }
   200  
   201  func RandomInt64SignalInfoMap() map[int64]*persistencespb.SignalInfo {
   202  	return map[int64]*persistencespb.SignalInfo{
   203  		rand.Int63(): RandomSignalInfo(),
   204  	}
   205  }
   206  
   207  func RandomActivityInfo() *persistencespb.ActivityInfo {
   208  	// cannot use gofakeit due to RetryLastFailure is of type Failure
   209  	// and Failure can contain another Failure -> stack overflow
   210  	return &persistencespb.ActivityInfo{
   211  		Version:                rand.Int63(),
   212  		ScheduledEventBatchId:  rand.Int63(),
   213  		ScheduledTime:          RandomTime(),
   214  		StartedEventId:         rand.Int63(),
   215  		StartedTime:            RandomTime(),
   216  		ActivityId:             uuid.New().String(),
   217  		RequestId:              uuid.New().String(),
   218  		ScheduleToStartTimeout: RandomDuration(),
   219  		ScheduleToCloseTimeout: RandomDuration(),
   220  		StartToCloseTimeout:    RandomDuration(),
   221  		HeartbeatTimeout:       RandomDuration(),
   222  
   223  		// other fields omitted, above should be enough for tests
   224  	}
   225  }
   226  
   227  func RandomTimerInfo() *persistencespb.TimerInfo {
   228  	var timerInfo persistencespb.TimerInfo
   229  	_ = gofakeit.Struct(&timerInfo)
   230  	return &timerInfo
   231  }
   232  
   233  func RandomChildExecutionInfo() *persistencespb.ChildExecutionInfo {
   234  	var childExecutionInfo persistencespb.ChildExecutionInfo
   235  	_ = gofakeit.Struct(&childExecutionInfo)
   236  	return &childExecutionInfo
   237  }
   238  
   239  func RandomRequestCancelInfo() *persistencespb.RequestCancelInfo {
   240  	var requestCancelInfo persistencespb.RequestCancelInfo
   241  	_ = gofakeit.Struct(&requestCancelInfo)
   242  	return &requestCancelInfo
   243  }
   244  
   245  func RandomSignalInfo() *persistencespb.SignalInfo {
   246  	var signalInfo persistencespb.SignalInfo
   247  	_ = gofakeit.Struct(&signalInfo)
   248  	return &signalInfo
   249  }
   250  
   251  func RandomHistoryEvent() *historypb.HistoryEvent {
   252  	var historyEvent historypb.HistoryEvent
   253  	_ = gofakeit.Struct(&historyEvent)
   254  	return &historyEvent
   255  }
   256  
   257  func RandomResetPoints() *workflowpb.ResetPoints {
   258  	return &workflowpb.ResetPoints{Points: []*workflowpb.ResetPointInfo{{
   259  		BinaryChecksum:               uuid.New().String(),
   260  		RunId:                        uuid.New().String(),
   261  		FirstWorkflowTaskCompletedId: rand.Int63(),
   262  		CreateTime:                   RandomTime(),
   263  		ExpireTime:                   RandomTime(),
   264  		Resettable:                   rand.Int31()%2 == 0,
   265  	}}}
   266  }
   267  
   268  func RandomStringPayloadMap() map[string]*commonpb.Payload {
   269  	return map[string]*commonpb.Payload{
   270  		uuid.New().String(): RandomPayload(),
   271  	}
   272  }
   273  
   274  func RandomPayload() *commonpb.Payload {
   275  	var payload commonpb.Payload
   276  	_ = gofakeit.Struct(&payload)
   277  	return &payload
   278  }
   279  
   280  func RandomVersionHistory(
   281  	lastWriteVersion int64,
   282  ) *historyspb.VersionHistories {
   283  	return &historyspb.VersionHistories{
   284  		CurrentVersionHistoryIndex: 0,
   285  		Histories: []*historyspb.VersionHistory{{
   286  			BranchToken: shuffle.Bytes([]byte("random branch token")),
   287  			Items: []*historyspb.VersionHistoryItem{{
   288  				EventId: rand.Int63(),
   289  				Version: lastWriteVersion,
   290  			}},
   291  		}},
   292  	}
   293  }
   294  
   295  func RandomTime() *timestamppb.Timestamp {
   296  	return timestamppb.New(time.Unix(0, rand.Int63()))
   297  }
   298  
   299  func RandomDuration() *durationpb.Duration {
   300  	return durationpb.New(time.Duration(rand.Int63()))
   301  }