import com.google.common.util.concurrent.FutureCallback; import com.google.protobuf.InvalidProtocolBufferException; import junit.framework.TestCase; import meerkat.Registry; import meerkat.bulletinboard.AsyncBulletinBoardClient; import meerkat.bulletinboard.ThreadedBulletinBoardClient; import meerkat.crypto.DigitalSignature; import meerkat.crypto.concrete.ECDSASignature; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; import meerkat.protobuf.VoterRegistry; import meerkat.protobuf.VoterRegistry.GroupID; import meerkat.protobuf.VoterRegistry.VoterID; import meerkat.protobuf.VoterRegistry.VoterInfo; import meerkat.protobuf.Voting; import meerkat.registry.MessageCollectionUtils; import meerkat.registry.RegistryTags; import java.io.InputStream; import java.math.BigInteger; import java.security.KeyStore; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Semaphore; import static meerkat.util.BulletinBoardUtils.findTagWithPrefix; /** * TODO: add logs prints for the tests to be clear what they are */ /** * Created by Vladimir Eliezer Tokarev on 1/16/2016. * Tests the Simple registry contents * NOTE: for most of this tests to pass there should run BulletinBoardServer * that should be reachable on BULLETIN_BOARD_SERVER_ADDRESS */ public class SimpleRegistryTest extends TestCase { private Collection signers; private AsyncBulletinBoardClient bulletinBoardClient; private InputStream certStream; private SecureRandom random = new SecureRandom(); public static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; public static String KEYFILE_PASSWORD = "secret"; Semaphore jobSemaphore; class DummyRegistryCallBackHandler implements meerkat.VoterRegistry.RegistryCallBack{ public int counter; public T data; public DummyRegistryCallBackHandler() { counter=0; } @Override public void handleResult(T result) { counter++; data = result; jobSemaphore.release(); } @Override public void handleFailure(Throwable throwable) { } } public class DummyBulletinBoardCallBackHandler implements FutureCallback> { public List messages; @Override public void onSuccess(List msg) { messages = msg; jobSemaphore.release(); } @Override public void onFailure(Throwable t){ messages = null; jobSemaphore.release(); } } private void createCertificateStream() { this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); } private void CommunicatorSetup() { bulletinBoardClient = new ThreadedBulletinBoardClient(); String BULLETIN_BOARD_SERVER_ADDRESS = "http://localhost:8081/"; bulletinBoardClient.init(Voting.BulletinBoardClientParams.newBuilder() .addBulletinBoardAddress(BULLETIN_BOARD_SERVER_ADDRESS) .setMinRedundancy((float) 1.0) .build()); } private void SetSigner(){ try { signers = new ArrayList<>(); ECDSASignature signer = new ECDSASignature(); InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); char[] password = KEYFILE_PASSWORD.toCharArray(); KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); signer.loadSigningCertificate(keyStore); keyStream.close(); signers.add(signer); } catch (Exception e){ assert false : "The signers creation failed "; } } /** * Initialize registry object */ public void setUp() { SetSigner(); CommunicatorSetup(); createCertificateStream(); jobSemaphore = new Semaphore(0); } private Registry GetRegistry() { Registry registry = new Registry(); registry.init(signers, bulletinBoardClient, certStream); return registry; } /** * Checks if the creation of the registry have been successful */ public void testSimpleRegistryCreation() { try { Registry registry = GetRegistry(); } catch (Exception e) { assert false : "While creating the registry exception have been thrown " + e; } } /** * Counts the amount of messages from messages that have all the wanted tags inside * @param messages List * @param tags List * @return integer that represent the amount of messages with wanted tags */ private int countMessagesWithTags(List messages, List tags) { int counter = 0 ; for (BulletinBoardMessage message : messages) { int wantedTagsCounter = 0; for (String tag : tags) { if(findTagWithPrefix(message, tag)!=null){ wantedTagsCounter++; } } if(wantedTagsCounter == tags.size()) { counter++; } } return counter; } /** * Test that add voter creates new correct bulletin board message and adds the voter */ public void testAddVoter() throws InvalidProtocolBufferException, InterruptedException { DummyRegistryCallBackHandler handler = new DummyRegistryCallBackHandler<>(); String id = new BigInteger(130, random).toString(32); String data = new BigInteger(130, random).toString(32); VoterInfo voterInfo = VoterInfo.newBuilder().setId(VoterID.newBuilder().setId(id)).setInfo(data).build(); Registry registry = GetRegistry(); registry.addVoter(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter ); List tags = new ArrayList(){{ add(RegistryTags.VOTER_ENTRY_TAG);}}; MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags); DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler(); bulletinBoardClient.readMessages(filters, bulletinHandler); jobSemaphore.acquire(); tags.clear(); tags.add(RegistryTags.ID_TAG + id); int counter = countMessagesWithTags(bulletinHandler.messages, tags); assert counter == 1 : "The server don't have the new user data."; } /** * Test that set voted posts creates correct bulletin board message and sets that the user have been voted */ public void testSetVoted() throws InvalidProtocolBufferException, InterruptedException { DummyRegistryCallBackHandler handler = new DummyRegistryCallBackHandler<>(); String id = new BigInteger(130, random).toString(32); VoterID voterInfo = VoterID.newBuilder().setId(id).build(); Registry registry = GetRegistry(); registry.setVoted(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter ); List tags = new ArrayList(){{ add(RegistryTags.VOTE_ACTION_TAG);}}; MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags); DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler(); bulletinBoardClient.readMessages(filters, bulletinHandler); jobSemaphore.acquire(); tags.clear(); tags.add(RegistryTags.ID_TAG + id); int counter = countMessagesWithTags(bulletinHandler.messages, tags); assert counter == 1 : "The server don't have the new user id."; } /** * Test that get groups retrieves the right groups the user are in */ public void testAddToGroup() throws InvalidProtocolBufferException, InterruptedException { DummyRegistryCallBackHandler handler = new DummyRegistryCallBackHandler<>(); String voterId = new BigInteger(130, random).toString(32); String groupId = new BigInteger(130, random).toString(32); VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder() .setVoterID(VoterID.newBuilder().setId(voterId)) .addGroupID(GroupID.newBuilder().setId(groupId)).build(); Registry registry = GetRegistry(); registry.addToGroups(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter); List tags = new ArrayList(){{add(RegistryTags.ADD_TO_GROUP_TAG);}}; MessageFilterList filters = MessageCollectionUtils.generateFiltersFromTags(tags); DummyBulletinBoardCallBackHandler bulletinHandler = new DummyBulletinBoardCallBackHandler(); bulletinBoardClient.readMessages(filters, bulletinHandler); jobSemaphore.acquire(); tags.clear(); tags.add(RegistryTags.ID_TAG + voterId); tags.add(RegistryTags.GROUP_ID_TAG + groupId); int counter = countMessagesWithTags(bulletinHandler.messages, tags); assert counter == 1 : "The server don't have the new user added to group."; } /** * Test that remove from group creates correct bulletin board message and removes the user from a group */ public void testGetGroups() throws InvalidProtocolBufferException, InterruptedException { DummyRegistryCallBackHandler> handler = new DummyRegistryCallBackHandler<>(); String voterId = new BigInteger(130, random).toString(32); String groupId = new BigInteger(130, random).toString(32); VoterRegistry.VoterRegistryMessage voterInfo = VoterRegistry.VoterRegistryMessage.newBuilder() .setVoterID(VoterID.newBuilder().setId(voterId)) .addGroupID(GroupID.newBuilder().setId(groupId)).build(); this.certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); Registry registry = GetRegistry(); registry.addToGroups(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter ); DummyRegistryCallBackHandler> groupsHandler = new DummyRegistryCallBackHandler<>(); registry.getGroups(GroupID.newBuilder().setId(groupId).build(), groupsHandler); jobSemaphore.acquire(1); List userGroups = groupsHandler.data; assert userGroups.contains(groupId) : "The simple voter registry object does not retrieved right user groups"; } /** * Test that the personal data outputted about the user is right */ public void testGetPersonalIDDetails() throws InvalidProtocolBufferException, InterruptedException { DummyRegistryCallBackHandler> handler = new DummyRegistryCallBackHandler<>(); String id = new BigInteger(130, random).toString(32); String data = new BigInteger(130, random).toString(32); VoterInfo voterInfo = VoterInfo.newBuilder(). setId(VoterID.newBuilder().setId(id)).setInfo(data).build(); Registry registry = GetRegistry(); registry.addVoter(voterInfo, handler); jobSemaphore.acquire(); assertEquals(1, handler.counter ); DummyRegistryCallBackHandler personalHandler = new DummyRegistryCallBackHandler<>(); registry.getPersonIDDetails(VoterID.newBuilder().setId(id).build(), personalHandler); jobSemaphore.acquire(1); assertEquals(id, findTagWithPrefix(personalHandler.data, RegistryTags.ID_TAG)); assertTrue(findTagWithPrefix(personalHandler.data, RegistryTags.VOTER_DATA_TAG).contains(data)); } }