Added a new version of the BB Server that allows for search of messages containing multiple tags and/or signatures.
Added tests for both Server types.Bulletin-Board-Client-phase_1
parent
679d18f4a2
commit
0b847dcaf4
|
@ -0,0 +1,190 @@
|
||||||
|
package meerkat.bulletinboard.sqlserver;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import meerkat.comm.CommunicationException;
|
||||||
|
import meerkat.protobuf.BulletinBoardAPI;
|
||||||
|
import meerkat.protobuf.BulletinBoardAPI.*;
|
||||||
|
import meerkat.protobuf.Crypto.*;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Arbel Deutsch Peled on 07-Dec-15.
|
||||||
|
* This server version allows for reading of messages with several tags and/or signatures
|
||||||
|
* The superclass only allows one constraint per type.
|
||||||
|
*/
|
||||||
|
public class EnhancedSQLiteBulletinBoardServer extends SQLiteBulletinBoardServer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements a comparator for the MessageFilter class
|
||||||
|
* The comparison is done solely by comparing the type of the filter
|
||||||
|
* This is used to sort the filters by type
|
||||||
|
*/
|
||||||
|
public class FilterTypeComparator implements Comparator<MessageFilter>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(MessageFilter filter1, MessageFilter filter2) {
|
||||||
|
return filter1.getTypeValue() - filter2.getTypeValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException {
|
||||||
|
|
||||||
|
PreparedStatement pstmt;
|
||||||
|
ResultSet messages, signatures;
|
||||||
|
|
||||||
|
long entryNum;
|
||||||
|
BulletinBoardMessageList.Builder resultListBuilder = BulletinBoardMessageList.newBuilder();
|
||||||
|
BulletinBoardMessage.Builder messageBuilder;
|
||||||
|
|
||||||
|
String sql;
|
||||||
|
String sqlSuffix = "";
|
||||||
|
|
||||||
|
List<MessageFilter> filters = new ArrayList<MessageFilter>(filterList.getFilterList());
|
||||||
|
int i;
|
||||||
|
|
||||||
|
boolean tagsRequired = false;
|
||||||
|
boolean signaturesRequired = false;
|
||||||
|
|
||||||
|
boolean isFirstFilter = true;
|
||||||
|
|
||||||
|
Collections.sort(filters, new FilterTypeComparator());
|
||||||
|
|
||||||
|
// Check if Tag/Signature tables are required for filtering purposes.
|
||||||
|
|
||||||
|
sql = "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable";
|
||||||
|
|
||||||
|
// Add conditions.
|
||||||
|
|
||||||
|
if (!filters.isEmpty()){
|
||||||
|
sql += " WHERE";
|
||||||
|
|
||||||
|
for (MessageFilter filter : filters){
|
||||||
|
|
||||||
|
if (filter.getType().getNumber() != FilterType.MAX_MESSAGES_VALUE){
|
||||||
|
if (isFirstFilter){
|
||||||
|
isFirstFilter = false;
|
||||||
|
} else{
|
||||||
|
sql += " AND";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (filter.getType().getNumber()){
|
||||||
|
case FilterType.EXACT_ENTRY_VALUE:
|
||||||
|
sql += " MsgTable.EntryNum = ?";
|
||||||
|
break;
|
||||||
|
case FilterType.MAX_ENTRY_VALUE:
|
||||||
|
sql += " MsgTable.EntryNum <= ?";
|
||||||
|
break;
|
||||||
|
case FilterType.MAX_MESSAGES_VALUE:
|
||||||
|
sqlSuffix += " LIMIT = ?";
|
||||||
|
break;
|
||||||
|
case FilterType.MSG_ID_VALUE:
|
||||||
|
sql += " MsgTable.MsgId = ?";
|
||||||
|
break;
|
||||||
|
case FilterType.SIGNER_ID_VALUE:
|
||||||
|
sql += " EXISTS (SELECT 1 FROM SignatureTable"
|
||||||
|
+ " WHERE SignatureTable.SignerId = ? AND SignatureTable.EntryNum = MsgTable.EntryNum)";
|
||||||
|
break;
|
||||||
|
case FilterType.TAG_VALUE:
|
||||||
|
sql += " EXISTS (SELECT 1 FROM TagTable"
|
||||||
|
+ " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId"
|
||||||
|
+ " WHERE TagTable.Tag = ? AND MsgTagTable.EntryNum = MsgTable.EntryNum)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sql += sqlSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make query.
|
||||||
|
|
||||||
|
try {
|
||||||
|
pstmt = connection.prepareStatement(sql);
|
||||||
|
|
||||||
|
// Specify values for filters.
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
for (MessageFilter filter : filters){
|
||||||
|
|
||||||
|
switch (filter.getType().getNumber()){
|
||||||
|
|
||||||
|
case FilterType.EXACT_ENTRY_VALUE: // Go through.
|
||||||
|
case FilterType.MAX_ENTRY_VALUE:
|
||||||
|
pstmt.setLong(i, filter.getEntry());
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterType.MSG_ID_VALUE: // Go through.
|
||||||
|
case FilterType.SIGNER_ID_VALUE:
|
||||||
|
pstmt.setBytes(i, filter.getId().toByteArray());
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterType.TAG_VALUE:
|
||||||
|
pstmt.setString(i, filter.getTag());
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// The max-messages condition is applied as a suffix. Therefore, it is treated differently.
|
||||||
|
case FilterType.MAX_MESSAGES_VALUE:
|
||||||
|
pstmt.setLong(filters.size(), filter.getMaxMessages());
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run query.
|
||||||
|
|
||||||
|
messages = pstmt.executeQuery();
|
||||||
|
|
||||||
|
// Compile list of messages.
|
||||||
|
|
||||||
|
sql = "SELECT Signature FROM SignatureTable WHERE EntryNum = ?";
|
||||||
|
pstmt = connection.prepareStatement(sql);
|
||||||
|
|
||||||
|
while (messages.next()){
|
||||||
|
|
||||||
|
// Get entry number and retrieve signatures.
|
||||||
|
|
||||||
|
entryNum = messages.getLong(1);
|
||||||
|
pstmt.setLong(1, entryNum);
|
||||||
|
signatures = pstmt.executeQuery();
|
||||||
|
|
||||||
|
// Create message and append signatures.
|
||||||
|
|
||||||
|
messageBuilder = BulletinBoardMessage.newBuilder()
|
||||||
|
.setEntryNum(entryNum)
|
||||||
|
.setMsg(UnsignedBulletinBoardMessage.parseFrom(messages.getBytes(2)));
|
||||||
|
|
||||||
|
while (signatures.next()){
|
||||||
|
messageBuilder.addSig(Signature.parseFrom(signatures.getBytes(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize message and add to message list.
|
||||||
|
|
||||||
|
resultListBuilder.addMessage(messageBuilder.build());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pstmt.close();
|
||||||
|
|
||||||
|
} catch (SQLException e){
|
||||||
|
throw new CommunicationException("Error reading messages from DB: " + e.getMessage());
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
throw new CommunicationException("Invalid data from DB: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Combine results and return.
|
||||||
|
|
||||||
|
return resultListBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package meerkat.bulletinboard;
|
||||||
|
|
||||||
|
import meerkat.bulletinboard.sqlserver.EnhancedSQLiteBulletinBoardServer;
|
||||||
|
import meerkat.comm.CommunicationException;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Arbel Deutsch Peled on 07-Dec-15.
|
||||||
|
*/
|
||||||
|
public class EnhancedSQLiteBulletinBoardServerTest{
|
||||||
|
|
||||||
|
private String testFilename = "EnhancedSQLiteDBTest.db";
|
||||||
|
|
||||||
|
private GenericBulletinBoardServerTest serverTest;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init(){
|
||||||
|
|
||||||
|
File old = new File(testFilename);
|
||||||
|
old.delete();
|
||||||
|
|
||||||
|
BulletinBoardServer bulletinBoardServer = new EnhancedSQLiteBulletinBoardServer();
|
||||||
|
try {
|
||||||
|
bulletinBoardServer.init(testFilename);
|
||||||
|
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println("Failed to initialize server " + e.getMessage());
|
||||||
|
fail("Failed to initialize server " + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serverTest = new GenericBulletinBoardServerTest();
|
||||||
|
serverTest.init(bulletinBoardServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bulkTest() {
|
||||||
|
System.err.println("Testing Enhanced SQLite Server");
|
||||||
|
serverTest.testInsert();
|
||||||
|
serverTest.testSimpleTagAndSignature();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void close() {
|
||||||
|
serverTest.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,12 +26,14 @@ import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
|
||||||
public abstract class GenericBulletinBoardServerTest {
|
public class GenericBulletinBoardServerTest {
|
||||||
|
|
||||||
protected BulletinBoardServer bulletinBoardServer;
|
protected BulletinBoardServer bulletinBoardServer;
|
||||||
private ECDSASignature signers[];
|
private ECDSASignature signers[];
|
||||||
|
private ByteString[] signerIDs;
|
||||||
|
|
||||||
private Random random;
|
private Random random;
|
||||||
|
|
||||||
private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12";
|
private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12";
|
||||||
private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12";
|
private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12";
|
||||||
|
|
||||||
|
@ -40,10 +42,9 @@ public abstract class GenericBulletinBoardServerTest {
|
||||||
|
|
||||||
public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt";
|
public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt";
|
||||||
public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt";
|
public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param bulletinBoardServer is an initialized server.
|
||||||
* @param cls
|
|
||||||
* @throws InstantiationException
|
* @throws InstantiationException
|
||||||
* @throws IllegalAccessException
|
* @throws IllegalAccessException
|
||||||
* @throws CertificateException
|
* @throws CertificateException
|
||||||
|
@ -53,19 +54,23 @@ public abstract class GenericBulletinBoardServerTest {
|
||||||
* @throws UnrecoverableKeyException
|
* @throws UnrecoverableKeyException
|
||||||
* @throws CommunicationException
|
* @throws CommunicationException
|
||||||
*/
|
*/
|
||||||
public void init(String meerkatDB) throws InstantiationException, IllegalAccessException, CertificateException, KeyStoreException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, CommunicationException{
|
public void init(BulletinBoardServer bulletinBoardServer) {
|
||||||
|
|
||||||
bulletinBoardServer.init(meerkatDB);
|
this.bulletinBoardServer = bulletinBoardServer;
|
||||||
|
|
||||||
signers = new ECDSASignature[2];
|
signers = new ECDSASignature[2];
|
||||||
|
signerIDs = new ByteString[signers.length];
|
||||||
signers[0] = new ECDSASignature();
|
signers[0] = new ECDSASignature();
|
||||||
signers[1] = new ECDSASignature();
|
signers[1] = new ECDSASignature();
|
||||||
|
|
||||||
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
|
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
|
||||||
char[] password = KEYFILE_PASSWORD1.toCharArray();
|
char[] password = KEYFILE_PASSWORD1.toCharArray();
|
||||||
|
|
||||||
KeyStore.Builder keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password);
|
KeyStore.Builder keyStoreBuilder = null;
|
||||||
signers[0].loadSigningCertificate(keyStoreBuilder);
|
try {
|
||||||
|
keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password);
|
||||||
|
|
||||||
|
signers[0].loadSigningCertificate(keyStoreBuilder);
|
||||||
|
|
||||||
signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE));
|
signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE));
|
||||||
|
|
||||||
|
@ -76,6 +81,40 @@ public abstract class GenericBulletinBoardServerTest {
|
||||||
signers[1].loadSigningCertificate(keyStoreBuilder);
|
signers[1].loadSigningCertificate(keyStoreBuilder);
|
||||||
|
|
||||||
signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE));
|
signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE));
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Failed reading from signature file " + e.getMessage());
|
||||||
|
fail("Failed reading from signature file " + e.getMessage());
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
System.err.println("Failed reading certificate " + e.getMessage());
|
||||||
|
fail("Failed reading certificate " + e.getMessage());
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
System.err.println("Failed reading keystore " + e.getMessage());
|
||||||
|
fail("Failed reading keystore " + e.getMessage());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
System.err.println("Couldn't find signing algorithm " + e.getMessage());
|
||||||
|
fail("Couldn't find signing algorithm " + e.getMessage());
|
||||||
|
} catch (UnrecoverableKeyException e) {
|
||||||
|
System.err.println("Couldn't find signing key " + e.getMessage());
|
||||||
|
fail("Couldn't find signing key " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get signer IDs
|
||||||
|
// TODO: remove this after creation of getSignerID method
|
||||||
|
|
||||||
|
UnsignedBulletinBoardMessage msg = UnsignedBulletinBoardMessage.newBuilder().build();
|
||||||
|
|
||||||
|
for (int i = 0 ; i < signers.length ; i++) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
signers[i].updateContent(UnsignedBulletinBoardMessage.newBuilder().build());
|
||||||
|
signerIDs[i] = signers[i].sign().getSignerId();
|
||||||
|
} catch (SignatureException e) {
|
||||||
|
System.err.println("Error signing message" + e.getMessage());
|
||||||
|
fail("Error signing message" + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
random = new Random(0); // We use insecure randomness in tests for repeatability
|
random = new Random(0); // We use insecure randomness in tests for repeatability
|
||||||
}
|
}
|
||||||
|
@ -87,96 +126,134 @@ public abstract class GenericBulletinBoardServerTest {
|
||||||
private String randomString(){
|
private String randomString(){
|
||||||
return new BigInteger(130, random).toString(32);
|
return new BigInteger(130, random).toString(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bulkTest() throws CommunicationException, SignatureException, InvalidKeyException, CertificateException, IOException{
|
private final int TAG_NUM = 5; // Number of tags.
|
||||||
|
private final int MESSAGE_NUM = 32; // Number of messages (2^TAG_NUM).
|
||||||
final int TAG_NUM = 5; // Number of tags.
|
|
||||||
final int MESSAGE_NUM = 32; // Number of messages (2^TAG_NUM).
|
|
||||||
|
private String[] tags;
|
||||||
|
private byte[][] data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests writing of several messages with multiple tags and signatures.
|
||||||
|
* @throws CommunicationException
|
||||||
|
* @throws SignatureException
|
||||||
|
* @throws InvalidKeyException
|
||||||
|
* @throws CertificateException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void testInsert() {
|
||||||
|
|
||||||
final int BYTES_PER_MESSAGE_DATA = 50; // Message size.
|
final int BYTES_PER_MESSAGE_DATA = 50; // Message size.
|
||||||
|
|
||||||
String[] tags = new String[TAG_NUM];
|
tags = new String[TAG_NUM];
|
||||||
byte[][] data = new byte[MESSAGE_NUM][BYTES_PER_MESSAGE_DATA];
|
data = new byte[MESSAGE_NUM][BYTES_PER_MESSAGE_DATA];
|
||||||
|
|
||||||
UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder;
|
UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder;
|
||||||
BulletinBoardMessage.Builder msgBuilder;
|
BulletinBoardMessage.Builder msgBuilder;
|
||||||
|
|
||||||
int i,j;
|
int i, j;
|
||||||
|
|
||||||
// Generate random data.
|
// Generate random data.
|
||||||
|
|
||||||
for (i = 1 ; i <= MESSAGE_NUM ; i++){
|
for (i = 1; i <= MESSAGE_NUM; i++) {
|
||||||
for (j = 0 ; j < BYTES_PER_MESSAGE_DATA ; j++){
|
for (j = 0; j < BYTES_PER_MESSAGE_DATA; j++) {
|
||||||
data[i-1][j] = randomByte();
|
data[i - 1][j] = randomByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < TAG_NUM ; i++){
|
for (i = 0; i < TAG_NUM; i++) {
|
||||||
tags[i] = randomString();
|
tags[i] = randomString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build messages.
|
// Build messages.
|
||||||
|
|
||||||
for (i = 1 ; i <= MESSAGE_NUM ; i++){
|
for (i = 1; i <= MESSAGE_NUM; i++) {
|
||||||
unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder()
|
unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder()
|
||||||
.setData(ByteString.copyFrom(data[i-1]));
|
.setData(ByteString.copyFrom(data[i - 1]));
|
||||||
|
|
||||||
// Add tags based on bit-representation of message number.
|
// Add tags based on bit-representation of message number.
|
||||||
|
|
||||||
int copyI = i;
|
int copyI = i;
|
||||||
for (j = 0 ; j < TAG_NUM ; j++){
|
for (j = 0; j < TAG_NUM; j++) {
|
||||||
if (copyI % 2 == 1){
|
if (copyI % 2 == 1) {
|
||||||
unsignedMsgBuilder.addTag(tags[j]);
|
unsignedMsgBuilder.addTag(tags[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyI >>>= 1;
|
copyI >>>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build message.
|
// Build message.
|
||||||
|
|
||||||
msgBuilder = BulletinBoardMessage.newBuilder()
|
msgBuilder = BulletinBoardMessage.newBuilder()
|
||||||
.setMsg(unsignedMsgBuilder.build());
|
.setMsg(unsignedMsgBuilder.build());
|
||||||
|
|
||||||
// Add signatures.
|
// Add signatures.
|
||||||
|
|
||||||
if (i % 2 == 1){
|
try {
|
||||||
signers[0].updateContent(msgBuilder.getMsg());
|
|
||||||
msgBuilder.addSig(signers[0].sign());
|
if (i % 2 == 1) {
|
||||||
|
signers[0].updateContent(msgBuilder.getMsg());
|
||||||
if (i % 4 == 1){
|
msgBuilder.addSig(signers[0].sign());
|
||||||
signers[1].updateContent(msgBuilder.getMsg());
|
|
||||||
msgBuilder.addSig(signers[1].sign());
|
if (i % 4 == 1) {
|
||||||
}
|
signers[1].updateContent(msgBuilder.getMsg());
|
||||||
}
|
msgBuilder.addSig(signers[1].sign());
|
||||||
|
}
|
||||||
// Post message.
|
}
|
||||||
|
|
||||||
bulletinBoardServer.postMessage(msgBuilder.build());
|
} catch (SignatureException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post message.
|
||||||
|
|
||||||
|
try {
|
||||||
|
bulletinBoardServer.postMessage(msgBuilder.build());
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests retrieval of messages written in {@Link #testInsert()}
|
||||||
|
* Only queries using one tag filter
|
||||||
|
*/
|
||||||
|
public void testSimpleTagAndSignature(){
|
||||||
|
|
||||||
|
List<BulletinBoardMessage> messages;
|
||||||
|
|
||||||
// Check tag mechanism
|
// Check tag mechanism
|
||||||
|
|
||||||
for (i = 0 ; i < TAG_NUM ; i++){
|
for (int i = 0 ; i < TAG_NUM ; i++){
|
||||||
|
|
||||||
// Retrieve messages having tag i
|
// Retrieve messages having tag i
|
||||||
|
|
||||||
List<BulletinBoardMessage> messages =
|
try {
|
||||||
bulletinBoardServer.readMessages(
|
|
||||||
MessageFilterList.newBuilder()
|
messages = bulletinBoardServer.readMessages(
|
||||||
.addFilter(MessageFilter.newBuilder()
|
MessageFilterList.newBuilder()
|
||||||
.setType(FilterType.TAG)
|
.addFilter(MessageFilter.newBuilder()
|
||||||
.setTag(tags[i])
|
.setType(FilterType.TAG)
|
||||||
|
.setTag(tags[i])
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
)
|
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
.getMessageList();
|
.getMessageList();
|
||||||
|
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Assert that the number of retrieved messages is correct.
|
// Assert that the number of retrieved messages is correct.
|
||||||
|
|
||||||
assertThat(messages.size(), is(MESSAGE_NUM / 2));
|
assertThat(messages.size(), is(MESSAGE_NUM / 2));
|
||||||
|
|
||||||
// Assert the identity of the messages.
|
// Assert the identity of the messages.
|
||||||
|
|
||||||
for (BulletinBoardMessage msg : messages){
|
for (BulletinBoardMessage msg : messages){
|
||||||
|
|
||||||
// Assert serial number and raw data.
|
// Assert serial number and raw data.
|
||||||
|
@ -185,34 +262,112 @@ public abstract class GenericBulletinBoardServerTest {
|
||||||
assertThat(msg.getMsg().getData().toByteArray(), is(data[(int) msg.getEntryNum() - 1]));
|
assertThat(msg.getMsg().getData().toByteArray(), is(data[(int) msg.getEntryNum() - 1]));
|
||||||
|
|
||||||
// Assert signatures.
|
// Assert signatures.
|
||||||
|
|
||||||
if (msg.getEntryNum() % 2 == 1){
|
try {
|
||||||
signers[0].initVerify(msg.getSig(0));
|
|
||||||
signers[0].updateContent(msg.getMsg());
|
if (msg.getEntryNum() % 2 == 1) {
|
||||||
assertTrue("Signature did not verify!", signers[0].verify());
|
signers[0].initVerify(msg.getSig(0));
|
||||||
|
signers[0].updateContent(msg.getMsg());
|
||||||
if (msg.getEntryNum() % 4 == 1){
|
assertTrue("Signature did not verify!", signers[0].verify());
|
||||||
signers[1].initVerify(msg.getSig(1));
|
|
||||||
signers[1].updateContent(msg.getMsg());
|
if (msg.getEntryNum() % 4 == 1) {
|
||||||
assertTrue("Signature did not verify!", signers[1].verify());
|
signers[1].initVerify(msg.getSig(1));
|
||||||
|
signers[1].updateContent(msg.getMsg());
|
||||||
assertThat(msg.getSigCount(), is(2));
|
assertTrue("Signature did not verify!", signers[1].verify());
|
||||||
}
|
|
||||||
else{
|
assertThat(msg.getSigCount(), is(2));
|
||||||
assertThat(msg.getSigCount(), is(1));
|
} else {
|
||||||
}
|
assertThat(msg.getSigCount(), is(1));
|
||||||
}
|
}
|
||||||
else{
|
} else {
|
||||||
assertThat(msg.getSigCount(), is(0));
|
assertThat(msg.getSigCount(), is(0));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests retrieval of messages written in {@Link #testInsert()} using multiple tags/signature filters.
|
||||||
|
*/
|
||||||
|
public void testEnhancedTagsAndSignatures(){
|
||||||
|
|
||||||
|
List<BulletinBoardMessage> messages;
|
||||||
|
MessageFilterList.Builder filterListBuilder = MessageFilterList.newBuilder();
|
||||||
|
|
||||||
|
int expectedMsgCount = MESSAGE_NUM;
|
||||||
|
|
||||||
|
// Check multiple tag filters.
|
||||||
|
|
||||||
|
for (int i = 0 ; i < TAG_NUM ; i++) {
|
||||||
|
|
||||||
|
filterListBuilder.addFilter(
|
||||||
|
MessageFilter.newBuilder()
|
||||||
|
.setType(FilterType.TAG)
|
||||||
|
.setTag(tags[i])
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList();
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println("Failed retrieving multi-tag messages from DB: " + e.getMessage());
|
||||||
|
fail("Failed retrieving multi-tag messages from DB: " + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedMsgCount /= 2;
|
||||||
|
|
||||||
|
assertThat(messages.size(), is(expectedMsgCount));
|
||||||
|
|
||||||
|
for (BulletinBoardMessage msg : messages) {
|
||||||
|
for (int j = 0 ; j < i ; j++) {
|
||||||
|
assertThat((msg.getEntryNum() >>> j) % 2, is((long) 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check multiple signature filters.
|
||||||
|
|
||||||
|
filterListBuilder = MessageFilterList.newBuilder()
|
||||||
|
.addFilter(MessageFilter.newBuilder()
|
||||||
|
.setType(FilterType.SIGNER_ID)
|
||||||
|
.setId(signerIDs[0])
|
||||||
|
.build())
|
||||||
|
.addFilter(MessageFilter.newBuilder()
|
||||||
|
.setType(FilterType.SIGNER_ID)
|
||||||
|
.setId(signerIDs[1])
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList();
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println("Failed retrieving multi-signature message from DB: " + e.getMessage());
|
||||||
|
fail("Failed retrieving multi-signature message from DB: " + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(messages.size(), is(MESSAGE_NUM / 4));
|
||||||
|
|
||||||
|
for (BulletinBoardMessage message : messages) {
|
||||||
|
assertThat(message.getEntryNum() % 4, is((long) 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void close(){
|
public void close(){
|
||||||
signers[0].clearSigningKey();
|
signers[0].clearSigningKey();
|
||||||
signers[1].clearSigningKey();
|
signers[1].clearSigningKey();
|
||||||
|
try {
|
||||||
|
bulletinBoardServer.close();
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println("Error closing server " + e.getMessage());
|
||||||
|
fail("Error closing server " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package meerkat.bulletinboard;
|
||||||
|
|
||||||
|
import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer;
|
||||||
|
import meerkat.comm.CommunicationException;
|
||||||
|
import meerkat.protobuf.*;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.*;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Arbel Deutsch Peled on 07-Dec-15.
|
||||||
|
*/
|
||||||
|
public class SQLiteBulletinBoardServerTest{
|
||||||
|
|
||||||
|
private String testFilename = "SQLiteDBTest.db";
|
||||||
|
|
||||||
|
private GenericBulletinBoardServerTest serverTest;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init(){
|
||||||
|
|
||||||
|
File old = new File(testFilename);
|
||||||
|
old.delete();
|
||||||
|
|
||||||
|
BulletinBoardServer bulletinBoardServer = new SQLiteBulletinBoardServer();
|
||||||
|
try {
|
||||||
|
bulletinBoardServer.init(testFilename);
|
||||||
|
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
fail(e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serverTest = new GenericBulletinBoardServerTest();
|
||||||
|
try {
|
||||||
|
serverTest.init(bulletinBoardServer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bulkTest() {
|
||||||
|
try {
|
||||||
|
serverTest.testInsert();
|
||||||
|
serverTest.testSimpleTagAndSignature();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void close() {
|
||||||
|
serverTest.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue