aboutsummaryrefslogtreecommitdiffstats
path: root/libccnx-portal/ccnx/api/ccnx_Portal/test
diff options
context:
space:
mode:
Diffstat (limited to 'libccnx-portal/ccnx/api/ccnx_Portal/test')
-rw-r--r--libccnx-portal/ccnx/api/ccnx_Portal/test/.gitignore9
-rw-r--r--libccnx-portal/ccnx/api/ccnx_Portal/test/CMakeLists.txt18
-rw-r--r--libccnx-portal/ccnx/api/ccnx_Portal/test/LOG25
-rw-r--r--libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_Portal.c826
-rwxr-xr-xlibccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAPI.c175
-rw-r--r--libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAnchor.c286
-rw-r--r--libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalFactory.c245
-rwxr-xr-xlibccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalRTA.c217
-rwxr-xr-xlibccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalStack.c366
9 files changed, 2167 insertions, 0 deletions
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/.gitignore b/libccnx-portal/ccnx/api/ccnx_Portal/test/.gitignore
new file mode 100644
index 00000000..1d17bd28
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/.gitignore
@@ -0,0 +1,9 @@
+my_keystore
+test_ccnx_Portal
+test_ccnx_PortalAPI
+test_ccnx_PortalFactory
+test_ccnx_PortalImplementation
+test_ccnx_PortalImplementation_keystore
+test_ccnx_PortalStack
+test_ccnx_PortalRTA
+test_ccnx_PortalAnchor
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/CMakeLists.txt b/libccnx-portal/ccnx/api/ccnx_Portal/test/CMakeLists.txt
new file mode 100644
index 00000000..88ce6f1a
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Enable gcov output for the tests
+add_definitions(--coverage)
+set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
+
+set(TestsExpectedToPass
+ test_ccnx_Portal
+ test_ccnx_PortalFactory
+ test_ccnx_PortalStack
+ test_ccnx_PortalAPI
+ test_ccnx_PortalRTA
+ test_ccnx_PortalAnchor
+)
+
+
+foreach(test ${TestsExpectedToPass})
+ AddTest(${test})
+endforeach()
+
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/LOG b/libccnx-portal/ccnx/api/ccnx_Portal/test/LOG
new file mode 100644
index 00000000..b12907ad
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/LOG
@@ -0,0 +1,25 @@
+Tue Nov 17 11:07:47 PST 2015
+test_ccnx_Portal: 2 fixtures
+test_ccnx_Portal/Global: Ran 15 test cases. 100% (15) succeeded
+test_ccnx_Portal/Global/ccnxPortal_Open 1.003460s 0.000000s 0.000000s 58088 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Open_NonBlocking 1.004843s 0.000000s 0.000000s 7633 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Send 1.005196s 0.000000s 0.000000s 9095 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_GetStatus 1.005718s 0.000000s 0.000000s 8515 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_GetError 1.001110s 0.000000s 0.000000s 9675 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_GetFileId 1.004810s 0.000000s 0.000000s 9326 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Listen 1.005183s 0.000000s 0.000000s 11009 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Ignore 1.002009s 0.000000s 0.000000s 12281 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_GetKeyId 1.004295s 0.000000s 0.000000s 6628 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_IsEOF 1.001509s 0.000000s 0.000000s 8789 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_IsError 1.001177s 0.000000s 0.000000s 9116 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Receive_NeverTimeout 1.004686s 0.000000s 0.000000s 14333 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Receive_ImmediateTimeout 3.005053s 0.000000s 0.000000s 22072 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Receive_ImmediateTimeout_NoData 1.003191s 0.000000s 0.000000s 6700 Succeeded
+test_ccnx_Portal/Global/ccnxPortal_Receive_5SecondTimeout 6.005013s 0.000000s 0.000000s 16884 Succeeded
+test_ccnx_Portal/Performance: Ran 3 test cases. 100% (3) succeeded
+test_ccnx_Portal/Performance/ccnxPortalFactory_CreatePortal 4.504010s 0.000000s 0.000000s 4582325 Succeeded
+test_ccnx_Portal/Performance/ccnxPortal_Send 23.504715s 0.000000s 0.000000s 92851121 Succeeded
+test_ccnx_Portal/Performance/ccnxPortal_SendReceive 1.004153s 0.000000s 0.000000s 11961 Succeeded
+Program ended with exit code: 0
+
+
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_Portal.c b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_Portal.c
new file mode 100644
index 00000000..154b8be8
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_Portal.c
@@ -0,0 +1,826 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include "../ccnx_Portal.c"
+
+#include <LongBow/unit-test.h>
+#include <LongBow/debugging.h>
+
+#include <stdio.h>
+#include <sys/errno.h>
+
+#include <ccnx/api/ccnx_Portal/ccnx_PortalRTA.h>
+#include <ccnx/api/ccnx_Portal/ccnx_PortalAPI.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <parc/testing/parc_ObjectTesting.h>
+#include <parc/testing/parc_MemoryTesting.h>
+
+#include <parc/developer/parc_Stopwatch.h>
+
+#include <ccnx/transport/test_tools/bent_pipe.h>
+
+#include <parc/security/parc_IdentityFile.h>
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_Pkcs12KeyStore.h>
+
+//#define USE_APILOOPBACK
+
+#ifdef USE_APILOOPBACK
+# define TEST_STACK ccnxPortalAPI_LoopBack
+#else
+# define TEST_STACK ccnxPortalRTA_LoopBack
+#endif
+
+LONGBOW_TEST_RUNNER(test_ccnx_Portal /*, .requires="FeatureLongBowSubProcess"*/)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Performance);
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+#define perTestCase
+
+LONGBOW_TEST_RUNNER_SETUP(test_ccnx_Portal)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_RUNNER_TEARDOWN(test_ccnx_Portal)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Open);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Open_NonBlocking);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Send);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_GetStatus);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_GetError);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_GetFileId);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Listen);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Ignore);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_GetKeyId);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_IsEOF);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_IsError);
+
+// LONGBOW_RUN_TEST_CASE(Global, Hello);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Receive_NeverTimeout);
+// LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Receive_NeverTimeout_Hang);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Receive_ImmediateTimeout);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Receive_ImmediateTimeout_NoData);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Receive_5SecondTimeout);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Send_NeverTimeout);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Send_ImmediateTimeout);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortal_Send_ImmediateTimeout_WouldBlock);
+}
+
+static uint32_t InitialMemoryOutstanding = 0;
+
+typedef struct test_data {
+ BentPipeState *bentpipe;
+ CCNxPortalFactory *factory;
+} TestData;
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ InitialMemoryOutstanding = parcMemory_Outstanding();
+ if (InitialMemoryOutstanding != 0) {
+ printf("Global fixture setup has outstanding allocations %u\n", InitialMemoryOutstanding);
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ }
+
+ TestData *data = parcMemory_Allocate(sizeof(TestData));
+
+ char bent_pipe_name[1024];
+ static const char bent_pipe_format[] = "/tmp/test_ccnx_Portal%d.sock";
+ sprintf(bent_pipe_name, bent_pipe_format, getpid());
+ unlink(bent_pipe_name);
+ setenv("BENT_PIPE_NAME", bent_pipe_name, 1);
+
+ data->bentpipe = bentpipe_Create(bent_pipe_name);
+ bentpipe_Start(data->bentpipe);
+
+ unsigned int keyLength = 1024;
+ unsigned int validityDays = 30;
+ char *subjectName = "test_ccnx_Portal";
+
+ parcSecurity_Init();
+
+ bool success = parcPkcs12KeyStore_CreateFile("my_keystore", "my_keystore_password", subjectName, keyLength, validityDays);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('my_keystore', 'my_keystore_password') failed.");
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create("my_keystore", "my_keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+ parcIdentityFile_Release(&identityFile);
+
+ data->factory = ccnxPortalFactory_Create(identity);
+ parcIdentity_Release(&identity);
+
+ longBowTestCase_SetClipBoardData(testCase, data);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ sleep(2);
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ ccnxPortalFactory_Release(&data->factory);
+
+ bentpipe_Stop(data->bentpipe);
+ bentpipe_Destroy(&data->bentpipe);
+
+ parcMemory_Deallocate((void **) &data);
+ unsetenv("BENT_PIPE_NAME");
+ parcSecurity_Fini();
+
+ if (parcMemory_Outstanding() != InitialMemoryOutstanding) {
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ printf("('%s' leaks memory by %d\n",
+ longBowTestCase_GetName(testCase), parcMemory_Outstanding() - InitialMemoryOutstanding);
+// return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+char *keyStoreFileName = "/tmp/test_ccnx_Portal.keystore";
+char *keyStorePassWord = "password";
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Open)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ parcObjectTesting_AssertAcquire(portal);
+
+ ccnxPortal_Release(&portal);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Open_NonBlocking)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+
+ parcObjectTesting_AssertAcquire(portal);
+
+ ccnxPortal_Release(&portal);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Send)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+ bool actual = ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+
+ ccnxMetaMessage_Release(&message);
+ ccnxInterest_Release(&interest);
+
+ ccnxPortal_Release(&portal);
+
+ assertTrue(actual, "Expected ccnxPortal_Send to be successful.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_GetStatus)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+
+ const CCNxPortalStatus *status = ccnxPortal_GetStatus(portal);
+
+ ccnxMetaMessage_Release(&message);
+ ccnxInterest_Release(&interest);
+
+ ccnxPortal_Release(&portal);
+
+ assertNotNull(status, "Expected non-null result from ccnxPortal_GetStatus");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_GetError)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+
+ const int error = ccnxPortal_GetError(portal);
+
+ ccnxMetaMessage_Release(&message);
+ ccnxInterest_Release(&interest);
+
+ ccnxPortal_Release(&portal);
+
+ assertTrue(error == 0, "Expected 0 result from ccnxPortal_GetError");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_GetFileId)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+ ccnxInterest_Release(&interest);
+
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+ int fileId = ccnxPortal_GetFileId(portal);
+ assertTrue(fileId != -1, "Expected ccnxPortal_GetFileId to not return -1");
+ ccnxPortal_Release(&portal);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_IsEOF)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+
+ bool actual = ccnxPortal_IsEOF(portal);
+
+ ccnxInterest_Release(&interest);
+ ccnxMetaMessage_Release(&message);
+
+ ccnxPortal_Release(&portal);
+
+ assertFalse(actual, "Expected to not be at EOF");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_IsError)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+
+ bool actual = ccnxPortal_IsError(portal);
+
+ ccnxMetaMessage_Release(&message);
+ ccnxInterest_Release(&interest);
+
+ ccnxPortal_Release(&portal);
+
+ assertFalse(actual, "Expected not to have an error status");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Listen)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ bool actual = ccnxPortal_Listen(portal, name, 60, CCNxStackTimeout_Never);
+
+ ccnxName_Release(&name);
+
+ ccnxPortal_Release(&portal);
+
+ assertTrue(actual, "Expected ccnxPortal_Listen to return true");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Ignore)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ bool actual = ccnxPortal_Ignore(portal, name, CCNxStackTimeout_Never);
+ ccnxName_Release(&name);
+
+ ccnxPortal_Release(&portal);
+
+ assertTrue(actual, "Expected ccnxPortal_Ignore to return true");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_GetKeyId)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ const PARCKeyId *actual = ccnxPortal_GetKeyId(portal);
+ const PARCKeyId *expected = ccnxPortalFactory_GetKeyId(data->factory);
+
+ ccnxPortal_Release(&portal);
+
+ assertTrue(parcKeyId_Equals(actual, expected), "Expected the PARCKeyId instances to be equal.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Send_NeverTimeout)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalOut = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+ ccnxInterest_Release(&interest);
+
+ if (ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Never)) {
+ ccnxMetaMessage_Release(&interestMessage);
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+ }
+
+ ccnxPortal_Release(&portalIn);
+ ccnxPortal_Release(&portalOut);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Send_ImmediateTimeout)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalOut = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+ ccnxInterest_Release(&interest);
+
+ if (ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Immediate)) {
+ ccnxMetaMessage_Release(&interestMessage);
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+ }
+
+ ccnxPortal_Release(&portalIn);
+ ccnxPortal_Release(&portalOut);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Send_ImmediateTimeout_WouldBlock)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalOut = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+
+ for (int count = 0; count < 10000; count++) {
+ if (ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Immediate) == false) {
+ break;
+ }
+ count++;
+ }
+
+ assertFalse(ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Immediate),
+ "Expected send to fail due to blocking");
+
+ ccnxMetaMessage_Release(&interestMessage);
+ ccnxInterest_Release(&interest);
+ ccnxPortal_Release(&portalOut);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Receive_NeverTimeout)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalOut = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+ ccnxInterest_Release(&interest);
+
+ if (ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Never)) {
+ ccnxMetaMessage_Release(&interestMessage);
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+ }
+
+ ccnxPortal_Release(&portalIn);
+ ccnxPortal_Release(&portalOut);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Receive_NeverTimeout_Hang)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+ ccnxPortal_Release(&portalIn);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Receive_ImmediateTimeout)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalOut = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+
+ if (ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Never)) {
+ sleep(2);
+ ccnxMetaMessage_Release(&interestMessage);
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Immediate);
+
+ assertTrue(ccnxInterest_Equals(interest, ccnxMetaMessage_GetInterest(message)), "Expected Interest to be received.");
+ ccnxMetaMessage_Release(&message);
+ }
+
+ ccnxInterest_Release(&interest);
+ ccnxPortal_Release(&portalIn);
+ ccnxPortal_Release(&portalOut);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Receive_ImmediateTimeout_NoData)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ ccnxPortal_Receive(portalIn, CCNxStackTimeout_Immediate);
+ assertTrue(errno == ENOMSG, "Expected errno to be set to ENOMSG, actual %s", strerror(errno));
+
+ ccnxPortal_Release(&portalIn);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortal_Receive_5SecondTimeout)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ ccnxPortal_Receive(portalIn, CCNxStackTimeout_MicroSeconds(5000000));
+ assertTrue(errno == ENOMSG, "Expected errno to be set to ENOMSG, actual %s", strerror(errno));
+
+ ccnxPortal_Release(&portalIn);
+}
+
+LONGBOW_TEST_CASE(Global, Hello)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ CCNxPortal *portalIn = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ assertNotNull(portal, "Expected a non-null CCNxPortal pointer.");
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+
+ if (ccnxPortal_Send(portal, interestMessage, CCNxStackTimeout_Never)) {
+ for (int responses = 0; responses == 0; ) {
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Never);
+ if (message != NULL) {
+ if (ccnxMetaMessage_IsContentObject(message)) {
+ CCNxContentObject *contentObject = ccnxMetaMessage_GetContentObject(message);
+
+ PARCBuffer *payload = ccnxContentObject_GetPayload(contentObject);
+ if (parcBuffer_HasRemaining(payload) == false) {
+ fprintf(stderr, "**************** Content object has arrived WITH EMPTY CONTENT\n");
+ } else {
+ char *string = parcBuffer_ToString(payload);
+ fprintf(stderr, "**************** Content object has arrived: %s\n", string);
+ parcMemory_Deallocate((void **) &string);
+ }
+ responses++;
+ }
+ ccnxMetaMessage_Release(&message);
+ }
+ }
+ }
+
+ ccnxMetaMessage_Release(&interestMessage);
+ ccnxPortal_Release(&portal);
+}
+
+LONGBOW_TEST_FIXTURE_OPTIONS(Performance, .enabled = false)
+{
+ LONGBOW_RUN_TEST_CASE(Performance, ccnxPortal_SendReceive);
+ LONGBOW_RUN_TEST_CASE(Performance, ccnxPortalFactory_CreatePortal);
+ LONGBOW_RUN_TEST_CASE(Performance, ccnxPortal_Send);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Performance)
+{
+ InitialMemoryOutstanding = parcMemory_Outstanding();
+
+ TestData *data = parcMemory_Allocate(sizeof(TestData));
+
+ char bent_pipe_name[1024];
+ static const char bent_pipe_format[] = "/tmp/test_ccnx_Portal%d.sock";
+ sprintf(bent_pipe_name, bent_pipe_format, getpid());
+ setenv("BENT_PIPE_NAME", bent_pipe_name, 1);
+
+ data->bentpipe = bentpipe_Create(bent_pipe_name);
+ bentpipe_Start(data->bentpipe);
+
+ longBowTestRunner_SetClipBoardData(testRunner, data->bentpipe);
+
+ unsigned int keyLength = 1024;
+ unsigned int validityDays = 30;
+ char *subjectName = "test_ccnx_Comm";
+
+ parcSecurity_Init();
+
+ bool success = parcPkcs12KeyStore_CreateFile("my_keystore", "my_keystore_password", subjectName, keyLength, validityDays);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('my_keystore', 'my_keystore_password') failed.");
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create("my_keystore", "my_keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+ parcIdentityFile_Release(&identityFile);
+
+ data->factory = ccnxPortalFactory_Create(identity);
+ parcIdentity_Release(&identity);
+
+ longBowTestCase_SetClipBoardData(testCase, data);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Performance)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ ccnxPortalFactory_Release(&data->factory);
+ bentpipe_Stop(data->bentpipe);
+ bentpipe_Destroy(&data->bentpipe);
+ parcMemory_Deallocate((void **) &data);
+ unsetenv("BENT_PIPE_NAME");
+ parcSecurity_Fini();
+
+ if (parcMemory_Outstanding() != InitialMemoryOutstanding) {
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ printf("('%s' leaks memory by %d\n",
+ longBowTestCase_GetName(testCase), parcMemory_Outstanding() - InitialMemoryOutstanding);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Performance, ccnxPortalFactory_CreatePortal)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ for (int i = 0; i < 1000; i++) {
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ ccnxPortal_Release(&portal);
+ }
+}
+
+LONGBOW_TEST_CASE(Performance, ccnxPortal_Send)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ for (int i = 0; i < 100000; i++) {
+ ccnxPortal_Flush(portal, CCNxStackTimeout_Never);
+ }
+
+ ccnxPortal_Release(&portal);
+}
+
+typedef struct parc_ewma {
+ bool initialized;
+ int64_t value;
+ double coefficient;
+} PARCEWMA;
+
+PARCEWMA *
+parcEWMA_Create(double coefficient)
+{
+ PARCEWMA *result = parcMemory_AllocateAndClear(sizeof(PARCEWMA));
+ if (result != NULL) {
+ result->initialized = false;
+ result->value = 0;
+ result->coefficient = coefficient;
+ }
+
+ return result;
+}
+
+void
+parcEWMW_Destroy(PARCEWMA **ewma)
+{
+ parcMemory_Deallocate(ewma);
+}
+
+int64_t
+parcEWMA_Update(PARCEWMA *ewma, int64_t value)
+{
+ if (ewma->initialized) {
+ ewma->value = ((value + ewma->coefficient * ewma->value - ewma->value) / ewma->coefficient);
+ } else {
+ ewma->value = value;
+ ewma->initialized = true;
+ }
+ return ewma->value;
+}
+
+int64_t
+parcEWMA_GetValue(const PARCEWMA *ewma)
+{
+ return ewma->value;
+}
+
+static uint64_t
+sendx(CCNxPortal *portalOut, uint32_t index, const CCNxName *name)
+{
+ PARCStopwatch *timer = parcStopwatch_Create();
+
+ parcStopwatch_Start(timer);
+
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ PARCBuffer *payload = parcBuffer_Allocate(sizeof(uint64_t) + sizeof(uint32_t));
+ parcBuffer_PutUint32(payload, index);
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ uint64_t theTime = tv.tv_sec * 1000000 + tv.tv_usec;
+ parcBuffer_PutUint64(payload, theTime);
+ parcBuffer_Flip(payload);
+
+ ccnxInterest_SetPayload(interest, payload);
+
+ CCNxMetaMessage *interestMessage = ccnxMetaMessage_CreateFromInterest(interest);
+
+ ccnxPortal_Send(portalOut, interestMessage, CCNxStackTimeout_Never);
+
+ parcBuffer_Release(&payload);
+
+ ccnxMetaMessage_Release(&interestMessage);
+ ccnxInterest_Release(&interest);
+
+ uint64_t result = parcStopwatch_ElapsedTimeNanos(timer);
+ parcStopwatch_Release(&timer);
+ return result;
+}
+
+static void *
+sender(void *data)
+{
+ CCNxPortal *portalOut = data;
+
+ PARCEWMA *ewma = parcEWMA_Create(0.75);
+ CCNxName *name = ccnxName_CreateFormatString("lci:/local/trace");
+
+ for (uint32_t i = 300; i != 0; i--) {
+ uint64_t elapsedTime = sendx(portalOut, i, name);
+ parcEWMA_Update(ewma, elapsedTime);
+ }
+ uint64_t elapsedTime = sendx(portalOut, 0, name);
+ parcEWMA_Update(ewma, elapsedTime);
+
+ printf("sender %9" PRId64 " us/message\n", parcEWMA_GetValue(ewma));
+
+ parcEWMW_Destroy(&ewma);
+ ccnxName_Release(&name);
+ return 0;
+}
+
+static void *
+receiver(void *data)
+{
+ CCNxPortal *portalIn = data;
+
+ uint32_t index;
+ PARCEWMA *ewma = parcEWMA_Create(0.75);
+ PARCEWMA *roundTrip = parcEWMA_Create(0.75);
+
+ PARCStopwatch *timer = parcStopwatch_Create();
+ do {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ uint64_t theTime = tv.tv_sec * 1000000 + tv.tv_usec;
+
+ parcStopwatch_Start(timer);
+ CCNxMetaMessage *message = ccnxPortal_Receive(portalIn, CCNxStackTimeout_Never);
+
+ PARCBuffer *payload = ccnxInterest_GetPayload(ccnxMetaMessage_GetInterest(message));
+
+ index = parcBuffer_GetUint32(payload);
+
+ parcEWMA_Update(roundTrip, theTime - parcBuffer_GetUint64(payload));
+
+ parcEWMA_Update(ewma, parcStopwatch_ElapsedTimeNanos(timer));
+
+ ccnxMetaMessage_Release(&message);
+ } while (index != 0);
+
+ printf("receiver %9" PRId64 " us/message %9" PRId64 " us\n", parcEWMA_GetValue(ewma), parcEWMA_GetValue(roundTrip));
+
+ parcStopwatch_Release(&timer);
+ parcEWMW_Destroy(&roundTrip);
+ parcEWMW_Destroy(&ewma);
+
+ return 0;
+}
+
+LONGBOW_TEST_CASE(Performance, ccnxPortal_SendReceive)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxPortal *portalSend = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+ CCNxPortal *portalReceive = ccnxPortalFactory_CreatePortal(data->factory, TEST_STACK);
+
+ pthread_t thread_receiver1;
+ pthread_t thread_sender;
+ pthread_create(&thread_receiver1, NULL, receiver, portalReceive);
+ pthread_create(&thread_sender, NULL, sender, portalSend);
+
+ pthread_join(thread_receiver1, NULL);
+
+ ccnxPortal_Flush(portalSend, CCNxStackTimeout_Never);
+ ccnxPortal_Flush(portalReceive, CCNxStackTimeout_Never);
+ ccnxPortal_Release(&portalSend);
+ ccnxPortal_Release(&portalReceive);
+ sleep(2);
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_ccnx_Portal);
+ int exitStatus = longBowMain(argc, argv, testRunner);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAPI.c b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAPI.c
new file mode 100755
index 00000000..736e6982
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAPI.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include "../ccnx_Portal.c"
+
+#include <LongBow/unit-test.h>
+#include <LongBow/debugging.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <ccnx/api/ccnx_Portal/ccnx_PortalAPI.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <parc/security/parc_IdentityFile.h>
+
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_Pkcs12KeyStore.h>
+
+LONGBOW_TEST_RUNNER(test_ccnx_PortalAPI /*, .requires="FeatureLongBowSubProcess"*/)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+LONGBOW_TEST_RUNNER_SETUP(test_ccnx_PortalAPI)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_RUNNER_TEARDOWN(test_ccnx_PortalAPI)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalAPI_CreateRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalAPI_SendReceive);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalAPI_GetFileId);
+}
+
+static size_t InitialMemoryOutstanding = 0;
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ InitialMemoryOutstanding = parcMemory_Outstanding();
+
+ unsigned int keyLength = 1024;
+ unsigned int validityDays = 30;
+ char *subjectName = "test_ccnx_Comm";
+
+ parcSecurity_Init();
+
+ bool success = parcPkcs12KeyStore_CreateFile("my_keystore", "my_keystore_password", subjectName, keyLength, validityDays);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('my_keystore', 'my_keystore_password') failed.");
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create("my_keystore", "my_keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ longBowTestCase_SetClipBoardData(testCase, factory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ CCNxPortalFactory *factory = longBowTestCase_GetClipBoardData(testCase);
+ ccnxPortalFactory_Release(&factory);
+
+ parcSecurity_Fini();
+
+ if (parcMemory_Outstanding() != InitialMemoryOutstanding) {
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ printf("('%s' leaks memory by %zd\n",
+ longBowTestCase_GetName(testCase), parcMemory_Outstanding() - InitialMemoryOutstanding);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalAPI_CreateRelease)
+{
+ CCNxPortalFactory *factory = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(factory, ccnxPortalAPI_LoopBack);
+ assertNotNull(portal, "Expected a portal");
+
+ ccnxPortal_Release(&portal);
+ assertNull(portal, "Expected a null portal");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalAPI_SendReceive)
+{
+ CCNxPortalFactory *factory = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(factory, ccnxPortalAPI_LoopBack);
+
+ // Send Hello
+ CCNxName *name1 = ccnxName_CreateFromCString("lci:/Hello/World");
+ CCNxInterest *sentInterest1 = ccnxInterest_CreateSimple(name1);
+ ccnxName_Release(&name1);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(sentInterest1);
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+
+ // Send Goodbye. We want to make sure these arrive in that order.
+ CCNxName *name2 = ccnxName_CreateFromCString("lci:/Goodbye/World");
+ CCNxInterest *sentInterest2 = ccnxInterest_CreateSimple(name2);
+ ccnxName_Release(&name2);
+
+ message = ccnxMetaMessage_CreateFromInterest(sentInterest2);
+ ccnxPortal_Send(portal, message, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+
+ // Now verify that they arrive in Hello, Goodbye order.
+
+ CCNxMetaMessage *receivedMessage = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+
+ CCNxInterest *receivedInterest1 = ccnxMetaMessage_GetInterest(receivedMessage);
+ assertTrue(ccnxInterest_Equals(sentInterest1, receivedInterest1), "Expected the Hello interest");
+ ccnxMetaMessage_Release(&receivedMessage);
+ ccnxInterest_Release(&sentInterest1);
+
+ receivedMessage = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ CCNxInterest *receivedInterest2 = ccnxMetaMessage_GetInterest(receivedMessage);
+ assertTrue(ccnxInterest_Equals(sentInterest2, receivedInterest2), "Expected the Goodbye interest");
+ ccnxMetaMessage_Release(&receivedMessage);
+ ccnxInterest_Release(&sentInterest2);
+
+ ccnxPortal_Release(&portal);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalAPI_GetFileId)
+{
+ CCNxPortalFactory *factory = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortal *portal = ccnxPortalFactory_CreatePortal(factory, ccnxPortalAPI_LoopBack);
+
+ int fileId = ccnxPortal_GetFileId(portal);
+
+ assertTrue(fileId != -1, "Expected file-id to not be -1");
+
+ ccnxPortal_Release(&portal);
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_ccnx_PortalAPI);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAnchor.c b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAnchor.c
new file mode 100644
index 00000000..b2acbf51
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalAnchor.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include "../ccnx_PortalAnchor.c"
+
+#include <LongBow/testing.h>
+#include <LongBow/debugging.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_DisplayIndented.h>
+
+#include <parc/testing/parc_MemoryTesting.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(ccnx_PortalAnchor)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(CreateAcquireRelease);
+ LONGBOW_RUN_TEST_FIXTURE(Object);
+ LONGBOW_RUN_TEST_FIXTURE(Specialization);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_PortalAnchor)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_PortalAnchor)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(CreateAcquireRelease)
+{
+ LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, CreateRelease);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(CreateAcquireRelease)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(CreateAcquireRelease)
+{
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+ assertNotNull(instance, "Expected non-null result from ccnxPortalAnchor_Create();");
+
+ parcObjectTesting_AssertAcquireReleaseContract(ccnxPortalAnchor_Acquire, instance);
+
+ ccnxPortalAnchor_Release(&instance);
+ ccnxName_Release(&name);
+ assertNull(instance, "Expected null result from ccnxPortalAnchor_Release();");
+}
+
+LONGBOW_TEST_FIXTURE(Object)
+{
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_Compare);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_Copy);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_Display);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_Equals);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_HashCode);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_IsValid);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_ToJSON);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_ToString);
+ LONGBOW_RUN_TEST_CASE(Object, ccnxPortalAnchor_SerializeDeserialize);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Object)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Object)
+{
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s mismanaged memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_Compare)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_Copy)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+
+ CCNxPortalAnchor *copy = ccnxPortalAnchor_Copy(instance);
+ assertTrue(ccnxPortalAnchor_Equals(instance, copy), "Expected the copy to be equal to the original");
+
+ ccnxPortalAnchor_Release(&instance);
+ ccnxPortalAnchor_Release(&copy);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_Display)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+ ccnxPortalAnchor_Display(instance, 0);
+ ccnxPortalAnchor_Release(&instance);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_Equals)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *x = ccnxPortalAnchor_Create(name, expireTime);
+ CCNxPortalAnchor *y = ccnxPortalAnchor_Create(name, expireTime);
+ CCNxPortalAnchor *z = ccnxPortalAnchor_Create(name, expireTime);
+
+ parcObjectTesting_AssertEquals(x, y, z, NULL);
+
+ ccnxPortalAnchor_Release(&x);
+ ccnxPortalAnchor_Release(&y);
+ ccnxPortalAnchor_Release(&z);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_HashCode)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *x = ccnxPortalAnchor_Create(name, expireTime);
+ CCNxPortalAnchor *y = ccnxPortalAnchor_Create(name, expireTime);
+
+ parcObjectTesting_AssertHashCode(x, y);
+
+ ccnxPortalAnchor_Release(&x);
+ ccnxPortalAnchor_Release(&y);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_IsValid)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+ assertTrue(ccnxPortalAnchor_IsValid(instance), "Expected ccnxPortalAnchor_Create to result in a valid instance.");
+
+ ccnxPortalAnchor_Release(&instance);
+ ccnxName_Release(&name);
+
+ assertFalse(ccnxPortalAnchor_IsValid(instance), "Expected ccnxPortalAnchor_Release to result in an invalid instance.");
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_ToJSON)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+
+ PARCJSON *json = ccnxPortalAnchor_ToJSON(instance);
+
+ parcJSON_Release(&json);
+
+ ccnxPortalAnchor_Release(&instance);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_ToString)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+
+ char *string = ccnxPortalAnchor_ToString(instance);
+
+ assertNotNull(string, "Expected non-NULL result from ccnxPortalAnchor_ToString");
+
+ parcMemory_Deallocate((void **) &string);
+ ccnxPortalAnchor_Release(&instance);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Object, ccnxPortalAnchor_SerializeDeserialize)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *instance = ccnxPortalAnchor_Create(name, expireTime);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ ccnxPortalAnchor_Serialize(instance, composer);
+ PARCBuffer *buffer = parcBufferComposer_ProduceBuffer(composer);
+ CCNxPortalAnchor *copy = ccnxPortalAnchor_Deserialize(buffer);
+
+ assertTrue(ccnxPortalAnchor_Equals(instance, copy), "Expected deserialized form to be equal to the original");
+ ccnxPortalAnchor_Release(&copy);
+ parcBuffer_Release(&buffer);
+ parcBufferComposer_Release(&composer);
+ ccnxPortalAnchor_Release(&instance);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_FIXTURE(Specialization)
+{
+ LONGBOW_RUN_TEST_CASE(Specialization, ccnxPortalAnchor_GetNamePrefix);
+
+ LONGBOW_RUN_TEST_CASE(Specialization, ccnxPortalAnchor_GetExpireTime);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Specialization)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Specialization)
+{
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s mismanaged memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Specialization, ccnxPortalAnchor_GetNamePrefix)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *anchor = ccnxPortalAnchor_Create(name, expireTime);
+
+ CCNxName *actual = ccnxPortalAnchor_GetNamePrefix(anchor);
+
+ assertTrue(ccnxName_Equals(name, actual), "Expected name to be equal.");
+ ccnxPortalAnchor_Release(&anchor);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Specialization, ccnxPortalAnchor_GetExpireTime)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ time_t expireTime = 123;
+ CCNxPortalAnchor *anchor = ccnxPortalAnchor_Create(name, expireTime);
+
+ time_t actual = ccnxPortalAnchor_GetExpireTime(anchor);
+
+ assertTrue(expireTime == actual, "Expected expire-time to be equal.");
+ ccnxPortalAnchor_Release(&anchor);
+ ccnxName_Release(&name);
+}
+
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_PortalAnchor);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalFactory.c b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalFactory.c
new file mode 100644
index 00000000..8c98705f
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalFactory.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @header <#Headline Name#>
+ * @abstract <#Abstract#>
+ * @discussion
+ * <#Discussion#>
+ *
+ */
+#include "../ccnx_PortalFactory.c"
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <LongBow/unit-test.h>
+#include <LongBow/debugging.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_IdentityFile.h>
+
+#include <ccnx/transport/test_tools/bent_pipe.h>
+
+#include <parc/security/parc_Pkcs12KeyStore.h>
+
+LONGBOW_TEST_RUNNER(test_ccnx_PortalFactory /*, .requires="FeatureLongBowSubProcess"*/)
+{
+ LONGBOW_RUN_TEST_FIXTURE(CreateAcquireRelease);
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Errors);
+}
+
+LONGBOW_TEST_RUNNER_SETUP(test_ccnx_PortalFactory)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_RUNNER_TEARDOWN(test_ccnx_PortalFactory)
+{
+// LongBowSubProcess *metis = longBowTestRunner_GetClipBoardData(testRunner);
+// longBowSubProcess_Display(0, metis);
+// longBowSubProcess_Destroy(&metis);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(CreateAcquireRelease)
+{
+ LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, ccnxPortalFactory_Create);
+ LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, ccnxPortalFactory_AcquireRelease);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(CreateAcquireRelease)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(CreateAcquireRelease)
+{
+ unlink("ccnxPortalFactory_keystore");
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(CreateAcquireRelease, ccnxPortalFactory_Create)
+{
+ const char *keystoreName = "ccnxPortalFactory_keystore";
+
+ parcSecurity_Init();
+
+ bool success = parcPkcs12KeyStore_CreateFile(keystoreName, "keystore_password", "consumer", 1024, 30);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('%s', 'keystore_password') failed.", keystoreName);
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, "keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ ccnxPortalFactory_Release(&factory);
+
+ parcSecurity_Fini();
+}
+
+LONGBOW_TEST_CASE(CreateAcquireRelease, ccnxPortalFactory_AcquireRelease)
+{
+ const char *keystoreName = "ccnxPortalFactory_keystore";
+
+ parcSecurity_Init();
+
+ bool success = parcPkcs12KeyStore_CreateFile(keystoreName, "keystore_password", "consumer", 1024, 30);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('%s', 'keystore_password') failed.", keystoreName);
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, "keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ CCNxPortalFactory *reference = ccnxPortalFactory_Acquire(factory);
+ assertTrue(factory == reference, "Expected Acquire to return its argument.");
+
+ ccnxPortalFactory_Release(&factory);
+ ccnxPortalFactory_Release(&reference);
+
+ parcSecurity_Fini();
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalFactory_GetIdentity);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalFactory_GetKeyId);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ unlink("ccnxPortalFactory_keystore");
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalFactory_GetIdentity)
+{
+ const char *keystoreName = "ccnxPortalFactory_keystore";
+
+ parcSecurity_Init();
+ bool success = parcPkcs12KeyStore_CreateFile(keystoreName, "keystore_password", "consumer", 1024, 30);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('%s', 'keystore_password') failed.", keystoreName);
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, "keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+
+ const PARCIdentity *actual = ccnxPortalFactory_GetIdentity(factory);
+
+ assertTrue(identity == actual, "Expected the result to be the same as provided to the constructor");
+
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ ccnxPortalFactory_Release(&factory);
+ parcSecurity_Fini();
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalFactory_GetKeyId)
+{
+ const char *keystoreName = "ccnxPortalFactory_keystore";
+
+ parcSecurity_Init();
+ bool success = parcPkcs12KeyStore_CreateFile(keystoreName, "keystore_password", "consumer", 1024, 30);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('%s', 'keystore_password') failed.", keystoreName);
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, "keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+
+ const PARCKeyId *actual = ccnxPortalFactory_GetKeyId(factory);
+
+ PARCSigner *signer = parcIdentity_CreateSigner(identity);
+ PARCKeyId *expected = parcSigner_CreateKeyId(signer);
+ parcSigner_Release(&signer);
+
+ assertTrue(parcKeyId_Equals(expected, actual), "KeyIds not equal");
+
+ parcKeyId_Release(&expected);
+
+ ccnxPortalFactory_Release(&factory);
+
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ parcSecurity_Fini();
+}
+
+LONGBOW_TEST_FIXTURE(Errors)
+{
+ LONGBOW_RUN_TEST_CASE(Errors, ccnxPortalFactory_Create_NULL_Identity);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Errors)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Errors)
+{
+ unlink("ccnxPortalFactory_keystore");
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE_EXPECTS(Errors, ccnxPortalFactory_Create_NULL_Identity, .event = &LongBowTrapInvalidValue)
+{
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(NULL);
+
+ ccnxPortalFactory_Release(&factory);
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_ccnx_PortalFactory);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalRTA.c b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalRTA.c
new file mode 100755
index 00000000..901b1b7e
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalRTA.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Runner.
+#include "../ccnx_PortalRTA.c"
+
+#include <LongBow/unit-test.h>
+
+LONGBOW_TEST_RUNNER(ccnx_PortalRTA)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified here, but every test must be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Static);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_PortalRTA)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_PortalRTA)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalRTA_Chunked);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalRTA_LoopBack);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalRTA_Message);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalRTA_Chunked)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalRTA_LoopBack)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalRTA_Message)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_FIXTURE(Static)
+{
+ LONGBOW_RUN_TEST_CASE(Static, _autowrap_destroy__CCNxPortalRTAContext);
+ LONGBOW_RUN_TEST_CASE(Static, _blockingPortal);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalProtocol_RTALoopback);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalProtocol_RTAMetis);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTAContext_Create);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTAContext_Destroy);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTAContext_Release);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_CreatePortal);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_GetAttributes);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_GetFileId);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_Ignore);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_IsConnected);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_Listen);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_Receive);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_Send);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_SetAttributes);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_Start);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxPortalRTA_Stop);
+ LONGBOW_RUN_TEST_CASE(Static, _createTransportConfig);
+ LONGBOW_RUN_TEST_CASE(Static, _nonBlockingPortal);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Static, _autowrap_destroy__CCNxPortalRTAContext)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _blockingPortal)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalProtocol_RTALoopback)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalProtocol_RTAMetis)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTAContext_Create)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTAContext_Destroy)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTAContext_Release)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_CreatePortal)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_GetAttributes)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_GetFileId)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_Ignore)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_IsConnected)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_Listen)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_Receive)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_Send)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_SetAttributes)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_Start)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxPortalRTA_Stop)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _createTransportConfig)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Static, _nonBlockingPortal)
+{
+ testUnimplemented("");
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_PortalRTA);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalStack.c b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalStack.c
new file mode 100755
index 00000000..ebba0dea
--- /dev/null
+++ b/libccnx-portal/ccnx/api/ccnx_Portal/test/test_ccnx_PortalStack.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** *
+ */
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_PortalStack.c"
+
+#include <LongBow/testing.h>
+#include <LongBow/debugging.h>
+
+#include <ccnx/api/ccnx_Portal/ccnx_PortalFactory.h>
+
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_Pkcs12KeyStore.h>
+
+#include <parc/testing/parc_ObjectTesting.h>
+#include <parc/testing/parc_MemoryTesting.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_IdentityFile.h>
+
+LONGBOW_TEST_RUNNER(test_ccnx_PortalStack)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(CreateRelease);
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(test_ccnx_PortalStack)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(test_ccnx_PortalStack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+
+LONGBOW_TEST_FIXTURE(CreateRelease)
+{
+ LONGBOW_RUN_TEST_CASE(CreateRelease, CreateRelease);
+}
+
+static uint32_t setupFixtureAllocations;
+
+LONGBOW_TEST_FIXTURE_SETUP(CreateRelease)
+{
+ setupFixtureAllocations = parcMemory_Outstanding();
+ parcSecurity_Init();
+
+ const char *keystoreName = "test_ccnx_PortalImplementation_keystore";
+
+ bool success = parcPkcs12KeyStore_CreateFile(keystoreName, "keystore_password", "consumer", 1024, 30);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('%s', 'keystore_password') failed.", keystoreName);
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, "keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ longBowTestCase_SetClipBoardData(testCase, factory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(CreateRelease)
+{
+ CCNxPortalFactory *factory = (CCNxPortalFactory *) longBowTestCase_GetClipBoardData(testCase);
+
+ ccnxPortalFactory_Release(&factory);
+
+ parcSecurity_Fini();
+ if (!parcMemoryTesting_ExpectedOutstanding(setupFixtureAllocations, "%s", longBowTestCase_GetName(testCase))) {
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+static void
+_mockStart(void *privateData)
+{
+}
+
+static void
+_mockStop(void *privateData)
+{
+}
+
+static CCNxMetaMessage *
+_mockRead(void *privateData, const uint64_t *microSeconds)
+{
+ CCNxName *name = ccnxName_Create();
+ PARCBuffer *payload = parcBuffer_Allocate(10);
+ CCNxContentObject *object = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+ ccnxName_Release(&name);
+
+ parcBuffer_Release(&payload);
+
+ CCNxMetaMessage *result = ccnxMetaMessage_CreateFromContentObject(object);
+ ccnxContentObject_Release(&object);
+ return result;
+}
+
+static bool
+_mockSend(void *privateData, const CCNxMetaMessage *message, const uint64_t *microSeconds)
+{
+ return true;
+}
+
+static bool
+_mockListen(void *privateData, const CCNxName *name, const uint64_t *microSeconds)
+{
+ return true;
+}
+
+static bool
+_mockIgnore(void *privateData, const CCNxName *name, const uint64_t *microSeconds)
+{
+ return true;
+}
+
+static int
+_mockGetFileId(void *privateData)
+{
+ return 2;
+}
+
+static CCNxPortalAttributes *
+_mockGetAttributes(void *privateData)
+{
+ return NULL;
+}
+
+static bool
+_mockSetAttributes(void *privateData, const CCNxPortalAttributes *attributes)
+{
+ return true;
+}
+
+LONGBOW_TEST_CASE(CreateRelease, CreateRelease)
+{
+ CCNxPortalFactory *factory = (CCNxPortalFactory *) longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxPortalAttributes *attributes = NULL;
+ CCNxPortalStack *actual =
+ ccnxPortalStack_Create(factory,
+ attributes,
+ _mockStart,
+ _mockStop,
+ _mockRead,
+ _mockSend,
+ _mockListen,
+ _mockIgnore,
+ _mockGetFileId,
+ _mockSetAttributes,
+ _mockGetAttributes,
+ parcMemory_Allocate(10),
+ parcMemory_DeallocateImpl);
+
+ parcObjectTesting_AssertAcquire(actual);
+
+ ccnxPortalStack_Release(&actual);
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_GetFileId);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_GetKeyId);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_GetAttributes);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_SetAttributes);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_Listen);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_Ignore);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_Send);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_Receive);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_Start);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_Stop);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxPortalStack_GetError);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ setupFixtureAllocations = parcMemory_Outstanding();
+ parcSecurity_Init();
+
+ const char *keystoreName = "test_ccnx_PortalImplementation_keystore";
+
+ bool success = parcPkcs12KeyStore_CreateFile(keystoreName, "keystore_password", "consumer", 1024, 30);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile('%s', 'keystore_password') failed.", keystoreName);
+
+ PARCIdentityFile *identityFile = parcIdentityFile_Create(keystoreName, "keystore_password");
+ PARCIdentity *identity = parcIdentity_Create(identityFile, PARCIdentityFileAsPARCIdentity);
+
+ CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);
+ parcIdentityFile_Release(&identityFile);
+ parcIdentity_Release(&identity);
+
+ const CCNxPortalAttributes *attributes = &ccnxPortalAttributes_NonBlocking;
+
+ CCNxPortalStack *stack = ccnxPortalStack_Create(factory,
+ attributes,
+ _mockStart,
+ _mockStop,
+ _mockRead,
+ _mockSend,
+ _mockListen,
+ _mockIgnore,
+ _mockGetFileId,
+ _mockSetAttributes,
+ _mockGetAttributes,
+ parcMemory_Allocate(10),
+ parcMemory_DeallocateImpl);
+ ccnxPortalFactory_Release(&factory);
+ longBowTestCase_SetClipBoardData(testCase, stack);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ ccnxPortalStack_Release(&stack);
+
+ parcSecurity_Fini();
+ if (!parcMemoryTesting_ExpectedOutstanding(setupFixtureAllocations, "%s", longBowTestCase_GetName(testCase))) {
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_GetError)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+ extern int errno;
+ errno = 0;
+ int actual = ccnxPortalStack_GetErrorCode(stack);
+ assertTrue(actual == 0, "Expected ccnxPortalStack_GetErrorCode to return 0, actual %d", actual);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_Start)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ bool actual = ccnxPortalStack_Start(stack);
+ assertTrue(actual, "Expected ccnxPortalStack_Start to return true");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_Stop)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+ bool actual = ccnxPortalStack_Stop(stack);
+
+ assertTrue(actual, "Expected ccnxPortalStack_Stop to return true");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_Receive)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxMetaMessage *result = ccnxPortalStack_Receive(stack, CCNxStackTimeout_Never);
+ assertTrue(result, "Expected ccnxPortalStack_Listen to return true.");
+ ccnxMetaMessage_Release(&result);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_Send)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxName *name = ccnxName_Create();
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+ ccnxInterest_Release(&interest);
+
+ bool result = ccnxPortalStack_Send(stack, message, CCNxStackTimeout_Never);
+ ccnxMetaMessage_Release(&message);
+ assertTrue(result, "Expected ccnxPortalStack_Ignore to return true.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_Listen)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxName *name = ccnxName_Create();
+ bool result = ccnxPortalStack_Listen(stack, name, CCNxStackTimeout_Never);
+ ccnxName_Release(&name);
+ assertTrue(result, "Expected ccnxPortalStack_Listen to return true.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_Ignore)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxName *name = ccnxName_Create();
+ bool result = ccnxPortalStack_Ignore(stack, name, CCNxStackTimeout_Never);
+ ccnxName_Release(&name);
+ assertTrue(result, "Expected ccnxPortalStack_Ignore to return true.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_SetAttributes)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ const CCNxPortalAttributes *attributes = &ccnxPortalAttributes_NonBlocking;
+ bool result = ccnxPortalStack_SetAttributes(stack, attributes);
+ assertTrue(result, "Expected ccnxPortalStack_SetAttributes to return true.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_GetAttributes)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ ccnxPortalStack_GetAttributes(stack);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_GetFileId)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ int fileId = ccnxPortalStack_GetFileId(stack);
+ assertFalse(fileId == -1, "Expected ccnxPortalStack_GetFileId to not return -1.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxPortalStack_GetKeyId)
+{
+ CCNxPortalStack *stack = (CCNxPortalStack *) longBowTestCase_GetClipBoardData(testCase);
+
+ const PARCKeyId *keyId = ccnxPortalStack_GetKeyId(stack);
+ assertNotNull(keyId, "Expected non-NULL result from ccnxPortalStack_GetKeyId");
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_ccnx_PortalStack);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}