1
+ // Licensed to the .NET Foundation under one or more agreements.
2
+ // The .NET Foundation licenses this file to you under the MIT license.
3
+ // See the LICENSE file in the project root for more information.
4
+
5
+ using System ;
6
+ using System . Diagnostics . Tracing ;
7
+ using System . IO ;
8
+ using System . Linq ;
9
+ using System . Threading ;
10
+ using System . Threading . Tasks ;
11
+ using System . Collections . Generic ;
12
+ using Microsoft . Diagnostics . NETCore . Client ;
13
+ using Microsoft . Diagnostics . Tools . RuntimeClient ;
14
+ using Microsoft . Diagnostics . Tracing ;
15
+ using Microsoft . Diagnostics . Tracing . Parsers ;
16
+ using Tracing . Tests . Common ;
17
+ using Microsoft . Diagnostics . Tracing . Parsers . Clr ;
18
+
19
+ namespace Tracing . Tests . EventSourceError
20
+ {
21
+ public class GCDumpTest
22
+ {
23
+ private static int _bulkTypeCount = 0 ;
24
+ private static int _bulkNodeCount = 0 ;
25
+ private static int _bulkEdgeCount = 0 ;
26
+ private static int _bulkRootEdgeCount = 0 ;
27
+ private static int _bulkRootStaticVarCount = 0 ;
28
+
29
+ private static readonly ulong GC_HeapDump_Keyword = 0x100000UL ;
30
+
31
+ public static int Main ( string [ ] args )
32
+ {
33
+ // This test validates that if an EventSource generates an error
34
+ // during construction it gets emitted over EventPipe
35
+
36
+ List < Provider > providers = new List < Provider >
37
+ {
38
+ new Provider ( "Microsoft-Windows-DotNETRuntime" , eventLevel : EventLevel . Verbose , keywords : ( ulong ) ClrTraceEventParser . Keywords . GCHeapSnapshot )
39
+ } ;
40
+
41
+ var configuration = new SessionConfiguration ( circularBufferSizeMB : 1024 , format : EventPipeSerializationFormat . NetTrace , providers : providers ) ;
42
+ return IpcTraceTest . RunAndValidateEventCounts ( _expectedEventCounts , _eventGeneratingAction , configuration , _DoesRundownContainMethodEvents ) ;
43
+ }
44
+
45
+ private static Dictionary < string , ExpectedEventCount > _expectedEventCounts = new Dictionary < string , ExpectedEventCount > ( )
46
+ {
47
+ // This space intentionally left blank
48
+ } ;
49
+
50
+ private static Action _eventGeneratingAction = ( ) =>
51
+ {
52
+ // This space intentionally left blank
53
+ } ;
54
+
55
+ private static Func < EventPipeEventSource , Func < int > > _DoesRundownContainMethodEvents = ( source ) =>
56
+ {
57
+ source . Clr . TypeBulkType += ( GCBulkTypeTraceData data ) =>
58
+ {
59
+ _bulkTypeCount += data . Count ;
60
+ } ;
61
+
62
+ source . Clr . GCBulkNode += delegate ( GCBulkNodeTraceData data )
63
+ {
64
+ _bulkNodeCount += data . Count ;
65
+ } ;
66
+
67
+ source . Clr . GCBulkEdge += ( GCBulkEdgeTraceData data ) =>
68
+ {
69
+ _bulkEdgeCount += data . Count ;
70
+ } ;
71
+
72
+ source . Clr . GCBulkRootEdge += ( GCBulkRootEdgeTraceData data ) =>
73
+ {
74
+ _bulkRootEdgeCount += data . Count ;
75
+ } ;
76
+
77
+ source . Clr . GCBulkRootStaticVar += ( GCBulkRootStaticVarTraceData data ) =>
78
+ {
79
+ _bulkRootStaticVarCount += data . Count ;
80
+ } ;
81
+
82
+ return ( ) =>
83
+ {
84
+ // 50 is a safe number, comfortably less than the events we expect.
85
+ // Hopefully it is low enough to be resillient to changes in the runtime
86
+ // and high enough to catch issues.
87
+ if ( _bulkTypeCount > 50
88
+ && _bulkNodeCount > 50
89
+ && _bulkEdgeCount > 50
90
+ && _bulkRootEdgeCount > 50
91
+ && _bulkRootStaticVarCount > 50 )
92
+ {
93
+ return 100 ;
94
+ }
95
+
96
+
97
+ Console . WriteLine ( $ "Test failed due to missing GC heap events.") ;
98
+ Console . WriteLine ( $ "_bulkTypeCount = { _bulkTypeCount } ") ;
99
+ Console . WriteLine ( $ "_bulkNodeCount = { _bulkNodeCount } ") ;
100
+ Console . WriteLine ( $ "_bulkEdgeCount = { _bulkEdgeCount } ") ;
101
+ Console . WriteLine ( $ "_bulkRootEdgeCount = { _bulkRootEdgeCount } ") ;
102
+ Console . WriteLine ( $ "_bulkRootStaticVarCount = { _bulkRootStaticVarCount } ") ;
103
+ return - 1 ;
104
+ } ;
105
+ } ;
106
+ }
107
+ }
0 commit comments