package peergos.server.tests;
import org.junit.*;
import org.junit.runner.*;
import org.junit.runners.*;
import peergos.server.*;
import peergos.server.storage.*;
import peergos.shared.*;
import peergos.shared.crypto.*;
import peergos.shared.crypto.asymmetric.*;
import peergos.shared.crypto.asymmetric.curve25519.*;
import peergos.shared.crypto.hash.*;
import peergos.shared.crypto.random.*;
import peergos.shared.crypto.symmetric.*;
import peergos.shared.io.ipfs.cid.*;
import peergos.shared.merklebtree.*;
import peergos.shared.user.*;
import peergos.shared.user.fs.*;
import peergos.shared.util.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
import static org.junit.Assert.*;
@RunWith(Parameterized.class)
public class CorenodeTests {
public static int RANDOM_SEED = 666;
private final NetworkAccess network;
private static Random random = new Random(RANDOM_SEED);
public CorenodeTests(String useIPFS, Random r) throws Exception {
int webPort = 9000 + r.nextInt(1000);
int corePort = 10000 + r.nextInt(1000);
Args args = Args.parse(new String[]{"useIPFS", ""+useIPFS.equals("IPFS"), "-port", Integer.toString(webPort), "-corenodePort", Integer.toString(corePort)});
Start.local(args);
this.network = NetworkAccess.buildJava(new URL("http://localhost:" + webPort)).get();
// use insecure random otherwise tests take ages
setFinalStatic(TweetNaCl.class.getDeclaredField("prng"), new Random(1));
}
@Parameterized.Parameters(name = "{index}: {0}")
public static Collection<Object[]> parameters() {
Random r = new Random(1234);
return Arrays.asList(new Object[][] {
// {"IPFS", r},
{"RAM", r}
});
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
@Test
public void writeThroughput() throws Exception {
Crypto crypto = Crypto.initJava();
ForkJoinPool pool = new ForkJoinPool(10);
List<Future<Long>> worstLatencies = new ArrayList<>();
for (int t = 0; t < 10; t++)
worstLatencies.add(pool.submit(() -> {
SigningKeyPair owner = SigningKeyPair.random(crypto.random, crypto.signer);
SigningKeyPair writer = SigningKeyPair.random(crypto.random, crypto.signer);
byte[] data = new byte[10];
MaybeMultihash current = MaybeMultihash.EMPTY();
long t1 = System.currentTimeMillis();
int iterations = 100;
long maxLatency = 0;
for (int i = 0; i < iterations; i++) {
random.nextBytes(data);
Cid cid = RAMStorage.hashToCid(data);
HashCasPair cas = new HashCasPair(current, MaybeMultihash.of(cid));
byte[] signed = writer.signMessage(cas.serialize());
try {
long t3 = System.currentTimeMillis();
network.mutable.setPointer(owner.publicSigningKey, writer.publicSigningKey, signed).get();
long latency = System.currentTimeMillis() - t3;
if (latency > maxLatency)
maxLatency = latency;
current = MaybeMultihash.of(cid);
} catch (Exception e) {
e.printStackTrace();
}
}
long t2 = System.currentTimeMillis();
System.out.printf("%d iterations took %d mS\n", iterations, t2 - t1);
return maxLatency;
}));
long worstLatency = worstLatencies.stream().mapToLong(f -> {
try {
return f.get();
} catch (Exception e) {
return Long.MIN_VALUE;
}
}).max().getAsLong();
System.out.println("Worst Latency: " + worstLatency);
Assert.assertTrue("Worst latency < 1 second: " + worstLatency, worstLatency < 2000);
pool.awaitQuiescence(5, TimeUnit.MINUTES);
}
}