DocOpScrub.setShouldScrubByDefault(false);
r = RandomProviderImpl.ofSeed(seed);
p = new Parameters();
p.setMaxOpeningComponents(5);
Doc client = new Doc();
FakeServer server = new FakeServer(r, p);
LinkedList<Integer> xhrResponses = Lists.newLinkedList();
TransformQueue<DocOp> q = new TransformQueue<DocOp>(
ChannelTestUtil.randomlyCompactingTransformer(0));
q.init(0);
int[] scenario = new int[8];
// PrintStream out = System.out;
PrintStream out = NULL_STREAM;
int numConvergences = 0;
for (int iter = 0; iter < numIterations; iter++) {
Event e = randomEvent();
out.println("\n" + iter + " " + e + " ========");
eventCounts.put(e, (eventCounts.containsKey(e) ? eventCounts.get(e) : 0) + 1);
switch (e) {
case CLIENT_OP:
DocOp op = randomOp(client);
q.clientOp(op);
break;
case CLIENT_SEND:
if (!q.hasUnacknowledgedClientOps() && q.hasQueuedClientOps()) {
server.sendToServer(q.revision(), q.pushQueuedOpsToUnacked());
}
break;
case SERVER_OP:
server.randomServerOp();
break;
case XHR_RESPONSE:
while (!xhrResponses.isEmpty()) {
int responseVersion = xhrResponses.remove();
q.ackOpsIfVersionMatches(responseVersion);
}
break;
case CLIENT_RECEIVE:
case CLIENT_RECEIVE_ALL:
while (server.channelPending()) {
UnitPackage p = server.clientReceive();
if (p.clientSourced) {
out.println("client");
if (!q.expectedAck(p.resultingRevision)) {
q.ackClientOp(p.resultingRevision);
}
} else {
q.serverOp(p.resultingRevision, p.onlyOp());
}
if (e == Event.CLIENT_RECEIVE) {
break;
}
}
break;
case CLIENT_APPLY:
if (q.hasServerOp()) {
client.consume(q.removeServerOp());
}
break;
case SERVER_RECEIVE:
if (server.serverReceive()) {
xhrResponses.add(server.revision());
}
break;
default:
throw new AssertionError("Unhandled event");
}
// out.println(server);
// out.println(q);
// out.println(client);
// Extra checking, simulate convergence
if (iter % 10 == 0) {
Doc clientCopy = client.copy();
Doc serverCopy = server.at(q.revision()).copy();
for (DocOp pendingServerOp : q.serverOps) {
clientCopy.consume(pendingServerOp);
}
for (DocOp pendingClientOp : q.unackedClientOps) {
serverCopy.consume(pendingClientOp);
}
for (DocOp pendingClientOp : q.queuedClientOps) {
serverCopy.consume(pendingClientOp);
}
assertEquals("Unequal states", clientCopy.repr(), serverCopy.repr());
}
boolean qco = q.hasQueuedClientOps();
boolean uco = q.hasUnacknowledgedClientOps();
boolean so = q.hasServerOp();
if (!qco && !uco && !so) {
out.println("CONVERGED STATE (" + iter + ") " + client.doc.size());
numConvergences++;
assertEquals("Unequal states", client.repr(), server.at(q.revision()).repr());
}
scenario[(qco ? 1<<2 : 0) + (uco ? 1<<1 : 0) + (so ? 1<<0 : 0)]++;
}