import com.google.protobuf.InvalidProtocolBufferException; import junit.framework.TestCase; import meerkat.RegistryCallBack; import meerkat.SimpleRegistry; import meerkat.VoterRegistryMessage; import meerkat.bulletinboard.SimpleBulletinBoardClient; import meerkat.crypto.concrete.ECElGamalEncryption; import meerkat.crypto.concrete.ECElGamalUtils; import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.Voting; import org.factcenter.qilin.primitives.concrete.ECElGamal; import org.factcenter.qilin.primitives.concrete.ECGroup; import util.RegistryTags; import util.SimpleRegistryCallBackHandler; import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.ArrayList; import java.util.List; import static util.CollectionMessagesUtils.ConvertToVoterRegistryMessages; import static util.CollectionMessagesUtils.GetUnsignedBulletinBoardMessages; /** * 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 ECElGamalEncryption signatory; private SimpleBulletinBoardClient communicator; private static String BULLETIN_BOARD_SERVER_ADDRESS = "http://localhost:8081"; private SecureRandom random = new SecureRandom(); /** * Creates the ElGamal encryption object */ private void ElGamalSetup() { try { ECGroup group = new ECGroup("secp256k1"); BigInteger sk = ECElGamal.generateSecretKey(group, random); ECElGamal.SK key = new ECElGamal.SK(group, sk); ConcreteCrypto.ElGamalPublicKey serializedPk = ECElGamalUtils.serializePk(group, key); signatory = new ECElGamalEncryption(); signatory.init(serializedPk); } catch (InvalidKeySpecException e) { assertTrue(false); } } /** * Creates the communication object (the bulletinBoardClient) */ private void CommunicatorSetup() { communicator = new SimpleBulletinBoardClient(); communicator.init(Voting.BulletinBoardClientParams.newBuilder() .addBulletinBoardAddress(BULLETIN_BOARD_SERVER_ADDRESS) .setMinRedundancy((float) 1.0) .build()); } private SimpleRegistryCallBackHandler RegistryAnswersHandlerSetup() { return new SimpleRegistryCallBackHandler(); } /** * Initialize SimpleRegistry object */ public void setUp() { ElGamalSetup(); CommunicatorSetup(); } /** * Checks if the creation of the registry have been successful */ public void testSimpleRegistryCreation() { try { new SimpleRegistry(signatory, communicator); } catch (Exception e) { assert false : "While creating the SimpleRegistry exception have been thrown " + e; } } /** * Creates list of lists of strings for different testing purposes * @param actionDataNumber number of string in a list * @param numberOfInstances number of lists in a list * @return List> */ private List> getActionsData(int actionDataNumber, int numberOfInstances) { System.out.println("- Creating "+ numberOfInstances +" ids and personal data strings for adding different voters."); List> actionData = new ArrayList<>(); for (int i = 0 ; i < numberOfInstances ; i++ ){ List data = new ArrayList<>(); for (int j = 0 ; j < actionDataNumber ; j++){ data.add(new BigInteger(130, random).toString(32)); } actionData.add(data); } return actionData; } /** * Create Message filter list from list of tags * @param tags list of string with wanted tags * @return MessageFilterList */ private BulletinBoardAPI.MessageFilterList createFiltersFromTags(List tags){ if (tags == null){ return BulletinBoardAPI.MessageFilterList.newBuilder().build(); } BulletinBoardAPI.MessageFilterList.Builder filters = BulletinBoardAPI.MessageFilterList.newBuilder(); for (String tag : tags) { filters.addFilter(BulletinBoardAPI.MessageFilter.newBuilder() .setTag(tag).setType(BulletinBoardAPI.FilterType.TAG)); } return filters.build(); } /** * Counts the amount of posted messaages that have their tags in voterData * @param votersData List> of information about voters (tags etc...) * @param tags List of tags * @return int * @throws InvalidProtocolBufferException */ private int countActualAddedMessages(List> votersData, List tags) throws InvalidProtocolBufferException { System.out.println("- Check that the server have the new voters data:"); BulletinBoardAPI.MessageFilterList filters = createFiltersFromTags(tags); List messages = ConvertToVoterRegistryMessages(GetUnsignedBulletinBoardMessages(communicator.readMessages(filters))); System.out.println(messages.size() + " asdasasdasdasasasdaasddas"); int addedMessagesCounter = 0; for (List voterData : votersData) { for (VoterRegistryMessage message : messages) { String addedVoterId = message.GetWantedTagFromBasicMessage(RegistryTags.ID_TAG); String addedVoterData = new String(message.base.getData().toByteArray()); if (voterData.size() == 2 && addedVoterId.contains(voterData.get(0)) && addedVoterData.contains(voterData.get(1))) { addedMessagesCounter++; } else if (addedVoterId.contains(voterData.get(0)) ){ addedMessagesCounter++; } } } return addedMessagesCounter; } /** * Call methodToCheck voterData as list of params * @param methodToCheck the name of the wanted method * @param numberOfParamsWithoutHandler the amount of params to pass to the wanted method * @param handler object which method will be called as callback from SimpleRegistry * @param registry the simpleRegistry object * @param voterData List of string which is the params to pass to the wantedMethod */ private void CallWantedMethod(String methodToCheck, int numberOfParamsWithoutHandler, SimpleRegistryCallBackHandler handler, SimpleRegistry registry, List voterData) { try { if (numberOfParamsWithoutHandler == 1) { java.lang.reflect.Method method = registry.getClass().getMethod(methodToCheck,String.class, RegistryCallBack.class); method.invoke(registry, voterData.get(0), handler); assertTrue(handler.ActionSucceed); }else { java.lang.reflect.Method method = registry.getClass().getMethod( methodToCheck, String.class, String.class, RegistryCallBack.class); method.invoke(registry, voterData.get(0), voterData.get(1), handler); assertTrue(handler.ActionSucceed); } } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { e.printStackTrace(); } } /** * Creates new Registry information then sends it to the server then checks the server * have all sent data * @param methodToCheck the name of the method we want to call in SimpleRegistry * @param numberOfParamsToPass the number of params to pass to the methodToCheck * @param numberOfChecks the amount of checks to run * @param tags list of String that represent the tags to filter on the messages * @throws InvalidProtocolBufferException */ private void checkMessagesPostedSuccessfully(String methodToCheck, int numberOfParamsToPass, int numberOfChecks, List tags) throws InvalidProtocolBufferException { SimpleRegistryCallBackHandler handler = RegistryAnswersHandlerSetup(); System.out.println("Starting testing the " + methodToCheck + " capability."); List> votersData = getActionsData(numberOfParamsToPass, numberOfChecks); SimpleRegistry registry = new SimpleRegistry(signatory, communicator); System.out.println("- Check that all the callbacks have been called successfully after voters adding:"); for (List voterData : votersData) { CallWantedMethod(methodToCheck, numberOfParamsToPass, handler, registry, voterData); } System.out.println("- Check that for every voter added, the callback have been called:"); assertEquals(numberOfChecks, handler.counter); int addedMessagesCounter = countActualAddedMessages(votersData, tags); assert addedMessagesCounter == numberOfChecks : "The number of added messages actually is " + addedMessagesCounter; System.out.println("Ended addVoter testing."); } /** * Test that add voter creates new correct bulletin board message and adds the voter */ public void testAddVoter() throws InvalidProtocolBufferException { checkMessagesPostedSuccessfully("AddVoter", 2, 3, new ArrayList(){{add(RegistryTags.VOTER_ENTRY_TAG.toString());}}); } /** * Test that set voted posts creates correct bulletin board message and sets that the user have been voted */ public void testSetVoted() throws InvalidProtocolBufferException { checkMessagesPostedSuccessfully("SetVoted", 1, 3, new ArrayList(){{add(RegistryTags.VOTE_ACTION_TAG.toString());}}); } /** * Test that add to group creates correct bulletin board message and adds a user to a group */ public void testRemoveFromGroup() throws InvalidProtocolBufferException { checkMessagesPostedSuccessfully("RemoveFromGroup", 2, 3, null); } /** * Test that remove from group creates correct bulletin board message and removes the user from a group */ public void testGetGroups() { // print start of gorups testing // Create Registry check creation // Add to X groups remove y group and z group // for every action check that it happened // count the number of callback activated // get the relevant groups // check they are right // print and of groups } /** * Test that get groups retrieves the right groups the user are in */ public void testAddToGroup() throws InvalidProtocolBufferException { checkMessagesPostedSuccessfully("AddToGroup", 2, 3, null); } /** * Test that the personal data outputted about the user is right */ public void testGetPersonalIDDetails() { assertEquals(1, null); } }