Skip to content

Commit 468eb79

Browse files
tolbertamolim7t
authored andcommitted
Add tests for JAVA-852.
1 parent 4c75b91 commit 468eb79

File tree

3 files changed

+173
-40
lines changed

3 files changed

+173
-40
lines changed

driver-core/pom.xml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
limitations under the License.
1616
1717
-->
18-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
18+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
1920
<modelVersion>4.0.0</modelVersion>
2021
<parent>
2122
<groupId>com.datastax.cassandra</groupId>
@@ -25,7 +26,9 @@
2526
<artifactId>cassandra-driver-core</artifactId>
2627
<packaging>bundle</packaging>
2728
<name>DataStax Java Driver for Apache Cassandra - Core</name>
28-
<description>A driver for Apache Cassandra 1.2+ that works exclusively with the Cassandra Query Language version 3 (CQL3) and Cassandra's binary protocol.</description>
29+
<description>A driver for Apache Cassandra 1.2+ that works exclusively with the Cassandra Query Language version 3
30+
(CQL3) and Cassandra's binary protocol.
31+
</description>
2932
<url>https://github.com/datastax/java-driver</url>
3033

3134
<properties>
@@ -67,17 +70,17 @@
6770
<!-- Each of them is only a mandatory runtime dependency if you want to use the compression it offers -->
6871

6972
<dependency>
70-
<groupId>org.xerial.snappy</groupId>
71-
<artifactId>snappy-java</artifactId>
72-
<version>${snappy.version}</version>
73-
<optional>true</optional>
73+
<groupId>org.xerial.snappy</groupId>
74+
<artifactId>snappy-java</artifactId>
75+
<version>${snappy.version}</version>
76+
<optional>true</optional>
7477
</dependency>
7578

7679
<dependency>
77-
<groupId>net.jpountz.lz4</groupId>
78-
<artifactId>lz4</artifactId>
79-
<version>${lz4.version}</version>
80-
<optional>true</optional>
80+
<groupId>net.jpountz.lz4</groupId>
81+
<artifactId>lz4</artifactId>
82+
<version>${lz4.version}</version>
83+
<optional>true</optional>
8184
</dependency>
8285

8386
<!-- End of compression libraries -->
@@ -221,7 +224,9 @@
221224
<executions>
222225
<execution>
223226
<phase>package</phase>
224-
<goals><goal>shade</goal></goals>
227+
<goals>
228+
<goal>shade</goal>
229+
</goals>
225230
<configuration>
226231
<shadedArtifactAttached>true</shadedArtifactAttached>
227232
<artifactSet>
@@ -287,7 +292,7 @@
287292
</goals>
288293
</pluginExecutionFilter>
289294
<action>
290-
<ignore />
295+
<ignore/>
291296
</action>
292297
</pluginExecution>
293298
</pluginExecutions>
@@ -375,6 +380,7 @@
375380
<includes>
376381
<include>**/SSL*Test.java</include>
377382
<include>**/UUIDsPID*.java</include>
383+
<include>**/ControlConnectionTest.java</include>
378384
</includes>
379385
</configuration>
380386
</plugin>

driver-core/src/test/java/com/datastax/driver/core/ControlConnectionTest.java

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525
import com.google.common.collect.ImmutableMap;
2626
import com.google.common.collect.ImmutableSet;
2727
import com.google.common.collect.Maps;
28+
import org.apache.log4j.Level;
2829
import org.scassandra.http.client.PrimingRequest;
2930
import org.slf4j.Logger;
3031
import org.slf4j.LoggerFactory;
32+
import org.testng.annotations.DataProvider;
3133
import org.testng.annotations.Test;
3234

3335
import java.net.InetAddress;
@@ -36,6 +38,7 @@
3638
import java.util.Collection;
3739
import java.util.Iterator;
3840
import java.util.Map;
41+
import java.util.UUID;
3942
import java.util.concurrent.TimeUnit;
4043
import java.util.concurrent.atomic.AtomicInteger;
4144

