11package com .datadog .debugger .sink ;
22
3+ import static com .datadog .debugger .sink .SymbolSink .MAX_SYMDB_UPLOAD_SIZE ;
4+ import static java .util .Collections .singletonList ;
35import static org .junit .jupiter .api .Assertions .*;
46import static org .mockito .Mockito .mock ;
57import static org .mockito .Mockito .when ;
1012import datadog .trace .api .Config ;
1113import java .util .ArrayList ;
1214import java .util .Arrays ;
15+ import java .util .Collections ;
1316import java .util .List ;
17+ import org .jetbrains .annotations .NotNull ;
1418import org .junit .jupiter .api .Test ;
1519
1620class SymbolSinkTest {
@@ -20,7 +24,7 @@ public void testSimpleFlush() {
2024 SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
2125 Config config = mock (Config .class );
2226 when (config .getServiceName ()).thenReturn ("service1" );
23- SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock );
27+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , MAX_SYMDB_UPLOAD_SIZE );
2428 symbolSink .addScope (Scope .builder (ScopeType .JAR , null , 0 , 0 ).build ());
2529 symbolSink .flush ();
2630 assertEquals (2 , symbolUploaderMock .multiPartContents .size ());
@@ -43,17 +47,13 @@ public void testMultiScopeFlush() {
4347 SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
4448 Config config = mock (Config .class );
4549 when (config .getServiceName ()).thenReturn ("service1" );
46- SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock );
50+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , MAX_SYMDB_UPLOAD_SIZE );
4751 symbolSink .addScope (Scope .builder (ScopeType .JAR , "jar1.jar" , 0 , 0 ).build ());
4852 symbolSink .addScope (Scope .builder (ScopeType .JAR , "jar2.jar" , 0 , 0 ).build ());
4953 symbolSink .flush ();
5054 // only 1 request because we are batching the scopes
5155 assertEquals (2 , symbolUploaderMock .multiPartContents .size ());
52- BatchUploader .MultiPartContent eventContent = symbolUploaderMock .multiPartContents .get (0 );
53- assertEquals ("event" , eventContent .getPartName ());
54- BatchUploader .MultiPartContent symbolContent = symbolUploaderMock .multiPartContents .get (1 );
55- assertEquals ("file" , symbolContent .getPartName ());
56- String strContent = new String (symbolContent .getContent ());
56+ String strContent = assertMultipartContent (symbolUploaderMock , 0 );
5757 assertTrue (strContent .contains ("\" source_file\" :\" jar1.jar\" " ));
5858 assertTrue (strContent .contains ("\" source_file\" :\" jar2.jar\" " ));
5959 }
@@ -63,7 +63,7 @@ public void testQueueFull() {
6363 SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
6464 Config config = mock (Config .class );
6565 when (config .getServiceName ()).thenReturn ("service1" );
66- SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock );
66+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , MAX_SYMDB_UPLOAD_SIZE );
6767 for (int i = 0 ; i < SymbolSink .CAPACITY ; i ++) {
6868 symbolSink .addScope (Scope .builder (ScopeType .JAR , "jar1.jar" , 0 , 0 ).build ());
6969 }
@@ -81,6 +81,131 @@ public void testQueueFull() {
8181 .contains ("\" source_file\" :\" jar2.jar\" " ));
8282 }
8383
84+ @ Test
85+ public void splitByJarScopes () {
86+ SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
87+ Config config = mock (Config .class );
88+ when (config .getServiceName ()).thenReturn ("service1" );
89+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , 1024 );
90+ final int NUM_JAR_SCOPES = 10 ;
91+ for (int i = 0 ; i < NUM_JAR_SCOPES ; i ++) {
92+ symbolSink .addScope (
93+ Scope .builder (ScopeType .JAR , "jar" + i + ".jar" , 0 , 0 )
94+ .scopes (singletonList (Scope .builder (ScopeType .CLASS , "class" + i , 0 , 0 ).build ()))
95+ .build ());
96+ }
97+ symbolSink .flush ();
98+ // split upload request per jar scope
99+ assertEquals (NUM_JAR_SCOPES * 2 , symbolUploaderMock .multiPartContents .size ());
100+ for (int i = 0 ; i < NUM_JAR_SCOPES * 2 ; i += 2 ) {
101+ String strContent = assertMultipartContent (symbolUploaderMock , i );
102+ assertTrue (strContent .contains ("\" source_file\" :\" jar" + (i / 2 ) + ".jar\" " ));
103+ }
104+ }
105+
106+ @ Test
107+ public void splitTootManyJarScopes () {
108+ SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
109+ Config config = mock (Config .class );
110+ when (config .getServiceName ()).thenReturn ("service1" );
111+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , 2048 );
112+ final int NUM_JAR_SCOPES = 21 ;
113+ for (int i = 0 ; i < NUM_JAR_SCOPES ; i ++) {
114+ symbolSink .addScope (
115+ Scope .builder (ScopeType .JAR , "jar" + i + ".jar" , 0 , 0 )
116+ .scopes (singletonList (Scope .builder (ScopeType .CLASS , "class" + i , 0 , 0 ).build ()))
117+ .build ());
118+ }
119+ symbolSink .flush ();
120+ // split upload request per half jar scopes
121+ assertEquals (2 * 2 , symbolUploaderMock .multiPartContents .size ());
122+ String strContent1 = assertMultipartContent (symbolUploaderMock , 0 );
123+ assertTrue (strContent1 .contains ("\" source_file\" :\" jar0.jar\" " ));
124+ assertTrue (strContent1 .contains ("\" source_file\" :\" jar9.jar\" " ));
125+ String strContent2 = assertMultipartContent (symbolUploaderMock , 2 );
126+ assertTrue (strContent2 .contains ("\" source_file\" :\" jar10.jar\" " ));
127+ assertTrue (strContent2 .contains ("\" source_file\" :\" jar20.jar\" " ));
128+ }
129+
130+ @ Test
131+ public void splitByClassScopes () {
132+ SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
133+ Config config = mock (Config .class );
134+ when (config .getServiceName ()).thenReturn ("service1" );
135+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , 1024 );
136+ final int NUM_CLASS_SCOPES = 10 ;
137+ List <Scope > classScopes = new ArrayList <>();
138+ for (int i = 0 ; i < NUM_CLASS_SCOPES ; i ++) {
139+ classScopes .add (
140+ Scope .builder (ScopeType .CLASS , "class" + i , 0 , 0 )
141+ .scopes (
142+ Collections .singletonList (
143+ Scope .builder (ScopeType .METHOD , "class" + i , 0 , 0 )
144+ .name ("method" + i )
145+ .build ()))
146+ .build ());
147+ }
148+ symbolSink .addScope (
149+ Scope .builder (ScopeType .JAR , "jar1.jar" , 0 , 0 )
150+ .name ("jar1.jar" )
151+ .scopes (classScopes )
152+ .build ());
153+ symbolSink .flush ();
154+ // split upload request per jar scope
155+ final int EXPECTED_REQUESTS = 4 ;
156+ assertEquals (EXPECTED_REQUESTS * 2 , symbolUploaderMock .multiPartContents .size ());
157+ List <List <String >> expectedSourceFiles =
158+ Arrays .asList (
159+ Arrays .asList ("class0" , "class1" ),
160+ Arrays .asList ("class2" , "class3" , "class4" ),
161+ Arrays .asList ("class5" , "class6" ),
162+ Arrays .asList ("class7" , "class8" , "class9" ));
163+ for (int i = 0 ; i < EXPECTED_REQUESTS * 2 ; i += 2 ) {
164+ String strContent = assertMultipartContent (symbolUploaderMock , i );
165+ for (String sourceFile : expectedSourceFiles .get (i / 2 )) {
166+ assertTrue (strContent .contains ("\" source_file\" :\" " + sourceFile + "\" " ));
167+ }
168+ }
169+ }
170+
171+ @ Test
172+ public void splitByClassScopesImpossible () {
173+ SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock ();
174+ Config config = mock (Config .class );
175+ when (config .getServiceName ()).thenReturn ("service1" );
176+ SymbolSink symbolSink = new SymbolSink (config , symbolUploaderMock , 1 );
177+ final int NUM_CLASS_SCOPES = 10 ;
178+ List <Scope > classScopes = new ArrayList <>();
179+ for (int i = 0 ; i < NUM_CLASS_SCOPES ; i ++) {
180+ classScopes .add (
181+ Scope .builder (ScopeType .CLASS , "class" + i , 0 , 0 )
182+ .scopes (
183+ Collections .singletonList (
184+ Scope .builder (ScopeType .METHOD , "class" + i , 0 , 0 )
185+ .name ("method" + i )
186+ .build ()))
187+ .build ());
188+ }
189+ symbolSink .addScope (
190+ Scope .builder (ScopeType .JAR , "jar1.jar" , 0 , 0 )
191+ .name ("jar1.jar" )
192+ .scopes (classScopes )
193+ .build ());
194+ symbolSink .flush ();
195+ // no request to upload because we cannot split the jar scope
196+ assertTrue (symbolUploaderMock .multiPartContents .isEmpty ());
197+ }
198+
199+ @ NotNull
200+ private static String assertMultipartContent (SymbolUploaderMock symbolUploaderMock , int index ) {
201+ BatchUploader .MultiPartContent eventContent = symbolUploaderMock .multiPartContents .get (index );
202+ assertEquals ("event" , eventContent .getPartName ());
203+ BatchUploader .MultiPartContent symbolContent =
204+ symbolUploaderMock .multiPartContents .get (index + 1 );
205+ assertEquals ("file" , symbolContent .getPartName ());
206+ return new String (symbolContent .getContent ());
207+ }
208+
84209 static class SymbolUploaderMock extends BatchUploader {
85210 final List <MultiPartContent > multiPartContents = new ArrayList <>();
86211
0 commit comments