Skip to content

Commit b79758a

Browse files
authored
Test Framework: Use test implementation for session activities (#810)
1 parent 924be32 commit b79758a

File tree

4 files changed

+122
-6
lines changed

4 files changed

+122
-6
lines changed

internal/internal_workflow_testsuite.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,16 @@ func (env *testWorkflowEnvironmentImpl) newTestActivityTaskHandler(taskList stri
14871487
return nil
14881488
}
14891489
ae := &activityExecutor{name: activity.ActivityType().Name, fn: activity.GetFunction()}
1490+
1491+
// Special handling for session creation and completion activities.
1492+
// If real creation activity is used, it will block timers from autofiring.
1493+
if ae.name == sessionCreationActivityName {
1494+
ae.fn = sessionCreationActivityForTest
1495+
}
1496+
if ae.name == sessionCompletionActivityName {
1497+
ae.fn = sessionCompletionActivityForTest
1498+
}
1499+
14901500
return &activityExecutorWrapper{activityExecutor: ae, env: env}
14911501
}
14921502

internal/session.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,25 @@ func (env *sessionEnvironmentImpl) GetResourceSpecificTasklist() string {
540540
func (env *sessionEnvironmentImpl) GetTokenBucket() *sessionTokenBucket {
541541
return env.sessionTokenBucket
542542
}
543+
544+
// The following two implemention is for testsuite only. The only difference is that
545+
// the creation activity is not long running, otherwise it will block timers from auto firing.
546+
func sessionCreationActivityForTest(ctx context.Context, sessionID string) error {
547+
sessionEnv := ctx.Value(sessionEnvironmentContextKey).(sessionEnvironment)
548+
549+
if _, err := sessionEnv.CreateSession(ctx, sessionID); err != nil {
550+
return err
551+
}
552+
553+
return sessionEnv.SignalCreationResponse(ctx, sessionID)
554+
}
555+
556+
func sessionCompletionActivityForTest(ctx context.Context, sessionID string) error {
557+
sessionEnv := ctx.Value(sessionEnvironmentContextKey).(sessionEnvironment)
558+
559+
sessionEnv.CompleteSession(sessionID)
560+
561+
// Add session token in the completion activity.
562+
sessionEnv.AddSessionToken()
563+
return nil
564+
}

internal/session_test.go

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"time"
2828

2929
"github.com/stretchr/testify/mock"
30-
3130
"github.com/stretchr/testify/require"
3231
"github.com/stretchr/testify/suite"
3332
)
@@ -83,10 +82,13 @@ func (s *SessionTestSuite) TestCreationCompletion() {
8382

8483
RegisterWorkflow(workflowFn)
8584
env := s.NewTestWorkflowEnvironment()
85+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
86+
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(sessionCompletionActivity).Once()
8687
env.ExecuteWorkflow(workflowFn)
8788

8889
s.True(env.IsWorkflowCompleted())
8990
s.NoError(env.GetWorkflowError())
91+
env.AssertExpectations(s.T())
9092
}
9193

