/* * A CCNx library test. * * Copyright (C) 2010, 2011, 2012 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.io.content; import java.util.Random; import org.ccnx.ccn.config.SystemConfiguration; import org.ccnx.ccn.impl.CCNFlowControl.SaveType; import org.ccnx.ccn.impl.security.crypto.CCNDigestHelper; import org.ccnx.ccn.impl.support.DataUtils; import org.ccnx.ccn.impl.support.Log; import org.ccnx.ccn.io.CCNReader; import org.ccnx.ccn.io.CCNRepositoryWriter; import org.ccnx.ccn.io.content.CCNStringObject; import org.ccnx.ccn.io.content.Link; import org.ccnx.ccn.io.content.LinkAuthenticator; import org.ccnx.ccn.io.content.Link.LinkObject; import org.ccnx.ccn.profiles.SegmentationProfile; import org.ccnx.ccn.protocol.CCNTime; import org.ccnx.ccn.protocol.ContentName; import org.ccnx.ccn.protocol.ContentObject; import org.ccnx.ccn.protocol.PublisherID; import org.ccnx.ccn.protocol.PublisherPublicKeyDigest; import org.ccnx.ccn.test.CCNTestBase; import org.ccnx.ccn.test.CCNTestHelper; import org.ccnx.ccn.test.TestUtils; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; public class LinkDereferenceTestRepo extends CCNTestBase { static CCNTestHelper testHelper = new CCNTestHelper(LinkDereferenceTestRepo.class); // Make some data, and some links. Test manual and automated dereferencing. static CCNStringObject data[] = new CCNStringObject[3]; static CCNStringObject gone; static ContentName bigData; static final int bigDataLength = SegmentationProfile.DEFAULT_BLOCKSIZE * 4 + 137; static String STRING_VALUE_NAME = "Value"; static String BIG_VALUE_NAME = "BigValue"; static String GONE_VALUE_NAME = "Gone"; static byte [] bigValueDigest; static byte [] bigDataContent; @BeforeClass public static void setUpBeforeClass() throws Exception { CCNTestBase.setUpBeforeClass(); CCNTime version = new CCNTime(); ContentName stringName = testHelper.getClassChildName(STRING_VALUE_NAME); for (int i=0; i < data.length; ++i) { // save multiple versions of the same object. data[i] = new CCNStringObject(stringName, "Value " + i, SaveType.REPOSITORY, putHandle); Log.info(Log.FAC_TEST, "Saving as version " + version); data[i].save(version); version.increment(1); // avoid version collisions } gone = new CCNStringObject(testHelper.getClassChildName(GONE_VALUE_NAME), GONE_VALUE_NAME, SaveType.REPOSITORY, putHandle); gone.saveAsGone(); TestUtils.checkObject(putHandle, gone); bigData = testHelper.getClassChildName(BIG_VALUE_NAME); bigDataContent = new byte [bigDataLength]; Random rand = new Random(); rand.nextBytes(bigDataContent); bigValueDigest = CCNDigestHelper.digest(bigDataContent); // generate some segmented data CCNRepositoryWriter writer = new CCNRepositoryWriter(putHandle); writer.newVersion(bigData, bigDataContent); } @Test public void testDereference() throws Exception { Log.info(Log.FAC_TEST, "Starting testDereference"); Link versionedLink = new Link(data[1].getVersionedName()); // Should get back a segment, ideally first, of that specific version. ContentObject versionedTarget = versionedLink.dereference(SystemConfiguration.getDefaultTimeout(), putHandle); Log.info(Log.FAC_TEST, "Dereferenced link {0}, retrieved content {1}", versionedLink, ((null == versionedTarget) ? "null" : versionedTarget.name())); Assert.assertNotNull(versionedTarget); Assert.assertTrue(versionedLink.targetName().isPrefixOf(versionedTarget.name())); Assert.assertTrue(SegmentationProfile.isFirstSegment(versionedTarget.name())); Link unversionedLink = new Link(data[1].getBaseName(), "unversioned", null); ContentObject unversionedTarget = unversionedLink.dereference(SystemConfiguration.getDefaultTimeout(), getHandle); Log.info(Log.FAC_TEST, "Dereferenced link {0}, retrieved content {1}", unversionedLink, ((null == unversionedTarget) ? "null" : unversionedTarget.name())); Assert.assertNotNull(unversionedTarget); Assert.assertTrue(unversionedLink.targetName().isPrefixOf(unversionedTarget.name())); Assert.assertTrue(data[data.length-1].getVersionedName().isPrefixOf(unversionedTarget.name())); Assert.assertTrue(SegmentationProfile.isFirstSegment(unversionedTarget.name())); Link bigDataLink = new Link(bigData, "big", new LinkAuthenticator(new PublisherID(putHandle.keyManager().getDefaultKeyID()))); ContentObject bigDataTarget = bigDataLink.dereference(SystemConfiguration.getDefaultTimeout(), putHandle); Log.info(Log.FAC_TEST, "BigData: Dereferenced link " + bigDataLink + ", retrieved content " + ((null == bigDataTarget) ? "null" : bigDataTarget.name())); Assert.assertNotNull(bigDataTarget); Assert.assertTrue(bigDataLink.targetName().isPrefixOf(bigDataTarget.name())); Assert.assertTrue(SegmentationProfile.isFirstSegment(bigDataTarget.name())); Log.info(Log.FAC_TEST, "Completed testDereference"); } @Test public void testMissingTarget() throws Exception { Log.info(Log.FAC_TEST, "Starting testMissingTarget"); Link linkToNowhere = new Link(testHelper.getTestChildName("testMissingTarget", "linkToNowhere")); ContentObject nothing = linkToNowhere.dereference(SystemConfiguration.SHORT_TIMEOUT, getHandle); Assert.assertNull(nothing); Log.info(Log.FAC_TEST, "Completed testMissingTarget"); } @Test public void testWrongPublisher() throws Exception { Log.info(Log.FAC_TEST, "Starting testWrongPublisher"); byte [] fakePublisher = new byte[PublisherID.PUBLISHER_ID_LEN]; PublisherID wrongPublisher = new PublisherID(new PublisherPublicKeyDigest(fakePublisher)); Link linkToWrongPublisher = new Link(bigData, new LinkAuthenticator(wrongPublisher)); ContentObject nothing = linkToWrongPublisher.dereference(SystemConfiguration.SHORT_TIMEOUT, getHandle); Assert.assertNull(nothing); Log.info(Log.FAC_TEST, "Completed testWrongPublisher"); } @Test public void testLinkToUnversioned() throws Exception { Log.info(Log.FAC_TEST, "Starting testLinkToUnversioned"); // test dereferencing link to unversioned data. CCNRepositoryWriter writer = new CCNRepositoryWriter(putHandle); ContentName unversionedDataName = testHelper.getTestChildName("testLinkToUnversioned", "UnversionedBigData"); // generate some segmented data; doesn't version the name writer.newVersion(unversionedDataName, bigDataContent); Link uvBigDataLink = new Link(unversionedDataName, "big", new LinkAuthenticator(new PublisherID(putHandle.keyManager().getDefaultKeyID()))); ContentObject bigDataTarget = uvBigDataLink.dereference(SystemConfiguration.SETTABLE_SHORT_TIMEOUT, getHandle); Log.info(Log.FAC_TEST, "BigData: Dereferenced link " + uvBigDataLink + ", retrieved content " + ((null == bigDataTarget) ? "null" : bigDataTarget.name())); Assert.assertNotNull(bigDataTarget); Assert.assertTrue(uvBigDataLink.targetName().isPrefixOf(bigDataTarget.name())); Assert.assertTrue(SegmentationProfile.isFirstSegment(bigDataTarget.name())); Log.info(Log.FAC_TEST, "Completed testLinkToUnversioned"); } @Test public void testAutomatedDereferenceForStreams() throws Exception { Log.info(Log.FAC_TEST, "Starting testAutomatedDereferenceForStreams"); Link bigDataLink = new Link(bigData, "big", new LinkAuthenticator(new PublisherID(putHandle.keyManager().getDefaultKeyID()))); LinkObject bigDataLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForStreams", "bigDataLink"), bigDataLink, SaveType.REPOSITORY, putHandle); bigDataLinkObject.save(); TestUtils.checkObject(putHandle, bigDataLinkObject); Link twoHopLink = new Link(bigDataLinkObject.getBaseName()); LinkObject twoHopLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForStreams", "twoHopLink"), twoHopLink, SaveType.REPOSITORY, putHandle); twoHopLinkObject.save(); TestUtils.checkObject(putHandle, twoHopLinkObject); CCNReader reader = new CCNReader(putHandle); byte [] bigDataReadback = reader.getVersionedData(bigDataLinkObject.getVersionedName(), null, SystemConfiguration.getDefaultTimeout()); byte [] bdrdigest = CCNDigestHelper.digest(bigDataReadback); Log.info(Log.FAC_TEST, "Read back big data via link, got " + bigDataReadback.length + " bytes of an expected " + bigDataLength + ", digest match? " + (0 == DataUtils.compare(bdrdigest, bigValueDigest))); Assert.assertEquals(bigDataLength, bigDataReadback.length); Assert.assertArrayEquals(bdrdigest, bigValueDigest); byte [] bigDataReadback2 = reader.getVersionedData(twoHopLinkObject.getBaseName(), null, SystemConfiguration.getDefaultTimeout()); byte [] bdr2digest = CCNDigestHelper.digest(bigDataReadback); Log.info(Log.FAC_TEST, "Read back big data via two links, got " + bigDataReadback2.length + " bytes of an expected " + bigDataLength + ", digest match? " + (0 == DataUtils.compare(bdr2digest, bigValueDigest))); Assert.assertEquals(bigDataLength, bigDataReadback2.length); Assert.assertArrayEquals(bdr2digest, bigValueDigest); Log.info(Log.FAC_TEST, "Completed testAutomatedDereferenceForStreams"); } @Test public void testAutomatedDereferenceForObjects() throws Exception { Log.info(Log.FAC_TEST, "Starting testAutomatedDereferenceForObjects"); Link versionedLink = new Link(data[1].getVersionedName()); LinkObject versionedLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForObjects", "versionedLink"), versionedLink, SaveType.REPOSITORY, putHandle); versionedLinkObject.save(); TestUtils.checkObject(putHandle, versionedLinkObject); Link unversionedLink = new Link(data[1].getBaseName()); LinkObject unversionedLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForObjects", "unversionedLink"), unversionedLink, SaveType.REPOSITORY, putHandle); unversionedLinkObject.save(); TestUtils.checkObject(putHandle, unversionedLinkObject); Link twoHopLink = new Link(unversionedLinkObject.getBaseName()); LinkObject twoHopLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForObjects", "twoHopLink"), twoHopLink, SaveType.REPOSITORY, putHandle); twoHopLinkObject.save(); TestUtils.checkObject(putHandle, twoHopLinkObject); // read via the name iself CCNStringObject readObjectControl = new CCNStringObject(data[data.length-1].getBaseName(), null); Assert.assertEquals(readObjectControl.getVersionedName(), data[data.length-1].getVersionedName()); Assert.assertEquals(readObjectControl.string(), data[data.length-1].string()); // read via the versioned link. CCNStringObject versionedReadObject = new CCNStringObject(versionedLinkObject.getBaseName(), getHandle); Assert.assertEquals(versionedReadObject.getVersionedName(), data[1].getVersionedName()); Assert.assertEquals(versionedReadObject.string(), data[1].string()); Assert.assertNotNull(versionedReadObject.getDereferencedLink()); Assert.assertEquals(versionedReadObject.getDereferencedLink(), versionedLinkObject); // read latest version via the unversioned link CCNStringObject unversionedReadObject = new CCNStringObject(unversionedLinkObject.getBaseName(), getHandle); Assert.assertEquals(unversionedReadObject.getVersionedName(), data[data.length-1].getVersionedName()); Assert.assertEquals(unversionedReadObject.string(), data[data.length-1].string()); Assert.assertNotNull(unversionedReadObject.getDereferencedLink()); Assert.assertEquals(unversionedReadObject.getDereferencedLink(), unversionedLinkObject); // read via the two-hop link CCNStringObject twoHopReadObject = new CCNStringObject(twoHopLinkObject.getBaseName(), getHandle); Assert.assertEquals(twoHopReadObject.getVersionedName(), data[data.length-1].getVersionedName()); Assert.assertEquals(twoHopReadObject.string(), data[data.length-1].string()); Assert.assertNotNull(twoHopReadObject.getDereferencedLink()); Assert.assertEquals(twoHopReadObject.getDereferencedLink(), unversionedLinkObject); Assert.assertNotNull(twoHopReadObject.getDereferencedLink().getDereferencedLink()); Assert.assertEquals(twoHopReadObject.getDereferencedLink().getDereferencedLink(), twoHopLinkObject); Log.info(Log.FAC_TEST, "Completed testAutomatedDereferenceForObjects"); } @Test public void testAutomatedDereferenceForGone() throws Exception { Log.info(Log.FAC_TEST, "Starting testAutomatedDereferenceForGone"); Link versionedLink = new Link(gone.getVersionedName()); LinkObject versionedLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForGone", "versionedLink"), versionedLink, SaveType.REPOSITORY, putHandle); versionedLinkObject.save(); TestUtils.checkObject(putHandle, versionedLinkObject); Link unversionedLink = new Link(gone.getBaseName()); LinkObject unversionedLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForGone", "unversionedLink"), unversionedLink, SaveType.REPOSITORY, putHandle); unversionedLinkObject.save(); TestUtils.checkObject(putHandle, unversionedLinkObject); Link twoHopLink = new Link(unversionedLinkObject.getBaseName()); LinkObject twoHopLinkObject = new LinkObject(testHelper.getTestChildName("testAutomatedDereferenceForGone", "twoHopLink"), twoHopLink, SaveType.REPOSITORY, putHandle); twoHopLinkObject.save(); TestUtils.checkObject(putHandle, twoHopLinkObject); // read via the name iself CCNStringObject readObjectControl = new CCNStringObject(gone.getBaseName(), null); Assert.assertEquals(readObjectControl.getVersionedName(), gone.getVersionedName()); Assert.assertTrue(readObjectControl.isGone()); // read via the versioned link. CCNStringObject versionedReadObject = new CCNStringObject(versionedLinkObject.getBaseName(), getHandle); Assert.assertEquals(versionedReadObject.getVersionedName(), gone.getVersionedName()); Assert.assertTrue(versionedReadObject.isGone()); Assert.assertNotNull(versionedReadObject.getDereferencedLink()); Assert.assertEquals(versionedReadObject.getDereferencedLink(), versionedLinkObject); // read latest version via the unversioned link CCNStringObject unversionedReadObject = new CCNStringObject(unversionedLinkObject.getBaseName(), getHandle); Assert.assertEquals(unversionedReadObject.getVersionedName(), gone.getVersionedName()); Assert.assertTrue(unversionedReadObject.isGone()); Assert.assertNotNull(unversionedReadObject.getDereferencedLink()); Assert.assertEquals(unversionedReadObject.getDereferencedLink(), unversionedLinkObject); // read via the two-hop link CCNStringObject twoHopReadObject = new CCNStringObject(twoHopLinkObject.getBaseName(), getHandle); Assert.assertEquals(twoHopReadObject.getVersionedName(), gone.getVersionedName()); Assert.assertTrue(twoHopReadObject.isGone()); Assert.assertNotNull(twoHopReadObject.getDereferencedLink()); Assert.assertEquals(twoHopReadObject.getDereferencedLink(), unversionedLinkObject); Assert.assertNotNull(twoHopReadObject.getDereferencedLink().getDereferencedLink()); Assert.assertEquals(twoHopReadObject.getDereferencedLink().getDereferencedLink(), twoHopLinkObject); Log.info(Log.FAC_TEST, "Completed testAutomatedDereferenceForGone"); } }