/* * A CCNx library test. * * Copyright (C) 2008-2013 Palo Alto Research Center, Inc. * * This work is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * This work is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ package org.ccnx.ccn.test.profiles.nameenum; import java.io.IOException; import java.util.ArrayList; import java.util.Random; import junit.framework.Assert; import org.ccnx.ccn.impl.support.Log; import org.ccnx.ccn.profiles.nameenum.BasicNameEnumeratorListener; import org.ccnx.ccn.profiles.nameenum.CCNNameEnumerator; import org.ccnx.ccn.protocol.ContentName; import org.ccnx.ccn.protocol.MalformedContentNameStringException; import org.ccnx.ccn.test.CCNTestBase; import org.junit.Test; /** * Test the asynchronous interface to name enumeration. */ public class NameEnumeratorTest extends CCNTestBase implements BasicNameEnumeratorListener{ CCNNameEnumerator putne; CCNNameEnumerator getne; Random rand = new Random(); String namespaceString = "/parc.com"; ContentName namespace; String name1String = "/parc.com/registerTest/name1"; ContentName name1; String name2String = "/parc.com/registerTest/name2"; ContentName name2; String name2aString = "/parc.com/registerTest/name2/namea"; ContentName name2a; String name1StringDirty = "/parc.com/registerTest/name1TestDirty"; ContentName name1Dirty; String prefix1String = "/parc.com/registerTest"; String prefix1StringError = "/park.com/registerTest"; ArrayList<ContentName> names; Object namesLock = new Object(); ContentName prefix1; ContentName c1; ContentName c2; @Test public void testNameEnumerator() throws Exception { Log.info(Log.FAC_TEST, "Starting testNameEnumerator"); //set up CCN libraries for testing setupNE(); Assert.assertNotNull(putne); Assert.assertNotNull(getne); //tests that the names are properly registered (namespace and object names) testRegisterName(); //tests that prefixes are properly registered for exploring the namespace testRegisterPrefix(); //tests that an ArrayList of ContentNames was received for the registered prefix testGetCallback(); //register additional name to trigger (set responser dirty flag) a new response by the responder registerAdditionalName(); //verify that the new response with an updated list of names was received. testGetCallbackDirty(); //test that registered prefixes and their interests are canceled testCancelPrefix(); //verify that we only get a response for names with the correct prefix and that are active testGetCallbackNoResponse(); Log.info(Log.FAC_TEST, "Completed testNameEnumerator"); } public void testRegisterName() throws IOException{ Log.info(Log.FAC_TEST, "Starting testRegisterName"); try{ namespace = ContentName.fromNative(namespaceString); name1 = ContentName.fromNative(name1String); name2 = ContentName.fromNative(name2String); name2a = ContentName.fromNative(name2aString); } catch(Exception e){ Assert.fail("Could not create ContentName from "+name1String +" or "+name2String); } putne.registerNameSpace(namespace); putne.registerNameForResponses(name1); putne.registerNameForResponses(name2); putne.registerNameForResponses(name2a); ContentName nullName = null; putne.registerNameForResponses(nullName); try{ while(!putne.containsRegisteredName(name2a)){ Thread.sleep(rand.nextInt(50)); } //the names are registered... Log.info(Log.FAC_TEST, "the names are now registered"); } catch(InterruptedException e){ Log.warning(Log.FAC_TEST, "error waiting for names to be registered by name enumeration responder"); Assert.fail(); } Log.info(Log.FAC_TEST, "Completed testRegisterName"); } public void testRegisterPrefix(){ Log.info(Log.FAC_TEST, "Starting testRegisterPrefix"); try{ prefix1 = ContentName.fromNative(prefix1String); } catch(Exception e){ Assert.fail("Could not create ContentName from "+prefix1String); } Log.info(Log.FAC_TEST, "registering prefix: "+prefix1.toString()); try{ getne.registerPrefix(prefix1); } catch(IOException e){ Log.warning(Log.FAC_TEST, "error registering prefix"); Log.warningStackTrace(Log.FAC_TEST, e); Assert.fail(); } Log.info(Log.FAC_TEST, "Completed testRegisterPrefix"); } public void testGetCallback(){ Log.info(Log.FAC_TEST, "Starting testGetCallback"); int attempts = 1; try{ synchronized (namesLock) { while (null == names && attempts < 500){ namesLock.wait(50); attempts++; } } //we either broke out of loop or the names are here Log.info(Log.FAC_TEST, "done waiting for results to arrive: attempts " + attempts); } catch(InterruptedException e){ Log.warning(Log.FAC_TEST, "error waiting for names to be registered by name enumeration responder"); Assert.fail(); } synchronized (namesLock) { Assert.assertNotNull(names); for (ContentName cn: names){ Log.info(Log.FAC_TEST, "got name: "+cn.toString()); Assert.assertTrue(cn.toString().equals("/name1") || cn.toString().equals("/name2")); } names = null; } Log.info(Log.FAC_TEST, "Completed testGetCallback"); } public void registerAdditionalName(){ //now add new name try{ name1Dirty = ContentName.fromNative(name1StringDirty); putne.registerNameForResponses(name1Dirty); while(!putne.containsRegisteredName(name1Dirty)){ Thread.sleep(50); } //the names are registered... Log.info(Log.FAC_TEST, "the new name is now registered to trigger the dirty flag"); } catch(InterruptedException e){ Log.warning(Log.FAC_TEST, "error waiting for names to be registered by name enumeration responder"); Assert.fail(); } catch (MalformedContentNameStringException e) { // TODO Auto-generated catch block Log.warningStackTrace(Log.FAC_TEST, e); } } public void testGetCallbackDirty(){ Log.info(Log.FAC_TEST, "Starting testGetCallbackDirty"); int attempts = 1; try{ synchronized (namesLock) { while(names == null && attempts < 1000) { namesLock.wait(50); attempts++; } } //we either broke out of loop or the names are here Log.info(Log.FAC_TEST, "done waiting for results to arrive: attempts " + attempts); } catch(InterruptedException e){ Log.warning(Log.FAC_TEST, "error waiting for names to be registered by name enumeration responder"); Assert.fail(); } synchronized (namesLock) { Assert.assertNotNull(names); Assert.assertTrue(names.size()==3); for(ContentName cn: names){ Log.info(Log.FAC_TEST, "got name: "+cn.toString()); Assert.assertTrue(cn.toString().equals("/name1") || cn.toString().equals("/name2") || cn.toString().equals("/name1TestDirty")); } names = null; } Log.info(Log.FAC_TEST, "Completed testGetCallbackDirty"); } public void testCancelPrefix(){ Log.info(Log.FAC_TEST, "Starting testCancelPrefix"); ContentName prefix1Error = null; try{ prefix1Error = ContentName.fromNative(prefix1StringError); } catch(Exception e){ Log.warningStackTrace(Log.FAC_TEST, e); Assert.fail("Could not create ContentName from "+prefix1String); } //try to remove a prefix not registered Assert.assertFalse(getne.cancelPrefix(prefix1Error)); //remove the registered name Assert.assertTrue(getne.cancelPrefix(prefix1)); //try to remove the registered name again Assert.assertFalse(getne.cancelPrefix(prefix1)); Log.info(Log.FAC_TEST, "Completed testCancelPrefix"); } public void testGetCallbackNoResponse(){ Log.info(Log.FAC_TEST, "Starting testGetCallbackNoResponse"); ContentName p1 = null; try{ p1 = ContentName.fromNative(prefix1String+"NoNames"); } catch(Exception e){ Assert.fail("Could not create ContentName from "+prefix1String+"NoNames"); } Log.info(Log.FAC_TEST, "registering prefix: "+p1.toString()); try{ getne.registerPrefix(p1); } catch(IOException e){ Log.warning(Log.FAC_TEST, "error registering prefix"); Log.warningStackTrace(Log.FAC_TEST, e); Assert.fail(); } int attempts = 0; try{ synchronized (namesLock) { while(names==null && attempts < 100){ namesLock.wait(50); attempts++; } //we either broke out of loop or the names are here Log.info(Log.FAC_TEST, "done waiting for results to arrive"); Assert.assertNull(names); } getne.cancelPrefix(p1); } catch(InterruptedException e){ Log.info(Log.FAC_TEST, "error waiting for names to be registered by name enumeration responder"); Assert.fail(); } Log.info(Log.FAC_TEST, "Completed testGetCallbackNoResponse"); } public void testGetCallbackAfterCancel(){ Log.info(Log.FAC_TEST, "Starting testGetCallbackAfterCancel"); //assert names are still null in case we got a response even though the request was canceled synchronized (namesLock) { Assert.assertNull(names); } Log.info(Log.FAC_TEST, "Completed testGetCallbackAfterCancel"); } /* * function to create and set the Name Enumerator Objects * */ public void setupNE(){ putne = new CCNNameEnumerator(putHandle, this); getne = new CCNNameEnumerator(getHandle, this); } public int handleNameEnumerator(ContentName p, ArrayList<ContentName> n) { Log.info(Log.FAC_TEST, "got a callback!"); synchronized (namesLock) { names = new ArrayList<ContentName>(); for (ContentName name : n) names.add(name); namesLock.notify(); Log.info(Log.FAC_TEST, "here are the returned names: "); for (ContentName cn: names) Log.info(Log.FAC_TEST, cn.toString()+" ("+p.toString()+cn.toString()+")"); } return 0; } }