9294
func (s *SessionTestSuite) TestCreationWithOpenSessionContext() {
@@ -106,6 +108,7 @@ func (s *SessionTestSuite) TestCreationWithOpenSessionContext() {
106108

107109
s.True(env.IsWorkflowCompleted())
108110
s.Equal(errFoundExistingOpenSession.Error(), env.GetWorkflowError().Error())
111+
env.AssertExpectations(s.T())
109112
}
110113

111114
func (s *SessionTestSuite) TestCreationWithClosedSessionContext() {
@@ -132,10 +135,13 @@ func (s *SessionTestSuite) TestCreationWithClosedSessionContext() {
132135

133136
RegisterWorkflow(workflowFn)
134137
env := s.NewTestWorkflowEnvironment()
138+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
139+
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(sessionCompletionActivity).Once()
135140
env.ExecuteWorkflow(workflowFn)
136141

137142
s.True(env.IsWorkflowCompleted())
138143
s.NoError(env.GetWorkflowError())
144+
env.AssertExpectations(s.T())
139145
}
140146

141147
func (s *SessionTestSuite) TestCreationWithFailedSessionContext() {
@@ -162,10 +168,13 @@ func (s *SessionTestSuite) TestCreationWithFailedSessionContext() {
162168

163169
RegisterWorkflow(workflowFn)
164170
env := s.NewTestWorkflowEnvironment()
171+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
172+
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(sessionCompletionActivity).Once()
165173
env.ExecuteWorkflow(workflowFn)
166174

167175
s.True(env.IsWorkflowCompleted())
168176
s.NoError(env.GetWorkflowError())
177+
env.AssertExpectations(s.T())
169178
}
170179

171180
func (s *SessionTestSuite) TestCompletionWithClosedSessionContext() {
@@ -185,6 +194,7 @@ func (s *SessionTestSuite) TestCompletionWithClosedSessionContext() {
185194

186195
s.True(env.IsWorkflowCompleted())
187196
s.NoError(env.GetWorkflowError())
197+
env.AssertExpectations(s.T())
188198
}
189199

190200
func (s *SessionTestSuite) TestCompletionWithFailedSessionContext() {
@@ -204,6 +214,7 @@ func (s *SessionTestSuite) TestCompletionWithFailedSessionContext() {
204214

205215
s.True(env.IsWorkflowCompleted())
206216
s.NoError(env.GetWorkflowError())
217+
env.AssertExpectations(s.T())
207218
}
208219

209220
func (s *SessionTestSuite) TestGetSessionInfo() {
@@ -271,10 +282,13 @@ func (s *SessionTestSuite) TestRecreation() {
271282

272283
RegisterWorkflow(workflowFn)
273284
env := s.NewTestWorkflowEnvironment()
285+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
286+
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(sessionCompletionActivity).Once()
274287
env.ExecuteWorkflow(workflowFn)
275288

276289
s.True(env.IsWorkflowCompleted())
277290
s.NoError(env.GetWorkflowError())
291+
env.AssertExpectations(s.T())
278292
}
279293

280294
func (s *SessionTestSuite) TestMaxConcurrentSession_CreationOnly() {
@@ -341,10 +355,12 @@ func (s *SessionTestSuite) TestMaxConcurrentSession_WithRecreation() {
341355
env.SetWorkerOptions(WorkerOptions{
342356
MaxConcurrentSessionExecutionSize: maxConcurrentSessionExecutionSize,
343357
})
358+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity)
344359
env.ExecuteWorkflow(workflowFn)
345360

346361
s.True(env.IsWorkflowCompleted())
347362
s.Equal(errTooManySessionsMsg, env.GetWorkflowError().Error())
363+
env.AssertExpectations(s.T())
348364
}
349365

350366
func (s *SessionTestSuite) TestSessionTaskList() {
@@ -378,6 +394,8 @@ func (s *SessionTestSuite) TestSessionTaskList() {
378394
taskListUsed = append(taskListUsed, activityInfo.TaskList)
379395
})
380396
resourceID := "testResourceID"
397+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
398+
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(sessionCompletionActivity).Once()
381399
env.ExecuteWorkflow(workflowFn)
382400

383401
s.True(env.IsWorkflowCompleted())
@@ -387,6 +405,7 @@ func (s *SessionTestSuite) TestSessionTaskList() {
387405
for _, taskList := range taskListUsed[1:] {
388406
s.Equal(expectedTaskList, taskList)
389407
}
408+
env.AssertExpectations(s.T())
390409
}
391410

392411
func (s *SessionTestSuite) TestSessionRecreationTaskList() {
@@ -427,13 +446,16 @@ func (s *SessionTestSuite) TestSessionRecreationTaskList() {
427446
env.SetOnActivityStartedListener(func(activityInfo *ActivityInfo, ctx context.Context, args Values) {
428447
taskListUsed = append(taskListUsed, activityInfo.TaskList)
429448
})
449+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
450+
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(sessionCompletionActivity).Once()
430451
env.ExecuteWorkflow(workflowFn)
431452

432453
s.True(env.IsWorkflowCompleted())
433454
s.NoError(env.GetWorkflowError())
434455
for _, taskList := range taskListUsed {
435456
s.Equal(resourceSpecificTaskList, taskList)
436457
}
458+
env.AssertExpectations(s.T())
437459
}
438460

439461
func (s *SessionTestSuite) TestExecuteActivityInFailedSession() {
@@ -455,7 +477,6 @@ func (s *SessionTestSuite) TestExecuteActivityInFailedSession() {
455477

456478
RegisterWorkflow(workflowFn)
457479
env := s.NewTestWorkflowEnvironment()
458-
459480
env.ExecuteWorkflow(workflowFn)
460481

461482
s.True(env.IsWorkflowCompleted())
@@ -485,7 +506,6 @@ func (s *SessionTestSuite) TestExecuteActivityInClosedSession() {
485506
env.SetOnActivityStartedListener(func(activityInfo *ActivityInfo, ctx context.Context, args Values) {
486507
taskListUsed = activityInfo.TaskList
487508
})
488-
489509
env.ExecuteWorkflow(workflowFn)
490510

491511
s.True(env.IsWorkflowCompleted())
@@ -538,12 +558,76 @@ func (s *SessionTestSuite) TestCompletionFailed() {
538558

539559
RegisterWorkflow(workflowFn)
540560
env := s.NewTestWorkflowEnvironment()
561+
env.OnActivity(sessionCreationActivityName, mock.Anything, mock.Anything).Return(sessionCreationActivity).Once()
541562
env.OnActivity(sessionCompletionActivityName, mock.Anything, mock.Anything).Return(errors.New("some random error")).Once()
542563
env.ExecuteWorkflow(workflowFn)
543564

544565
env.AssertExpectations(s.T())
545566
s.True(env.IsWorkflowCompleted())
546567
s.NoError(env.GetWorkflowError())
568+
env.AssertExpectations(s.T())
569+
}
570+
571+
func (s *SessionTestSuite) TestUserTimerWithinSession() {
572+
workflowFn := func(ctx Context) error {
573+
sessionCtx, err := CreateSession(ctx, s.sessionOptions)
574+
if err != nil {
575+
return err
576+
}
577+
578+
defer CompleteSession(sessionCtx)
579+
580+
if err := NewTimer(sessionCtx, time.Hour).Get(sessionCtx, nil); err != nil {
581+
return err
582+
}
583+
return nil
584+
}
585+
586+
RegisterWorkflow(workflowFn)
587+
env := s.NewTestWorkflowEnvironment()
588+
env.ExecuteWorkflow(workflowFn)
589+
590+
env.AssertExpectations(s.T())
591+
s.True(env.IsWorkflowCompleted())
592+
s.NoError(env.GetWorkflowError())
593+
}
594+
595+
func (s *SessionTestSuite) TestActivityRetryWithinSession() {
596+
workflowFn := func(ctx Context) error {
597+
ao := ActivityOptions{
598+
ScheduleToStartTimeout: time.Minute,
599+
StartToCloseTimeout: time.Minute,
600+
HeartbeatTimeout: time.Second * 20,
601+
RetryPolicy: &RetryPolicy{
602+
InitialInterval: time.Second,
603+
BackoffCoefficient: 2.0,
604+
MaximumInterval: time.Minute,
605+
ExpirationInterval: time.Minute * 10,
606+
NonRetriableErrorReasons: []string{"bad-error"},
607+
},
608+
}
609+
ctx = WithActivityOptions(ctx, ao)
610+
sessionCtx, err := CreateSession(ctx, s.sessionOptions)
611+
if err != nil {
612+
return err
613+
}
614+
615+
defer CompleteSession(sessionCtx)
616+
617+
if err := ExecuteActivity(sessionCtx, testSessionActivity, "").Get(sessionCtx, nil); err != nil {
618+
return err
619+
}
620+
return nil
621+
}
622+
623+
RegisterWorkflow(workflowFn)
624+
env := s.NewTestWorkflowEnvironment()
625+
env.OnActivity(testSessionActivity, mock.Anything, mock.Anything).Return("", errors.New("some random error"))
626+
env.ExecuteWorkflow(workflowFn)
627+
628+
env.AssertExpectations(s.T())
629+
s.True(env.IsWorkflowCompleted())
630+
s.Error(env.GetWorkflowError())
547631
}
548632

549633
func (s *SessionTestSuite) createSessionWithoutRetry(ctx Context) (Context, error) {

internal/workflow_testsuite.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,17 +353,17 @@ func (t *TestWorkflowEnvironment) wrapCall(call *mock.Call) *MockCallWrapper {
353353
return callWrapper
354354
}
355355

356-
// Once indicates that that the mock should only return the value once.
356+
// Once indicates that the mock should only return the value once.
357357
func (c *MockCallWrapper) Once() *MockCallWrapper {
358358
return c.Times(1)
359359
}
360360

361-
// Twice indicates that that the mock should only return the value twice.
361+
// Twice indicates that the mock should only return the value twice.
362362
func (c *MockCallWrapper) Twice() *MockCallWrapper {
363363
return c.Times(2)
364364
}
365365

366-
// Times indicates that that the mock should only return the indicated number of times.
366+
// Times indicates that the mock should only return the indicated number of times.
367367
func (c *MockCallWrapper) Times(i int) *MockCallWrapper {
368368
c.call.Times(i)
369369
return c

0 commit comments

Comments
 (0)