Skip to content

Commit

Permalink
Refactoring the test cases
Browse files Browse the repository at this point in the history
Further refactored the test cases. Tried to solidify the test case
by adding more checks and saw that most of them failed because of
 existing bugs. So commented them out and left whatever comments
I know of in those places.
  • Loading branch information
arunthirupathi committed Jan 7, 2015
1 parent 27387e0 commit 14e6d54
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 53 deletions.
18 changes: 2 additions & 16 deletions test/unit/voldemort/client/ClientTrafficGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

Expand Down Expand Up @@ -98,26 +97,13 @@ public void verifyIfClientsDetectedNewClusterXMLs() {

public void verifyPostConditions() {
for(ClientTrafficVerifier client: verifiers) {
if(!client.stopped) {
if(!client.isStopped()) {
client.stop();
}
}

for(ClientTrafficVerifier client: verifiers) {
Map<String, Integer> eMap = client.exceptionCount;
logger.info("-------------------------------------------------------------------");
logger.info("Client Operation Info of [" + client.clientName + "]");
logger.info(client.requestCount.toString());
if(eMap.size() == 0) {
logger.info("No Exception reported by ClientTrafficVerifier(ObsoleteVersionException are ignored)");

logger.info("-------------------------------------------------------------------");
} else {
logger.info("Exceptions Count Map of the client: ");
logger.info(eMap.toString());
logger.info("-------------------------------------------------------------------");
throw new RuntimeException("Found Exceptions by Client" + eMap);
}
client.verifyPostConditions();
}
}

Expand Down
104 changes: 70 additions & 34 deletions test/unit/voldemort/client/ClientTrafficVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public String toString() {
public final StoreClient<String, String> client;
final StoreClientFactory factory;
boolean shouldStop = false;
public boolean stopped = true; // not thread safe by multiple readers
private boolean stopped = true; // not thread safe by multiple readers
final Thread thread;
public final String clientName;
List<String> keys = new ArrayList<String>(KV_POOL_SIZE);
Expand All @@ -65,6 +65,7 @@ public ClientTrafficVerifier(String clientName,
// prevent duplicate keys
continue;
}
k = clientName + "_" + k;
kvMap.put(k, v);
kvUpdateCount.put(k, 0);
keys.add(k);
Expand Down Expand Up @@ -94,59 +95,49 @@ public void run() {
while(!shouldStop) {
String k = keys.get(r.nextInt(KV_POOL_SIZE));
try {
switch(r.nextInt(3)){
case 0 : // update
switch(r.nextInt(3)) {
case 0: // update
if((operationMode & MODE_ALLOW_PUT) == 0) {
break;
}
kvUpdateCount.put(k, kvUpdateCount.get(k) + 1);
client.put(k, kvMap.get(k) + "_" + kvUpdateCount.get(k).toString());
int newCount = kvUpdateCount.get(k) + 1;
client.put(k, kvMap.get(k) + "_" + newCount);
kvUpdateCount.put(k, newCount);
requestCount.put("PUT", requestCount.get("PUT") + 1);
break;
case 1 : // get
case 1: // get
if((operationMode & MODE_ALLOW_GET) == 0) {
break;
}
Versioned<String> value = client.get(k); // does not check versions, just prevent exceptions
if(value == null) {
throw new RuntimeException("Versioned is empty for key [" + k + "]") {};
} else {
if(value.getValue() == null) {
throw new RuntimeException("Versioned has empty value inside for key ["
+ k + "]") {};
}
}
Versioned<String> value = client.get(k);

verifyValue(k, value);
requestCount.put("GET", requestCount.get("GET") + 1);
break;
case 2 : // get all
case 2: // get all
if((operationMode & MODE_ALLOW_GETALL) == 0) {
break;
}
String k2 = keys.get(r.nextInt(KV_POOL_SIZE));
Map<String, Versioned<String>> result = client.getAll(Arrays.asList(k, k2));
if(result.get(k) == null) {
throw new RuntimeException("Versioned is empty for key [" + k + "]") {};
} else {
if(result.get(k).getValue() == null) {
throw new RuntimeException("Versioned has empty value inside for key ["
+ k + "]") {};
}
}
if(result.get(k2) == null) {
throw new RuntimeException("Versioned is empty for key [" + k2 + "]") {};
} else {
if(result.get(k2).getValue() == null) {
throw new RuntimeException("Versioned has empty value inside for key ["
+ k2 + "]") {};
}
}
verifyValue(k, result.get(k));
verifyValue(k2, result.get(k2));
requestCount.put("GETALL", requestCount.get("GETALL") + 1);
break;
}
} catch(ObsoleteVersionException e) {} catch(Exception e) {
} catch(ObsoleteVersionException e) {
// Theoretically, each thread works with its own set of keys the
// ObsoleteVersionException should not happen. But partitions
// are moving around nodes and because of the way we
// acknowledge writes before all nodes are complete and using
// async writes they can be out of sync and the exceptions can
// still happen. Did not try digging deeper on this one
// as it is irrelevant for the refactoring I am doing.

} catch(Exception e) {
logger.info("CLIENT EXCEPTION FAILURE on key [" + k + "]" + e.toString());
e.printStackTrace();
String exceptionName = e.getClass().toString();
String exceptionName = "Key " + k + " " + e.getClass().toString();
if(exceptionCount.containsKey(exceptionName)) {
exceptionCount.put(exceptionName, exceptionCount.get(exceptionName) + 1);
} else {
Expand All @@ -170,4 +161,49 @@ public void stop() {
e.printStackTrace();
}
}

public boolean isStopped() {
return this.stopped;
}

private void verifyValue(String key, Versioned<String> value) {
if(value == null) {
throw new RuntimeException("Versioned is empty for key [" + key + "]") {};
} else if(value.getValue() == null) {
throw new RuntimeException("Versioned has empty value inside for key [" + key + "]") {};
}
// For some reasons the expected and retrieved values are not the same.
// else {
// String retrievedValue = value.getValue();
// String expectedValue = kvMap.get(key) + "_" + kvUpdateCount.get(key);
// if(retrievedValue.equals(expectedValue) == false) {
// throw new RuntimeException("Key " + key + " Expected Value " +
// expectedValue
// + " Retrieved Value " + retrievedValue) {};
// }
// }
}

public void verifyPostConditions() {
// for(String key: kvMap.keySet()) {
// Versioned<String> value = client.get(key);
// verifyValue(key, value);
// }

Map<String, Integer> eMap = exceptionCount;
logger.info("-------------------------------------------------------------------");
logger.info("Client Operation Info of [" + clientName + "]");
logger.info(requestCount.toString());
if(eMap.size() == 0) {
logger.info("No Exception reported by ClientTrafficVerifier(ObsoleteVersionException are ignored)");

logger.info("-------------------------------------------------------------------");
} else {
logger.info("Exceptions Count Map of the client: ");
logger.info(eMap.toString());
logger.info("-------------------------------------------------------------------");
throw new RuntimeException("Found Exceptions by Client" + eMap);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public void setup() throws IOException {
bootstrapURL = survivingNodes.get(0).getSocketUrl().toString();
}

@Test(timeout = 60000)
@Test(timeout = 120000)
public void endToEndTestUpdateTogether() throws InterruptedException {
List<String> storeNames = Arrays.asList(new String[] { STORE211_NAME, STORE322_NAME });
List<Integer> zones = Arrays.asList(new Integer[] { 1, 2 });
Expand Down Expand Up @@ -178,8 +178,10 @@ public void testAllServersSendingOutSlopsCorrectly() throws InterruptedException
Map<Integer, SocketStore> slopStoresCreatedBeforeShrink = new HashMap<Integer, SocketStore>();
Map<Integer, SocketStore> slopStoresCreatedAfterShrink = new HashMap<Integer, SocketStore>();

// generate for keys each all servers that will be hosted on each server except itself (2*N*(N-1) keys)
// Map<Integer slopFinalDestinationNodeId, List<Pair<ByteArray key, Integer hostNodeId>>>
// generate for keys each all servers that will be hosted on each server
// except itself (2*N*(N-1) keys)
// Map<Integer slopFinalDestinationNodeId, List<Pair<ByteArray key,
// Integer hostNodeId>>>
Map<Integer, List<Pair<ByteArray, Integer>>> serverKeys = new HashMap<Integer, List<Pair<ByteArray, Integer>>>();
for(Node slopFinalDestinationNode: cluster.getNodes()) {
serverKeys.put(slopFinalDestinationNode.getId(),
Expand Down

0 comments on commit 14e6d54

Please sign in to comment.