package utils.test;
import services.ConfigurationService;
import utils.file.FileLockException;
import utils.file.FileUtils;
import utils.ssh.FilePermissions;
import utils.ssh.SSHClient;
import utils.ssh.SSHException;
import utils.test.data.YCSBWorkload;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Random;
/**
* Created by ricardolorenzo on 01/08/2014.
*/
public class YCSBTestRunner extends TestRunner {
/**
* Every node contain his own mongos process
*/
private static final String databaseUrl = "mongodb://localhost";
private static final String WORKLOAD_FILE_PATH = "/tmp/workload.test";
private YCSBWorkload workload;
private Integer threads;
private Integer bulkCount;
private Integer nodeCount;
public YCSBTestRunner(YCSBWorkload workload, Integer threads, Integer bulkCount) {
super();
this.workload = workload;
this.threads = threads;
this.bulkCount = bulkCount;
this.nodeCount = 0;
cleanAttributeObjects();
}
@Override
protected Test getTest(Integer phase, Integer nodeNumber) throws TestException {
String user = ConfigurationService.TEST_USER;
if(user.contains("@")) {
user = user.substring(0, user.indexOf("@"));
}
StringBuilder sb = new StringBuilder();
sb.append("/home/");
sb.append(user);
sb.append("/");
sb.append(TestConfiguration.YCSB_DIRECTORY);
sb.append("/bin");
Test t = new YCSBTest(sb.toString(), "ycsb", phase, WORKLOAD_FILE_PATH, threads, bulkCount);
t.setDatabaseUrl(databaseUrl);
Integer recordsPerNode = (this.workload.getRecordcount()/nodeCount);
t.setInsertCount(recordsPerNode);
t.setInsertStart(recordsPerNode * (nodeNumber - 1));
return t;
}
private static SSHClient connect(String address) throws SSHException, IOException {
if(!hasAttributeObject("ssh-client")) {
SSHClient client = new SSHClient(address, 22);
client.connect(ConfigurationService.TEST_USER);
setAttributeObject("ssh-client", client);
return client;
} else {
return SSHClient.class.cast(getAttributeObject("ssh-client"));
}
}
private static void disconnect() {
if(hasAttributeObject("ssh-client")) {
SSHClient.class.cast(getAttributeObject("ssh-client")).disconnect();
}
}
@Override
protected void finalizeTasks() {
disconnect();
}
@Override
protected void initializeTasks(Integer phase, String jumpAddress, List<String> testNodeAddresses) throws TestException {
Random r = new Random();
this.nodeCount = testNodeAddresses.size();
String randomTestNode = testNodeAddresses.get(r.nextInt(testNodeAddresses.size() - 1));
try {
SSHClient client = connect(jumpAddress);
switch(phase) {
case Test.PHASE_LOAD: {
client.forwardConnect(randomTestNode, ConfigurationService.TEST_USER, 22);
if(client.sendForwardCommand(randomTestNode, "ls /etc/mongos.js") != 0) {
throw new TestException("Test nodes are still running the initial configuration process, you must wait at least 60 seconds before run the first test");
}
File f = File.createTempFile("init-test", ".js");
try {
FilePermissions permissions = new FilePermissions(FilePermissions.READ + FilePermissions.WRITE,
FilePermissions.READ, FilePermissions.READ);
StringBuilder sb = new StringBuilder();
sb.append("db = db.getSiblingDB(\"ycsb\");\n");
sb.append("db.dropDatabase();\n");
sb.append("sh.enableSharding(\"ycsb\");\n");
sb.append("sh.shardCollection(\"ycsb.usertable\", { \"_id\": \"hashed\" });\n");
FileUtils.writeFile(f, sb.toString());
client.sendForwardFile(randomTestNode, f, "/tmp/init-test.js", permissions);
client.sendForwardCommand(randomTestNode, "mongo /tmp/init-test.js");
} catch(FileLockException e) {
throw new TestException(e);
} finally {
f.delete();
//client.forwardDisconnect(randomTestNode);
}
}
break;
}
} catch(SSHException e) {
throw new TestException(e);
} catch(IOException e) {
throw new TestException(e);
}
}
@Override
protected void preRunTask(String jumpAddress, String testNodeAddress) throws TestException {
try {
FilePermissions permissions = new FilePermissions(FilePermissions.READ + FilePermissions.WRITE,
FilePermissions.READ, FilePermissions.READ);
SSHClient client = connect(jumpAddress);
File f = File.createTempFile("workload", ".test");
try {
FileUtils.writeFile(f, this.workload.toString());
client.forwardConnect(testNodeAddress, ConfigurationService.TEST_USER, 22);
client.sendForwardFile(testNodeAddress, f, WORKLOAD_FILE_PATH, permissions);
} catch(FileLockException e) {
throw new TestException(e);
} finally {
f.delete();
//client.forwardDisconnect(testNodeAddress);
}
} catch(SSHException e) {
throw new TestException(e);
} catch(IOException e) {
throw new TestException(e);
}
}
@Override
protected void postRunTask() {
// none
}
}