Skip to content

Commit 8e76fa1

Browse files
committed
Tracing: added abstract-based unit tests
These tests verify that the span tree structure is valid and that spans are filled with tags of proper content, by providing a mock implementation of TracingInfo.
1 parent d0d73ac commit 8e76fa1

File tree

3 files changed

+731
-0
lines changed

3 files changed

+731
-0
lines changed
Lines changed: 357 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
/*
2+
* Copyright (C) 2021 ScyllaDB
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.datastax.driver.core.tracing;
18+
19+
import static org.junit.Assert.assertNotNull;
20+
import static org.testng.Assert.assertEquals;
21+
import static org.testng.Assert.assertNotEquals;
22+
import static org.testng.Assert.assertNull;
23+
import static org.testng.Assert.assertTrue;
24+
25+
import com.datastax.driver.core.BoundStatement;
26+
import com.datastax.driver.core.CCMTestsSupport;
27+
import com.datastax.driver.core.ConsistencyLevel;
28+
import com.datastax.driver.core.PreparedStatement;
29+
import com.datastax.driver.core.ResultSet;
30+
import com.datastax.driver.core.Session;
31+
import com.datastax.driver.core.SimpleStatement;
32+
import com.datastax.driver.core.policies.DefaultRetryPolicy;
33+
import com.datastax.driver.core.policies.FallthroughRetryPolicy;
34+
import com.datastax.driver.core.policies.NoSpeculativeExecutionPolicy;
35+
import com.datastax.driver.core.policies.PagingOptimizingLoadBalancingPolicy;
36+
import java.util.ArrayList;
37+
import java.util.Collection;
38+
import java.util.concurrent.ExecutionException;
39+
import org.testng.annotations.Test;
40+
41+
public class BasicTracingTest extends CCMTestsSupport {
42+
private static TestTracingInfoFactory testTracingInfoFactory;
43+
private Session session;
44+
45+
@Override
46+
public void onTestContextInitialized() {
47+
initializeTestTracing();
48+
session.execute("USE " + keyspace);
49+
session.execute("DROP TABLE IF EXISTS t");
50+
session.execute("CREATE TABLE t (k int PRIMARY KEY, v int)");
51+
session.execute("INSERT INTO t(k, v) VALUES (2, 3)");
52+
session.execute("INSERT INTO t(k, v) VALUES (1, 7)");
53+
session.execute("INSERT INTO t(k, v) VALUES (5, 7)");
54+
session.execute("INSERT INTO t(k, v) VALUES (6, 7)");
55+
session.execute("INSERT INTO t(k, v) VALUES (7, 7)");
56+
session.execute("INSERT INTO t(k, v) VALUES (8, 7)");
57+
session.execute("INSERT INTO t(k, v) VALUES (9, 7)");
58+
session.execute("INSERT INTO t(k, v) VALUES (10, 7)");
59+
60+
Collection<TracingInfo> spans = testTracingInfoFactory.getSpans();
61+
spans.clear();
62+
}
63+
64+
@Test(groups = "short")
65+
public void simpleTracingTest() {
66+
session.execute("INSERT INTO t(k, v) VALUES (4, 5)");
67+
68+
Collection<TracingInfo> spans = testTracingInfoFactory.getSpans();
69+
assertNotEquals(spans.size(), 0);
70+
71+
TracingInfo rootSpan = getRoot(spans);
72+
assertTrue(rootSpan instanceof TestTracingInfo);
73+
TestTracingInfo root = (TestTracingInfo) rootSpan;
74+
75+
assertTrue(root.isSpanStarted());
76+
assertTrue(root.isSpanFinished());
77+
assertEquals(root.getStatusCode(), TracingInfo.StatusCode.OK);
78+
79+
spans.clear();
80+
}
81+
82+
@Test(groups = "short")
83+
public void tagsInsertTest() {
84+
PreparedStatement prepared = session.prepare("INSERT INTO t(k, v) VALUES (?, ?)");
85+
86+
Collection<TracingInfo> prepareSpans = testTracingInfoFactory.getSpans();
87+
assertNotEquals(prepareSpans.size(), 0);
88+
assertTrue(getRoot(prepareSpans) instanceof TestTracingInfo);
89+
prepareSpans.clear();
90+
91+
BoundStatement bound = prepared.bind(1, 7);
92+
session.execute(bound);
93+
94+
Collection<TracingInfo> spans = testTracingInfoFactory.getSpans();
95+
assertNotEquals(spans.size(), 0);
96+
97+
TracingInfo rootSpan = getRoot(spans);
98+
assertTrue(rootSpan instanceof TestTracingInfo);
99+
TestTracingInfo root = (TestTracingInfo) rootSpan;
100+
101+
assertTrue(root.isSpanStarted());
102+
assertTrue(root.isSpanFinished());
103+
assertEquals(root.getStatusCode(), TracingInfo.StatusCode.OK);
104+
105+
// these tags should be set for request span
106+
assertEquals(root.getStatementType(), "prepared");
107+
assertNull(root.getBatchSize());
108+
assertEquals(root.getConsistencyLevel(), ConsistencyLevel.ONE);
109+
assertNull(root.getRowsCount()); // no rows are returned in INSERT
110+
assertTrue(root.getLoadBalancingPolicy() instanceof PagingOptimizingLoadBalancingPolicy);
111+
assertTrue(root.getSpeculativeExecutionPolicy() instanceof NoSpeculativeExecutionPolicy);
112+
assertTrue(root.getRetryPolicy() instanceof DefaultRetryPolicy);
113+
assertNull(root.getFetchSize()); // fetch size was not explicitly set for this statement
114+
assertNull(root.getHasMorePages()); // no paging are returned in INSERT
115+
assertNull(root.getStatement()); // because of precision level NORMAL
116+
// these are tags specific to bound statement
117+
assertEquals(root.getKeyspace(), keyspace);
118+
assertEquals(root.getPartitionKey(), "k=1");
119+
assertEquals(root.getTable(), "t");
120+
121+
// these tags should not be set for request span
122+
assertNull(root.getPeerName());
123+
assertNull(root.getPeerIP());
124+
assertNull(root.getPeerPort());
125+
assertNull(root.getAttemptCount());
126+
127+
ArrayList<TracingInfo> speculativeExecutions = getChildren(spans, root);
128+
assertTrue(speculativeExecutions.size() > 0);
129+
130+
for (TracingInfo speculativeExecutionSpan : speculativeExecutions) {
131+
assertTrue(speculativeExecutionSpan instanceof TestTracingInfo);
132+
TestTracingInfo tracingInfo = (TestTracingInfo) speculativeExecutionSpan;
133+
134+
// these tags should not be set for speculative execution span
135+
assertNull(tracingInfo.getStatementType());
136+
assertNull(tracingInfo.getBatchSize());
137+
assertNull(tracingInfo.getConsistencyLevel());
138+
assertNull(tracingInfo.getRowsCount());
139+
assertNull(tracingInfo.getLoadBalancingPolicy());
140+
assertNull(tracingInfo.getRetryPolicy());
141+
assertNull(tracingInfo.getFetchSize());
142+
assertNull(tracingInfo.getHasMorePages());
143+
assertNull(tracingInfo.getStatement());
144+
assertNull(tracingInfo.getPeerName());
145+
assertNull(tracingInfo.getPeerIP());
146+
assertNull(tracingInfo.getPeerPort());
147+
// these are tags specific to bound statement
148+
assertNull(tracingInfo.getKeyspace());
149+
assertNull(tracingInfo.getPartitionKey());
150+
assertNull(tracingInfo.getTable());
151+
152+
// this tag should be set for speculative execution span
153+
assertTrue(tracingInfo.getAttemptCount() >= 1);
154+
}
155+
156+
ArrayList<TracingInfo> attempts = new ArrayList<TracingInfo>();
157+
for (TracingInfo tracingInfo : speculativeExecutions) {
158+
attempts.addAll(getChildren(spans, tracingInfo));
159+
}
160+
assertTrue(attempts.size() > 0);
161+
162+
for (TracingInfo attemptSpan : attempts) {
163+
assertTrue(attemptSpan instanceof TestTracingInfo);
164+
TestTracingInfo tracingInfo = (TestTracingInfo) attemptSpan;
165+
166+
// these tags should not be set for attempt span
167+
assertNull(tracingInfo.getStatementType());
168+
assertNull(tracingInfo.getBatchSize());
169+
assertNull(tracingInfo.getConsistencyLevel());
170+
assertNull(tracingInfo.getRowsCount());
171+
assertNull(tracingInfo.getLoadBalancingPolicy());
172+
assertNull(tracingInfo.getRetryPolicy());
173+
assertNull(tracingInfo.getFetchSize());
174+
assertNull(tracingInfo.getHasMorePages());
175+
assertNull(tracingInfo.getStatement());
176+
assertNull(tracingInfo.getAttemptCount());
177+
// these are tags specific to bound statement
178+
assertNull(tracingInfo.getKeyspace());
179+
assertNull(tracingInfo.getPartitionKey());
180+
assertNull(tracingInfo.getTable());
181+
182+
// these tags should be set for attempt span
183+
assertNotNull(tracingInfo.getPeerName());
184+
assertNotNull(tracingInfo.getPeerIP());
185+
assertNotNull(tracingInfo.getPeerPort());
186+
assertTrue(tracingInfo.getPeerPort() >= 0 && tracingInfo.getPeerPort() <= 65535);
187+
}
188+
189+
spans.clear();
190+
}
191+
192+
@Test(groups = "short")
193+
public void tagsSelectTest() {
194+
SimpleStatement s = new SimpleStatement("SELECT k FROM t WHERE v = 7 ALLOW FILTERING");
195+
s.setFetchSize(2);
196+
s.setIdempotent(true);
197+
s.setRetryPolicy(FallthroughRetryPolicy.INSTANCE);
198+
s.setConsistencyLevel(ConsistencyLevel.QUORUM);
199+
200+
final Collection<TracingInfo> spans = testTracingInfoFactory.getSpans();
201+
class SpanChecks {
202+
int totalRows = 0;
203+
204+
void checkTotalCount() {
205+
assertEquals(totalRows, 7);
206+
}
207+
208+
void checkAssertions(boolean hasMorePages) {
209+
assertEquals(spans.size(), 3);
210+
211+
TracingInfo rootSpan = getRoot(spans);
212+
assertTrue(rootSpan instanceof TestTracingInfo);
213+
TestTracingInfo root = (TestTracingInfo) rootSpan;
214+
215+
assertTrue(root.isSpanStarted());
216+
assertTrue(root.isSpanFinished());
217+
assertEquals(root.getStatusCode(), TracingInfo.StatusCode.OK);
218+
219+
// these tags should be set for request span
220+
assertEquals(root.getStatementType(), "regular");
221+
assertNull(root.getBatchSize());
222+
assertEquals(root.getConsistencyLevel(), ConsistencyLevel.QUORUM);
223+
assertNotNull(root.getRowsCount());
224+
totalRows += root.getRowsCount();
225+
assertTrue(root.getLoadBalancingPolicy() instanceof PagingOptimizingLoadBalancingPolicy);
226+
assertTrue(root.getSpeculativeExecutionPolicy() instanceof NoSpeculativeExecutionPolicy);
227+
assertTrue(root.getRetryPolicy() == FallthroughRetryPolicy.INSTANCE);
228+
assertEquals(root.getFetchSize(), new Integer(2));
229+
assertEquals(root.getHasMorePages(), new Boolean(hasMorePages));
230+
assertNull(root.getStatement()); // because of precision level NORMAL
231+
232+
// these are tags specific to bound statement
233+
assertNull(root.getKeyspace());
234+
assertNull(root.getPartitionKey());
235+
assertNull(root.getTable());
236+
237+
// these tags should not be set for request span
238+
assertNull(root.getPeerName());
239+
assertNull(root.getPeerIP());
240+
assertNull(root.getPeerPort());
241+
assertNull(root.getAttemptCount());
242+
243+
ArrayList<TracingInfo> speculativeExecutions = getChildren(spans, root);
244+
assertTrue(speculativeExecutions.size() > 0);
245+
246+
for (TracingInfo speculativeExecutionSpan : speculativeExecutions) {
247+
assertTrue(speculativeExecutionSpan instanceof TestTracingInfo);
248+
TestTracingInfo tracingInfo = (TestTracingInfo) speculativeExecutionSpan;
249+
250+
// these tags should not be set for speculative execution span
251+
assertNull(tracingInfo.getStatementType());
252+
assertNull(tracingInfo.getBatchSize());
253+
assertNull(tracingInfo.getConsistencyLevel());
254+
assertNull(tracingInfo.getRowsCount());
255+
assertNull(tracingInfo.getLoadBalancingPolicy());
256+
assertNull(tracingInfo.getRetryPolicy());
257+
assertNull(tracingInfo.getFetchSize());
258+
assertNull(tracingInfo.getHasMorePages());
259+
assertNull(tracingInfo.getStatement());
260+
assertNull(tracingInfo.getPeerName());
261+
assertNull(tracingInfo.getPeerIP());
262+
assertNull(tracingInfo.getPeerPort());
263+
// these are tags specific to bound statement
264+
assertNull(tracingInfo.getKeyspace());
265+
assertNull(tracingInfo.getPartitionKey());
266+
assertNull(tracingInfo.getTable());
267+
268+
// this tag should be set for speculative execution span
269+
assertTrue(tracingInfo.getAttemptCount() >= 1);
270+
}
271+
272+
ArrayList<TracingInfo> attempts = new ArrayList<TracingInfo>();
273+
for (TracingInfo tracingInfo : speculativeExecutions) {
274+
attempts.addAll(getChildren(spans, tracingInfo));
275+
}
276+
assertTrue(attempts.size() > 0);
277+
278+
for (TracingInfo attemptSpan : attempts) {
279+
assertTrue(attemptSpan instanceof TestTracingInfo);
280+
TestTracingInfo tracingInfo = (TestTracingInfo) attemptSpan;
281+
282+
// these tags should not be set for attempt span
283+
assertNull(tracingInfo.getStatementType());
284+
assertNull(tracingInfo.getBatchSize());
285+
assertNull(tracingInfo.getConsistencyLevel());
286+
assertNull(tracingInfo.getRowsCount());
287+
assertNull(tracingInfo.getLoadBalancingPolicy());
288+
assertNull(tracingInfo.getRetryPolicy());
289+
assertNull(tracingInfo.getFetchSize());
290+
assertNull(tracingInfo.getHasMorePages());
291+
assertNull(tracingInfo.getStatement());
292+
assertNull(tracingInfo.getAttemptCount());
293+
// these are tags specific to bound statement
294+
assertNull(tracingInfo.getKeyspace());
295+
assertNull(tracingInfo.getPartitionKey());
296+
assertNull(tracingInfo.getTable());
297+
298+
// these tags should be set for attempt span
299+
assertNotNull(tracingInfo.getPeerName());
300+
assertNotNull(tracingInfo.getPeerIP());
301+
assertNotNull(tracingInfo.getPeerPort());
302+
assertTrue(tracingInfo.getPeerPort() >= 0 && tracingInfo.getPeerPort() <= 65535);
303+
}
304+
305+
spans.clear();
306+
}
307+
}
308+
309+
SpanChecks spanChecks = new SpanChecks();
310+
311+
try {
312+
ResultSet rs = session.execute(s);
313+
314+
while (!rs.isFullyFetched()) {
315+
spanChecks.checkAssertions(true);
316+
rs.fetchMoreResults().get();
317+
}
318+
spanChecks.checkAssertions(false);
319+
320+
} catch (InterruptedException e) {
321+
assert false : "InterruptedException";
322+
} catch (ExecutionException e) {
323+
assert false : "ExecutionException";
324+
}
325+
spanChecks.checkTotalCount();
326+
}
327+
328+
private void initializeTestTracing() {
329+
testTracingInfoFactory = new TestTracingInfoFactory(PrecisionLevel.NORMAL);
330+
cluster().setTracingInfoFactory(testTracingInfoFactory);
331+
session = cluster().connect();
332+
}
333+
334+
private TracingInfo getRoot(Collection<TracingInfo> spans) {
335+
TracingInfo root = null;
336+
for (TracingInfo tracingInfo : spans) {
337+
if (tracingInfo instanceof TestTracingInfo
338+
&& ((TestTracingInfo) tracingInfo).getParent() == null) {
339+
assertNull(root); // There should be only one root.
340+
root = tracingInfo;
341+
}
342+
}
343+
344+
return root;
345+
}
346+
347+
private ArrayList<TracingInfo> getChildren(Collection<TracingInfo> spans, TracingInfo parent) {
348+
ArrayList<TracingInfo> children = new ArrayList<TracingInfo>();
349+
for (TracingInfo tracingInfo : spans) {
350+
if (tracingInfo instanceof TestTracingInfo
351+
&& ((TestTracingInfo) tracingInfo).getParent() == parent) {
352+
children.add(tracingInfo);
353+
}
354+
}
355+
return children;
356+
}
357+
}

0 commit comments

Comments
 (0)