@@ -5,47 +5,52 @@ import { MockActivityEnvironment, defaultActivityInfo } from '@temporalio/testin
5
5
import { isCancellation } from '@temporalio/workflow' ;
6
6
import { isAbortError } from '@temporalio/common/lib/type-helpers' ;
7
7
import * as activity from '@temporalio/activity' ;
8
+ import { SdkComponent } from '@temporalio/common' ;
8
9
import { withZeroesHTTPServer } from './zeroes-http-server' ;
9
10
import { cancellableFetch } from './activities' ;
10
11
11
12
interface MyTestActivityContext extends activity . Context {
12
13
logs : Array < LogEntry > ;
13
14
}
14
15
15
- test . before ( ( ) => {
16
- const mockLogger = new DefaultLogger ( 'DEBUG' , ( entry ) => {
16
+ const mockLogger = new DefaultLogger ( 'DEBUG' , ( entry ) => {
17
+ try {
17
18
( activity . Context . current ( ) as MyTestActivityContext ) . logs ??= [ ] ;
18
19
( activity . Context . current ( ) as MyTestActivityContext ) . logs . push ( entry ) ;
19
- } ) ;
20
- Runtime . install ( {
21
- logger : mockLogger ,
22
- } ) ;
20
+ } catch ( e ) {
21
+ // Ignore messages produced from non activity context
22
+ if ( ( e as Error ) . message !== 'Activity context not initialized' ) throw e ;
23
+ }
24
+ } ) ;
25
+ Runtime . install ( {
26
+ logger : mockLogger ,
23
27
} ) ;
24
28
25
- test ( " Activity Context logger defaults to Runtime's Logger" , async ( t ) => {
26
- const env = new MockActivityEnvironment ( { } ) ;
29
+ test ( ' Activity Context logger funnel through the parent Logger' , async ( t ) => {
30
+ const env = new MockActivityEnvironment ( { } , { logger : mockLogger } ) ;
27
31
await env . run ( async ( ) => {
28
32
activity . log . debug ( 'log message from activity' ) ;
29
33
} ) ;
30
34
const logs = ( env . context as MyTestActivityContext ) . logs ;
31
35
const entry = logs . find ( ( x ) => x . level === 'DEBUG' && x . message === 'log message from activity' ) ;
32
36
t . not ( entry , undefined ) ;
37
+ t . deepEqual ( entry ?. meta , { ...activityLogAttributes ( defaultActivityInfo ) , sdkComponent : SdkComponent . activity } ) ;
33
38
} ) ;
34
39
35
40
test ( 'Activity Worker logs when activity starts' , async ( t ) => {
36
- const env = new MockActivityEnvironment ( { } ) ;
41
+ const env = new MockActivityEnvironment ( { } , { logger : mockLogger } ) ;
37
42
await env . run ( async ( ) => {
38
43
activity . log . debug ( 'log message from activity' ) ;
39
44
} ) ;
40
45
const logs = ( env . context as MyTestActivityContext ) . logs ;
41
46
const entry = logs . find ( ( x ) => x . level === 'DEBUG' && x . message === 'Activity started' ) ;
42
47
t . not ( entry , undefined ) ;
43
- t . deepEqual ( entry ?. meta , activityLogAttributes ( defaultActivityInfo ) ) ;
48
+ t . deepEqual ( entry ?. meta , { ... activityLogAttributes ( defaultActivityInfo ) , sdkComponent : SdkComponent . worker } ) ;
44
49
} ) ;
45
50
46
51
test ( 'Activity Worker logs warning when activity fails' , async ( t ) => {
47
52
const err = new Error ( 'Failed for test' ) ;
48
- const env = new MockActivityEnvironment ( { } ) ;
53
+ const env = new MockActivityEnvironment ( { } , { logger : mockLogger } ) ;
49
54
try {
50
55
await env . run ( async ( ) => {
51
56
throw err ;
@@ -60,11 +65,11 @@ test('Activity Worker logs warning when activity fails', async (t) => {
60
65
const { durationMs, error, ...rest } = entry ?. meta ?? { } ;
61
66
t . true ( Number . isInteger ( durationMs ) ) ;
62
67
t . is ( err , error ) ;
63
- t . deepEqual ( rest , activityLogAttributes ( defaultActivityInfo ) ) ;
68
+ t . deepEqual ( rest , { ... activityLogAttributes ( defaultActivityInfo ) , sdkComponent : SdkComponent . worker } ) ;
64
69
} ) ;
65
70
66
71
test ( 'Activity Worker logs when activity completes async' , async ( t ) => {
67
- const env = new MockActivityEnvironment ( { } ) ;
72
+ const env = new MockActivityEnvironment ( { } , { logger : mockLogger } ) ;
68
73
try {
69
74
await env . run ( async ( ) => {
70
75
throw new activity . CompleteAsyncError ( ) ;
@@ -77,11 +82,11 @@ test('Activity Worker logs when activity completes async', async (t) => {
77
82
t . not ( entry , undefined ) ;
78
83
const { durationMs, ...rest } = entry ?. meta ?? { } ;
79
84
t . true ( Number . isInteger ( durationMs ) ) ;
80
- t . deepEqual ( rest , activityLogAttributes ( defaultActivityInfo ) ) ;
85
+ t . deepEqual ( rest , { ... activityLogAttributes ( defaultActivityInfo ) , sdkComponent : SdkComponent . worker } ) ;
81
86
} ) ;
82
87
83
88
test ( 'Activity Worker logs when activity is cancelled with promise' , async ( t ) => {
84
- const env = new MockActivityEnvironment ( { } ) ;
89
+ const env = new MockActivityEnvironment ( { } , { logger : mockLogger } ) ;
85
90
env . on ( 'heartbeat' , ( ) => env . cancel ( ) ) ;
86
91
try {
87
92
await env . run ( async ( ) => {
@@ -96,11 +101,11 @@ test('Activity Worker logs when activity is cancelled with promise', async (t) =
96
101
t . not ( entry , undefined ) ;
97
102
const { durationMs, ...rest } = entry ?. meta ?? { } ;
98
103
t . true ( Number . isInteger ( durationMs ) ) ;
99
- t . deepEqual ( rest , activityLogAttributes ( defaultActivityInfo ) ) ;
104
+ t . deepEqual ( rest , { ... activityLogAttributes ( defaultActivityInfo ) , sdkComponent : SdkComponent . worker } ) ;
100
105
} ) ;
101
106
102
107
test ( 'Activity Worker logs when activity is cancelled with signal' , async ( t ) => {
103
- const env = new MockActivityEnvironment ( { } ) ;
108
+ const env = new MockActivityEnvironment ( { } , { logger : mockLogger } ) ;
104
109
env . on ( 'heartbeat' , ( ) => env . cancel ( ) ) ;
105
110
try {
106
111
await env . run ( async ( ) => {
@@ -116,7 +121,7 @@ test('Activity Worker logs when activity is cancelled with signal', async (t) =>
116
121
t . not ( entry , undefined ) ;
117
122
const { durationMs, ...rest } = entry ?. meta ?? { } ;
118
123
t . true ( Number . isInteger ( durationMs ) ) ;
119
- t . deepEqual ( rest , activityLogAttributes ( defaultActivityInfo ) ) ;
124
+ t . deepEqual ( rest , { ... activityLogAttributes ( defaultActivityInfo ) , sdkComponent : SdkComponent . worker } ) ;
120
125
} ) ;
121
126
122
127
test ( '(Legacy) ActivityInboundLogInterceptor does not override Context.log by default' , async ( t ) => {
@@ -125,6 +130,7 @@ test('(Legacy) ActivityInboundLogInterceptor does not override Context.log by de
125
130
{
126
131
// eslint-disable-next-line deprecation/deprecation
127
132
interceptors : [ ( ctx ) => ( { inbound : new ActivityInboundLogInterceptor ( ctx ) } ) ] ,
133
+ logger : mockLogger ,
128
134
}
129
135
) ;
130
136
await env . run ( async ( ) => {
@@ -146,15 +152,14 @@ test('(Legacy) ActivityInboundLogInterceptor overrides Context.log if a logger i
146
152
{
147
153
// eslint-disable-next-line deprecation/deprecation
148
154
interceptors : [ ( ctx ) => ( { inbound : new ActivityInboundLogInterceptor ( ctx , logger ) } ) ] ,
155
+ logger : mockLogger ,
149
156
}
150
157
) ;
151
158
await env . run ( async ( ) => {
152
159
activity . log . debug ( 'log message from activity' ) ;
153
160
} ) ;
154
- const entry1 = logs . find ( ( x ) => x . level === 'DEBUG' && x . message === 'Activity started' ) ;
155
- t . not ( entry1 , undefined ) ;
156
- const entry2 = logs . find ( ( x ) => x . level === 'DEBUG' && x . message === 'log message from activity' ) ;
157
- t . not ( entry2 , undefined ) ;
161
+ const entry = logs . find ( ( x ) => x . level === 'DEBUG' && x . message === 'log message from activity' ) ;
162
+ t . not ( entry , undefined ) ;
158
163
} ) ;
159
164
160
165
test ( '(Legacy) ActivityInboundLogInterceptor overrides Context.log if class is extended' , async ( t ) => {
@@ -172,6 +177,7 @@ test('(Legacy) ActivityInboundLogInterceptor overrides Context.log if class is e
172
177
{ } ,
173
178
{
174
179
interceptors : [ ( ctx ) => ( { inbound : new CustomActivityInboundLogInterceptor ( ctx ) } ) ] ,
180
+ logger : mockLogger ,
175
181
}
176
182
) ;
177
183
await env . run ( async ( ) => {
0 commit comments