@@ -219,7 +222,17 @@ public Integer apply(InetAddress input) {
219222
} finally {
220223
scassandras.stop();
221224
}
225+
}
222226

227+
@DataProvider
228+
public Object[][] disallowedNullColumnsInPeerData() {
229+
return new Object[][]{
230+
{"host_id"},
231+
{"data_center"},
232+
{"rack"},
233+
{"tokens"},
234+
{"host_id,data_center,rack,tokens"}
235+
};
223236
}
224237

225238
/**
@@ -270,6 +283,7 @@ public void should_fetch_whole_peers_table_if_broadcast_address_changed() throws
270283
.put("data_center", datacenter(1))
271284
.put("rack", "rack1")
272285
.put("release_version", "2.1.8")
286+
.put("host_id", UUID.randomUUID())
273287
.put("tokens", ImmutableSet.of(Long.toString(scassandras.getTokensForDC(1).get(1))))
274288
.build();
275289

@@ -309,7 +323,117 @@ public void should_fetch_whole_peers_table_if_broadcast_address_changed() throws
309323
cluster.close();
310324
scassandras.stop();
311325
}
326+
}
327+
328+
/**
329+
* Validates that if the com.datastax.driver.EXTENDED_PEER_CHECK system property is set to false that a peer
330+
* with null values for host_id, data_center, rack, tokens is not ignored.
331+
*
332+
* @test_category host:metadata
333+
* @jira_ticket JAVA-852
334+
* @since 2.1.10
335+
*/
336+
@Test(groups = "isolated", dataProvider = "disallowedNullColumnsInPeerData")
337+
@CCMConfig(createCcm = false)
338+
public void should_use_peer_if_extended_peer_check_is_disabled(String columns) {
339+
System.setProperty("com.datastax.driver.EXTENDED_PEER_CHECK", "false");
340+
run_with_null_peer_info(columns, true);
341+
}
342+
343+
/**
344+
* Validates that if the com.datastax.driver.EXTENDED_PEER_CHECK system property is set to true that a peer
345+
* with null values for host_id, data_center, rack, or tokens is ignored.
346+
*
347+
* @test_category host:metadata
348+
* @jira_ticket JAVA-852
349+
* @since 2.1.10
350+
*/
351+
@Test(groups = "isolated", dataProvider = "disallowedNullColumnsInPeerData")
352+
@CCMConfig(createCcm = false)
353+
public void should_ignore_peer_if_extended_peer_check_is_enabled(String columns) {
354+
System.setProperty("com.datastax.driver.EXTENDED_PEER_CHECK", "true");
355+
run_with_null_peer_info(columns, false);
356+
}
357+
358+
/**
359+
* Validates that a peer with null values for host_id, data_center, rack, or tokens is ignored.
360+
*
361+
* @test_category host:metadata
362+
* @jira_ticket JAVA-852
363+
* @since 2.1.10
364+
*/
365+
@Test(groups = "short", dataProvider = "disallowedNullColumnsInPeerData")
366+
@CCMConfig(createCcm = false)
367+
public void should_ignore_and_warn_peers_with_null_entries_by_default(String columns) {
368+
run_with_null_peer_info(columns, false);
369+
}
370+
371+
private void run_with_null_peer_info(String columns, boolean expectPeer2) {
372+
// given: A cluster with peer 2 having a null rack.
373+
ScassandraCluster.ScassandraClusterBuilder builder = ScassandraCluster.builder()
374+
.withNodes(3);
375+
376+
StringBuilder columnDataBuilder = new StringBuilder();
377+
for (String column : columns.split(",")) {
378+
builder = builder.forcePeerInfo(1, 2, column, null);
379+
columnDataBuilder.append(String.format("%s=null, ", column));
380+
}
381+
382+
String columnData = columnDataBuilder.toString();
383+
if (columnData.endsWith(", ")) {
384+
columnData = columnData.substring(0, columnData.length() - 2);
385+
}
386+
387+
ScassandraCluster scassandraCluster = builder.build();
388+
389+
Cluster cluster = Cluster.builder()
390+
.addContactPoints(scassandraCluster.address(1).getAddress())
391+
.withPort(scassandraCluster.getBinaryPort())
392+
.withNettyOptions(nonQuietClusterCloseOptions)
393+
.build();
394+
395+
// Capture logs to ensure appropriate warnings are logged.
396+
org.apache.log4j.Logger cLogger = org.apache.log4j.Logger.getLogger("com.datastax.driver.core");
397+
Level originalLevel = cLogger.getLevel();
398+
if (originalLevel != null && !originalLevel.isGreaterOrEqual(Level.WARN)) {
399+
cLogger.setLevel(Level.WARN);
400+
}
401+
MemoryAppender logs = new MemoryAppender();
402+
cLogger.addAppender(logs);
312403

404+
try {
405+
scassandraCluster.init();
406+
407+
// when: Initializing a cluster instance and grabbing metadata.
408+
cluster.init();
409+
410+
InetAddress node2Address = scassandraCluster.address(2).getAddress();
411+
String expectedError = String.format("Found invalid row in system.peers: [peer=%s, %s]. " +
412+
"This is likely a gossip or snitch issue, this host will be ignored.", node2Address, columnData);
413+
String log = logs.get();
414+
// then: A peer with a null rack should not show up in host metadata, unless allowed via system property.
415+
if (expectPeer2) {
416+
assertThat(cluster.getMetadata().getAllHosts())
417+
.hasSize(3)
418+
.extractingResultOf("getAddress")
419+
.contains(node2Address);
420+
421+
assertThat(log).doesNotContain(expectedError);
422+
} else {
423+
assertThat(cluster.getMetadata().getAllHosts())
424+
.hasSize(2)
425+
.extractingResultOf("getAddress")
426+
.doesNotContain(node2Address);
427+
428+
assertThat(log)
429+
.containsOnlyOnce(expectedError);
430+
}
431+
} finally {
432+
cLogger.removeAppender(logs);
433+
cLogger.setLevel(originalLevel);
434+
cluster.close();
435+
scassandraCluster.stop();
436+
}
313437
}
314438

