Skip to content

Commit e19d883

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 77b3f0b commit e19d883

File tree

3 files changed

+727
-0
lines changed

3 files changed

+727
-0
lines changed
Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
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+
void check_assertions(/* int spansNumber, */ boolean hasMorePages, Integer rowsCount) {
203+
assertEquals(spans.size(), 3);
204+
205+
TracingInfo rootSpan = getRoot(spans);
206+
assertTrue(rootSpan instanceof TestTracingInfo);
207+
TestTracingInfo root = (TestTracingInfo) rootSpan;
208+
209+
assertTrue(root.isSpanStarted());
210+
assertTrue(root.isSpanFinished());
211+
assertEquals(root.getStatusCode(), TracingInfo.StatusCode.OK);
212+
213+
// these tags should be set for request span
214+
assertEquals(root.getStatementType(), "regular");
215+
assertNull(root.getBatchSize());
216+
assertEquals(root.getConsistencyLevel(), ConsistencyLevel.QUORUM);
217+
assertEquals(root.getRowsCount(), rowsCount); // no rows are returned in insert
218+
assertTrue(root.getLoadBalancingPolicy() instanceof PagingOptimizingLoadBalancingPolicy);
219+
assertTrue(root.getSpeculativeExecutionPolicy() instanceof NoSpeculativeExecutionPolicy);
220+
assertTrue(root.getRetryPolicy() == FallthroughRetryPolicy.INSTANCE);
221+
assertEquals(root.getFetchSize(), new Integer(2));
222+
assertEquals(root.getHasMorePages(), new Boolean(hasMorePages));
223+
assertNull(root.getStatement()); // because of precision level NORMAL
224+
225+
// these are tags specific to bound statement
226+
assertNull(root.getKeyspace());
227+
assertNull(root.getPartitionKey());
228+
assertNull(root.getTable());
229+
230+
// these tags should not be set for request span
231+
assertNull(root.getPeerName());
232+
assertNull(root.getPeerIP());
233+
assertNull(root.getPeerPort());
234+
assertNull(root.getAttemptCount());
235+
236+
ArrayList<TracingInfo> speculativeExecutions = getChildren(spans, root);
237+
assertTrue(speculativeExecutions.size() > 0);
238+
239+
for (TracingInfo speculativeExecutionSpan : speculativeExecutions) {
240+
assertTrue(speculativeExecutionSpan instanceof TestTracingInfo);
241+
TestTracingInfo tracingInfo = (TestTracingInfo) speculativeExecutionSpan;
242+
243+
// these tags should not be set for speculative execution span
244+
assertNull(tracingInfo.getStatementType());
245+
assertNull(tracingInfo.getBatchSize());
246+
assertNull(tracingInfo.getConsistencyLevel());
247+
assertNull(tracingInfo.getRowsCount());
248+
assertNull(tracingInfo.getLoadBalancingPolicy());
249+
assertNull(tracingInfo.getRetryPolicy());
250+
assertNull(tracingInfo.getFetchSize());
251+
assertNull(tracingInfo.getHasMorePages());
252+
assertNull(tracingInfo.getStatement());
253+
assertNull(tracingInfo.getPeerName());
254+
assertNull(tracingInfo.getPeerIP());
255+
assertNull(tracingInfo.getPeerPort());
256+
// these are tags specific to bound statement
257+
assertNull(tracingInfo.getKeyspace());
258+
assertNull(tracingInfo.getPartitionKey());
259+
assertNull(tracingInfo.getTable());
260+
261+
// this tag should be set for speculative execution span
262+
assertTrue(tracingInfo.getAttemptCount() >= 1);
263+
}
264+
265+
ArrayList<TracingInfo> attempts = new ArrayList<TracingInfo>();
266+
for (TracingInfo tracingInfo : speculativeExecutions) {
267+
attempts.addAll(getChildren(spans, tracingInfo));
268+
}
269+
assertTrue(attempts.size() > 0);
270+
271+
for (TracingInfo attemptSpan : attempts) {
272+
assertTrue(attemptSpan instanceof TestTracingInfo);
273+
TestTracingInfo tracingInfo = (TestTracingInfo) attemptSpan;
274+
275+
// these tags should not be set for attempt span
276+
assertNull(tracingInfo.getStatementType());
277+
assertNull(tracingInfo.getBatchSize());
278+
assertNull(tracingInfo.getConsistencyLevel());
279+
assertNull(tracingInfo.getRowsCount());
280+
assertNull(tracingInfo.getLoadBalancingPolicy());
281+
assertNull(tracingInfo.getRetryPolicy());
282+
assertNull(tracingInfo.getFetchSize());
283+
assertNull(tracingInfo.getHasMorePages());
284+
assertNull(tracingInfo.getStatement());
285+
assertNull(tracingInfo.getAttemptCount());
286+
// these are tags specific to bound statement
287+
assertNull(tracingInfo.getKeyspace());
288+
assertNull(tracingInfo.getPartitionKey());
289+
assertNull(tracingInfo.getTable());
290+
291+
// these tags should be set for attempt span
292+
assertNotNull(tracingInfo.getPeerName());
293+
assertNotNull(tracingInfo.getPeerIP());
294+
assertNotNull(tracingInfo.getPeerPort());
295+
assertTrue(tracingInfo.getPeerPort() >= 0 && tracingInfo.getPeerPort() <= 65535);
296+
}
297+
298+
spans.clear();
299+
}
300+
}
301+
302+
SpanChecks spanChecks = new SpanChecks();
303+
304+
try {
305+
ResultSet rs = session.execute(s); // first 2 rows
306+
spanChecks.check_assertions(true, 2);
307+
308+
rs = rs.fetchMoreResults().get(); // next 2 rows
309+
spanChecks.check_assertions(true, 2);
310+
311+
rs.fetchMoreResults().get(); // next 2 rows
312+
spanChecks.check_assertions(true, 2);
313+
314+
rs.fetchMoreResults().get(); // last 1 row
315+
spanChecks.check_assertions(false, 1);
316+
317+
} catch (InterruptedException e) {
318+
assert false : "InterruptedException";
319+
} catch (ExecutionException e) {
320+
assert false : "ExecutionException";
321+
}
322+
}
323+
324+
private void initializeTestTracing() {
325+
testTracingInfoFactory = new TestTracingInfoFactory(PrecisionLevel.NORMAL);
326+
cluster().setTracingInfoFactory(testTracingInfoFactory);
327+
session = cluster().connect();
328+
}
329+
330+
private TracingInfo getRoot(Collection<TracingInfo> spans) {
331+
TracingInfo root = null;
332+
for (TracingInfo tracingInfo : spans) {
333+
if (tracingInfo instanceof TestTracingInfo
334+
&& ((TestTracingInfo) tracingInfo).getParent() == null) {
335+
assertNull(root); // There should be only one root.
336+
root = tracingInfo;
337+
}
338+
}
339+
340+
return root;
341+
}
342+
343+
private ArrayList<TracingInfo> getChildren(Collection<TracingInfo> spans, TracingInfo parent) {
344+
ArrayList<TracingInfo> children = new ArrayList<TracingInfo>();
345+
for (TracingInfo tracingInfo : spans) {
346+
if (tracingInfo instanceof TestTracingInfo
347+
&& ((TestTracingInfo) tracingInfo).getParent() == parent) {
348+
children.add(tracingInfo);
349+
}
350+
}
351+
return children;
352+
}
353+
}

0 commit comments

Comments
 (0)