package org.robotninjas.barge.jaxrs;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import static org.robotninjas.barge.jaxrs.Logs.uniqueLog;
import org.robotninjas.barge.state.Raft;
import org.robotninjas.barge.utils.Prober;
import java.io.File;
import java.net.URI;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
*/
public abstract class ServerTest<T extends RaftServer<T>> {
@ClassRule
public static MuteJUL muteJUL = new MuteJUL();
private URI[] uris = new URI[3];
private T httpServer1;
private T httpServer2;
private T httpServer3;
@Before
public void setUp() throws Exception {
Logger.getLogger("").setLevel(Level.ALL);
uris[0] = new URI("http://localhost:56789/");
uris[1] = new URI("http://localhost:56790/");
uris[2] = new URI("http://localhost:56791/");
httpServer1 = createServer(0, uris, uniqueLog()).start(56789);
httpServer2 = createServer(1, uris, uniqueLog()).start(56790);
httpServer3 = createServer(2, uris, uniqueLog()).start(56791);
}
@After
public void tearDown() throws Exception {
httpServer1.stop();
httpServer2.stop();
httpServer3.stop();
httpServer1.clean();
httpServer2.clean();
httpServer3.clean();
}
@Test
public void can_commit_data_to_leader_instance() throws Exception {
final Client client = ClientBuilder.newBuilder().register(Jackson.customJacksonProvider()).build();
client.target(uris[0]).path("/raft/init").request().post(Entity.json(""));
client.target(uris[1]).path("/raft/init").request().post(Entity.json(""));
client.target(uris[2]).path("/raft/init").request().post(Entity.json(""));
new Prober(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return isLeader(client, uris[0]) || isLeader(client, uris[1]) || isLeader(client, uris[2]);
}
}).probe(10000);
URI leaderURI = getLeader(client);
Response result = client.target(leaderURI)
.path("/raft/commit")
.request()
.post(Entity.entity("foo".getBytes(),
MediaType.APPLICATION_OCTET_STREAM));
assertThat(result.getStatus()).isEqualTo(204);
}
protected abstract T createServer(int serverIndex, URI[] uris1, File logDir);
private URI getLeader(Client client) {
if (isLeader(client, uris[0]))
return uris[0];
if (isLeader(client, uris[1]))
return uris[1];
if (isLeader(client, uris[2]))
return uris[2];
throw new IllegalStateException("expected one server to be a leader");
}
private boolean isLeader(Client client, URI uri) {
return client.target(uri).path("/raft/state").request().get(Raft.StateType.class).equals(Raft.StateType.LEADER);
}
}