315439
static class QueryPlanCountingPolicy extends DelegatingLoadBalancingPolicy {

driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,8 @@
1515
*/
1616
package com.datastax.driver.core;
1717

18-
import com.beust.jcommander.internal.Lists;
19-
import com.beust.jcommander.internal.Maps;
2018
import com.datastax.driver.core.utils.UUIDs;
21-
import com.google.common.collect.ImmutableList;
22-
import com.google.common.collect.ImmutableMap;
23-
import com.google.common.collect.ImmutableSet;
19+
import com.google.common.collect.*;
2420
import org.scassandra.Scassandra;
2521
import org.scassandra.ScassandraFactory;
2622
import org.scassandra.http.client.PrimingClient;
@@ -264,7 +260,7 @@ public List<Long> getTokensForDC(int dc) {
264260
// Offset DCs by dc * 100 to ensure unique tokens.
265261
int offset = (dc - 1) * 100;
266262
int dcNodeCount = nodes(dc).size();
267-
List<Long> tokens = Lists.newArrayList(dcNodeCount);
263+
List<Long> tokens = Lists.newArrayListWithExpectedSize(dcNodeCount);
268264
for (int i = 0; i < dcNodeCount; i++) {
269265
tokens.add((i * ((long) Math.pow(2, 64) / dcNodeCount) + offset));
270266
}
@@ -288,31 +284,30 @@ private void primeMetadata(Scassandra node) {
288284
if (node == peer) { // prime system.local.
289285
metadata = SELECT_LOCAL;
290286
query = "SELECT * FROM system.local WHERE key='local'";
291-
row = ImmutableMap.<String, Object>builder()
292-
.put("key", "local")
293-
.put("bootstrapped", "COMPLETED")
294-
.put("broadcast_address", address)
295-
.put("cluster_name", "scassandra")
296-
.put("cql_version", "3.2.0")
297-
.put("data_center", datacenter(dc))
298-
.put("listen_address", address)
299-
.put("partitioner", "org.apache.cassandra.dht.Murmur3Partitioner")
300-
.put("rack", "rack1")
301-
.put("release_version", getPeerInfo(dc, n + 1, "release_version", "2.1.8"))
302-
.put("tokens", ImmutableSet.of(tokens.get(n)))
303-
.build();
287+
288+
row = Maps.newHashMap();
289+
addPeerInfo(row, dc, n + 1, "key", "local");
290+
addPeerInfo(row, dc, n + 1, "bootstrapped", "COMPLETED");
291+
addPeerInfo(row, dc, n + 1, "broadcast_address", address);
292+
addPeerInfo(row, dc, n + 1, "cluster_name", "scassandra");
293+
addPeerInfo(row, dc, n + 1, "cql_version", "3.2.0");
294+
addPeerInfo(row, dc, n + 1, "data_center", datacenter(dc));
295+
addPeerInfo(row, dc, n + 1, "listen_address", address);
296+
addPeerInfo(row, dc, n + 1, "partitioner", "org.apache.cassandra.dht.Murmur3Partitioner");
297+
addPeerInfo(row, dc, n + 1, "rack", getPeerInfo(dc, n + 1, "rack", "rack1"));
298+
addPeerInfo(row, dc, n + 1, "release_version", getPeerInfo(dc, n + 1, "release_version", "2.1.8"));
299+
addPeerInfo(row, dc, n + 1, "tokens", ImmutableSet.of(tokens.get(n)));
304300
} else { // prime system.peers.
305301
query = "SELECT * FROM system.peers WHERE peer='" + address + "'";
306302
metadata = SELECT_PEERS;
307-
row = ImmutableMap.<String, Object>builder()
308-
.put("peer", address)
309-
.put("rpc_address", address)
310-
.put("data_center", datacenter(dc))
311-
.put("rack", "rack1")
312-
.put("release_version", getPeerInfo(dc, n + 1, "release_version", "2.1.8"))
313-
.put("tokens", ImmutableSet.of(Long.toString(tokens.get(n))))
314-
.put("host_id", UUIDs.random())
315-
.build();
303+
row = Maps.newHashMap();
304+
addPeerInfo(row, dc, n + 1, "peer", address);
305+
addPeerInfo(row, dc, n + 1, "rpc_address", address);
306+
addPeerInfo(row, dc, n + 1, "data_center", datacenter(dc));
307+
addPeerInfo(row, dc, n + 1, "rack", getPeerInfo(dc, n + 1, "rack", "rack1"));
308+
addPeerInfo(row, dc, n + 1, "release_version", getPeerInfo(dc, n + 1, "release_version", "2.1.8"));
309+
addPeerInfo(row, dc, n + 1, "tokens", ImmutableSet.of(Long.toString(tokens.get(n))));
310+
addPeerInfo(row, dc, n + 1, "host_id", UUIDs.random());
316311
rows.add(row);
317312
}
318313
client.prime(PrimingRequest.queryBuilder()
@@ -355,6 +350,14 @@ private void primeMetadata(Scassandra node) {
355350
.build());
356351
}
357352

353+
private Map<String, Object> addPeerInfo(Map<String, Object> input, int dc, int node, String property, Object defaultValue) {
354+
Object peerInfo = getPeerInfo(dc, node, property, defaultValue);
355+
if(peerInfo != null) {
356+
input.put(property, peerInfo);
357+
}
358+
return input;
359+
}
360+
358361
private Object getPeerInfo(int dc, int node, String property, Object defaultValue) {
359362
Map<Integer, Map<String, Object>> forDc = forcedPeerInfos.get(dc);
360363
if (forDc == null)

0 commit comments

Comments
 (0)