diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-23 17:01:02 +0100 |
---|---|---|
committer | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-23 17:21:02 +0100 |
commit | ec688b4723a041044226358bcd4dd6e2da39da49 (patch) | |
tree | 3a244c48d1eb9e4d90f9050fd1a61ae5c0327526 /libparc/parc/concurrent/test | |
parent | 9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff) |
Initial commit: cframework. Longbow and Libparc
Change-Id: I90378dbd30da6033b20fb1f829b3b822cf366c59
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'libparc/parc/concurrent/test')
17 files changed, 4320 insertions, 0 deletions
diff --git a/libparc/parc/concurrent/test/.gitignore b/libparc/parc/concurrent/test/.gitignore new file mode 100644 index 00000000..2c9fe4f5 --- /dev/null +++ b/libparc/parc/concurrent/test/.gitignore @@ -0,0 +1,10 @@ +test_parc_Notifier +test_parc_RingBuffer_1x1 +test_parc_RingBuffer_NxM +test_parc_AtomicUint64 +test_parc_Barrier +test_parc_AtomicUint16 +test_parc_AtomicUint32 +test_parc_AtomicUint8 +test_parc_Synchronizer +test_parc_Lock diff --git a/libparc/parc/concurrent/test/CMakeLists.txt b/libparc/parc/concurrent/test/CMakeLists.txt new file mode 100644 index 00000000..092d0202 --- /dev/null +++ b/libparc/parc/concurrent/test/CMakeLists.txt @@ -0,0 +1,25 @@ +set(TestsExpectedToPass + test_parc_AtomicUint16 + test_parc_AtomicUint32 + test_parc_AtomicUint64 + test_parc_AtomicUint8 + test_parc_FutureTask + test_parc_Lock + test_parc_Notifier + test_parc_RingBuffer_1x1 + test_parc_RingBuffer_NxM + test_parc_ScheduledTask + test_parc_ScheduledThreadPool + test_parc_Synchronizer + test_parc_Thread + test_parc_ThreadPool + test_parc_Timer + ) + +# Enable gcov output for the tests +add_definitions(--coverage) +set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage") + +foreach(test ${TestsExpectedToPass}) + AddTest(${test}) +endforeach() diff --git a/libparc/parc/concurrent/test/test_parc_AtomicUint16.c b/libparc/parc/concurrent/test/test_parc_AtomicUint16.c new file mode 100644 index 00000000..ed97cc95 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_AtomicUint16.c @@ -0,0 +1,361 @@ +/* + * 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 "../parc_AtomicUint16.c" + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <inttypes.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/testing/parc_MemoryTesting.h> +#include <parc/testing/parc_ObjectTesting.h> + +LONGBOW_TEST_RUNNER(parc_AtomicUint16) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Macros); + LONGBOW_RUN_TEST_FIXTURE(Performance); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_AtomicUint16) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_AtomicUint16) +{ + 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) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + assertNotNull(instance, "Expeced non-null result from parcAtomicUint16_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcAtomicUint16_Acquire, instance); + + parcAtomicUint16_Release(&instance); + assertNull(instance, "Expected null result from parcAtomicUint16_Release();"); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_Compare); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_Copy); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_Equals); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_HashCode); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_IsValid); + + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_AddImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint16_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_Compare) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + PARCAtomicUint16 *high = parcAtomicUint16_Create(8); + PARCAtomicUint16 *low = parcAtomicUint16_Create(6); + PARCAtomicUint16 *equal = parcAtomicUint16_Create(7); + + int actual = parcAtomicUint16_Compare(instance, high); + assertTrue(actual < 0, "Expected < 0"); + actual = parcAtomicUint16_Compare(instance, low); + assertTrue(actual > 0, "Expected > 0"); + actual = parcAtomicUint16_Compare(instance, equal); + assertTrue(actual == 0, "Expected == 0"); + + parcAtomicUint16_Release(&instance); + parcAtomicUint16_Release(&high); + parcAtomicUint16_Release(&low); + parcAtomicUint16_Release(&equal); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_Copy) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + PARCAtomicUint16 *copy = parcAtomicUint16_Copy(instance); + + assertTrue(parcAtomicUint16_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcAtomicUint16_Release(&instance); + parcAtomicUint16_Release(©); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_Equals) +{ + PARCAtomicUint16 *x = parcAtomicUint16_Create(7); + PARCAtomicUint16 *y = parcAtomicUint16_Create(7); + PARCAtomicUint16 *z = parcAtomicUint16_Create(7); + PARCAtomicUint16 *u1 = parcAtomicUint16_Create(6); + + parcObjectTesting_AssertEquals(x, y, z, u1, NULL); + + parcAtomicUint16_Release(&x); + parcAtomicUint16_Release(&y); + parcAtomicUint16_Release(&z); + parcAtomicUint16_Release(&u1); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_HashCode) +{ + PARCAtomicUint16 *x = parcAtomicUint16_Create(7); + parcAtomicUint16_HashCode(x); + parcAtomicUint16_Release(&x); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_IsValid) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + assertTrue(parcAtomicUint16_IsValid(instance), "Expected parcAtomicUint16_Create to result in a valid instance."); + + parcAtomicUint16_Release(&instance); + assertFalse(parcAtomicUint16_IsValid(instance), "Expected parcAtomicUint16_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_SubtractImpl) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + + parcAtomicUint16_SubtractImpl(instance, 1); + + uint16_t actual = parcAtomicUint16_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu16, actual); + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_AddImpl) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + + parcAtomicUint16_AddImpl(instance, 1); + + uint16_t actual = parcAtomicUint16_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu16, actual); + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint16_CompareAndSwapImpl) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + + bool actual = parcAtomicUint16_CompareAndSwapImpl(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint16_CompareAndSwapImpl to return true"); + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Macros) +{ + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint16_Subtract); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint16_Add); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint16_CompareAndSwap); +} + +LONGBOW_TEST_FIXTURE_SETUP(Macros) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Macros) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint16_Subtract) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + + parcAtomicUint16_Subtract(instance, 1); + + uint16_t actual = parcAtomicUint16_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu16, actual); + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint16_Add) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + + parcAtomicUint16_Add(instance, 1); + + uint16_t actual = parcAtomicUint16_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu16, actual); + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint16_CompareAndSwap) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(7); + + bool actual = parcAtomicUint16_CompareAndSwap(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint16_CompareAndSwap to return true"); + parcAtomicUint16_Release(&instance); +} + + +LONGBOW_TEST_FIXTURE_OPTIONS(Performance, .enabled = false) +{ + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint16_Subtract_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint16_Add_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint16_CompareAndSwap_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint16_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint16_AddImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint16_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Performance) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Performance) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint16_Subtract_MACRO) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(65535); + + while (parcAtomicUint16_Subtract(instance, 1) > 0) { + ; + } + + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint16_Add_MACRO) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(1); + + while (parcAtomicUint16_Add(instance, 1) < 65535) { + ; + } + + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint16_CompareAndSwap_MACRO) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(0); + + for (uint16_t i = 0; i < 65535; i++) { + bool actual = parcAtomicUint16_CompareAndSwap(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint16_CompareAndSwap to return true"); + } + + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint16_SubtractImpl) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(65535); + + while (parcAtomicUint16_SubtractImpl(instance, 1) > 0) { + ; + } + + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint16_AddImpl) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(1); + + while (parcAtomicUint16_AddImpl(instance, 1) < 65535) { + ; + } + + parcAtomicUint16_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint16_CompareAndSwapImpl) +{ + PARCAtomicUint16 *instance = parcAtomicUint16_Create(0); + + for (uint16_t i = 0; i < 65535; i++) { + bool actual = parcAtomicUint16_CompareAndSwapImpl(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint16_CompareAndSwapImpl to return true"); + } + + parcAtomicUint16_Release(&instance); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_AtomicUint16); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_AtomicUint32.c b/libparc/parc/concurrent/test/test_parc_AtomicUint32.c new file mode 100644 index 00000000..1649cf1c --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_AtomicUint32.c @@ -0,0 +1,361 @@ +/* + * 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 "../parc_AtomicUint64.c" + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <inttypes.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/testing/parc_MemoryTesting.h> +#include <parc/testing/parc_ObjectTesting.h> + +LONGBOW_TEST_RUNNER(parc_AtomicUint64) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Macros); + LONGBOW_RUN_TEST_FIXTURE(Performance); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_AtomicUint64) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_AtomicUint64) +{ + 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) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + assertNotNull(instance, "Expeced non-null result from parcAtomicUint64_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcAtomicUint64_Acquire, instance); + + parcAtomicUint64_Release(&instance); + assertNull(instance, "Expected null result from parcAtomicUint64_Release();"); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_Compare); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_Copy); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_Equals); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_HashCode); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_IsValid); + + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_AddImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_Compare) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + PARCAtomicUint64 *high = parcAtomicUint64_Create(8); + PARCAtomicUint64 *low = parcAtomicUint64_Create(6); + PARCAtomicUint64 *equal = parcAtomicUint64_Create(7); + + int actual = parcAtomicUint64_Compare(instance, high); + assertTrue(actual < 0, "Expected < 0"); + actual = parcAtomicUint64_Compare(instance, low); + assertTrue(actual > 0, "Expected > 0"); + actual = parcAtomicUint64_Compare(instance, equal); + assertTrue(actual == 0, "Expected == 0"); + + parcAtomicUint64_Release(&instance); + parcAtomicUint64_Release(&high); + parcAtomicUint64_Release(&low); + parcAtomicUint64_Release(&equal); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_Copy) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + PARCAtomicUint64 *copy = parcAtomicUint64_Copy(instance); + + assertTrue(parcAtomicUint64_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcAtomicUint64_Release(&instance); + parcAtomicUint64_Release(©); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_Equals) +{ + PARCAtomicUint64 *x = parcAtomicUint64_Create(7); + PARCAtomicUint64 *y = parcAtomicUint64_Create(7); + PARCAtomicUint64 *z = parcAtomicUint64_Create(7); + PARCAtomicUint64 *u1 = parcAtomicUint64_Create(6); + + parcObjectTesting_AssertEquals(x, y, z, u1, NULL); + + parcAtomicUint64_Release(&x); + parcAtomicUint64_Release(&y); + parcAtomicUint64_Release(&z); + parcAtomicUint64_Release(&u1); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_HashCode) +{ + PARCAtomicUint64 *x = parcAtomicUint64_Create(7); + parcAtomicUint64_HashCode(x); + parcAtomicUint64_Release(&x); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_IsValid) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + assertTrue(parcAtomicUint64_IsValid(instance), "Expected parcAtomicUint64_Create to result in a valid instance."); + + parcAtomicUint64_Release(&instance); + assertFalse(parcAtomicUint64_IsValid(instance), "Expected parcAtomicUint64_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_SubtractImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_SubtractImpl(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_AddImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_AddImpl(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_CompareAndSwapImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + bool actual = parcAtomicUint64_CompareAndSwapImpl(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwapImpl to return true"); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Macros) +{ + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint64_Subtract); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint64_Add); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint64_CompareAndSwap); +} + +LONGBOW_TEST_FIXTURE_SETUP(Macros) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Macros) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint64_Subtract) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_Subtract(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint64_Add) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_Add(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint64_CompareAndSwap) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + bool actual = parcAtomicUint64_CompareAndSwap(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwap to return true"); + parcAtomicUint64_Release(&instance); +} + + +LONGBOW_TEST_FIXTURE_OPTIONS(Performance, .enabled = false) +{ + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_Subtract_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_Add_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwap_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_AddImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Performance) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Performance) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_Subtract_MACRO) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(100000000); + + while (parcAtomicUint64_Subtract(instance, 1) > 0) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_Add_MACRO) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(1); + + while (parcAtomicUint64_Add(instance, 1) < 100000000) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwap_MACRO) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(0); + + for (uint64_t i = 0; i < 100000000; i++) { + bool actual = parcAtomicUint64_CompareAndSwap(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwap to return true"); + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_SubtractImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(100000000); + + while (parcAtomicUint64_SubtractImpl(instance, 1) > 0) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_AddImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(1); + + while (parcAtomicUint64_AddImpl(instance, 1) < 100000000) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwapImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(0); + + for (uint64_t i = 0; i < 100000000; i++) { + bool actual = parcAtomicUint64_CompareAndSwapImpl(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwapImpl to return true"); + } + + parcAtomicUint64_Release(&instance); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_AtomicUint64); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_AtomicUint64.c b/libparc/parc/concurrent/test/test_parc_AtomicUint64.c new file mode 100644 index 00000000..1649cf1c --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_AtomicUint64.c @@ -0,0 +1,361 @@ +/* + * 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 "../parc_AtomicUint64.c" + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <inttypes.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/testing/parc_MemoryTesting.h> +#include <parc/testing/parc_ObjectTesting.h> + +LONGBOW_TEST_RUNNER(parc_AtomicUint64) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Macros); + LONGBOW_RUN_TEST_FIXTURE(Performance); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_AtomicUint64) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_AtomicUint64) +{ + 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) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + assertNotNull(instance, "Expeced non-null result from parcAtomicUint64_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcAtomicUint64_Acquire, instance); + + parcAtomicUint64_Release(&instance); + assertNull(instance, "Expected null result from parcAtomicUint64_Release();"); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_Compare); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_Copy); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_Equals); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_HashCode); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_IsValid); + + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_AddImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint64_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_Compare) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + PARCAtomicUint64 *high = parcAtomicUint64_Create(8); + PARCAtomicUint64 *low = parcAtomicUint64_Create(6); + PARCAtomicUint64 *equal = parcAtomicUint64_Create(7); + + int actual = parcAtomicUint64_Compare(instance, high); + assertTrue(actual < 0, "Expected < 0"); + actual = parcAtomicUint64_Compare(instance, low); + assertTrue(actual > 0, "Expected > 0"); + actual = parcAtomicUint64_Compare(instance, equal); + assertTrue(actual == 0, "Expected == 0"); + + parcAtomicUint64_Release(&instance); + parcAtomicUint64_Release(&high); + parcAtomicUint64_Release(&low); + parcAtomicUint64_Release(&equal); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_Copy) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + PARCAtomicUint64 *copy = parcAtomicUint64_Copy(instance); + + assertTrue(parcAtomicUint64_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcAtomicUint64_Release(&instance); + parcAtomicUint64_Release(©); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_Equals) +{ + PARCAtomicUint64 *x = parcAtomicUint64_Create(7); + PARCAtomicUint64 *y = parcAtomicUint64_Create(7); + PARCAtomicUint64 *z = parcAtomicUint64_Create(7); + PARCAtomicUint64 *u1 = parcAtomicUint64_Create(6); + + parcObjectTesting_AssertEquals(x, y, z, u1, NULL); + + parcAtomicUint64_Release(&x); + parcAtomicUint64_Release(&y); + parcAtomicUint64_Release(&z); + parcAtomicUint64_Release(&u1); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_HashCode) +{ + PARCAtomicUint64 *x = parcAtomicUint64_Create(7); + parcAtomicUint64_HashCode(x); + parcAtomicUint64_Release(&x); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_IsValid) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + assertTrue(parcAtomicUint64_IsValid(instance), "Expected parcAtomicUint64_Create to result in a valid instance."); + + parcAtomicUint64_Release(&instance); + assertFalse(parcAtomicUint64_IsValid(instance), "Expected parcAtomicUint64_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_SubtractImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_SubtractImpl(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_AddImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_AddImpl(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint64_CompareAndSwapImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + bool actual = parcAtomicUint64_CompareAndSwapImpl(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwapImpl to return true"); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Macros) +{ + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint64_Subtract); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint64_Add); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint64_CompareAndSwap); +} + +LONGBOW_TEST_FIXTURE_SETUP(Macros) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Macros) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint64_Subtract) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_Subtract(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint64_Add) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + parcAtomicUint64_Add(instance, 1); + + uint64_t actual = parcAtomicUint64_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu64, actual); + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint64_CompareAndSwap) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(7); + + bool actual = parcAtomicUint64_CompareAndSwap(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwap to return true"); + parcAtomicUint64_Release(&instance); +} + + +LONGBOW_TEST_FIXTURE_OPTIONS(Performance, .enabled = false) +{ + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_Subtract_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_Add_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwap_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_AddImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Performance) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Performance) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_Subtract_MACRO) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(100000000); + + while (parcAtomicUint64_Subtract(instance, 1) > 0) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_Add_MACRO) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(1); + + while (parcAtomicUint64_Add(instance, 1) < 100000000) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwap_MACRO) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(0); + + for (uint64_t i = 0; i < 100000000; i++) { + bool actual = parcAtomicUint64_CompareAndSwap(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwap to return true"); + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_SubtractImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(100000000); + + while (parcAtomicUint64_SubtractImpl(instance, 1) > 0) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_AddImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(1); + + while (parcAtomicUint64_AddImpl(instance, 1) < 100000000) { + ; + } + + parcAtomicUint64_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint64_CompareAndSwapImpl) +{ + PARCAtomicUint64 *instance = parcAtomicUint64_Create(0); + + for (uint64_t i = 0; i < 100000000; i++) { + bool actual = parcAtomicUint64_CompareAndSwapImpl(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint64_CompareAndSwapImpl to return true"); + } + + parcAtomicUint64_Release(&instance); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_AtomicUint64); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_AtomicUint8.c b/libparc/parc/concurrent/test/test_parc_AtomicUint8.c new file mode 100644 index 00000000..5b89d052 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_AtomicUint8.c @@ -0,0 +1,361 @@ +/* + * 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 "../parc_AtomicUint8.c" + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <inttypes.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/testing/parc_MemoryTesting.h> +#include <parc/testing/parc_ObjectTesting.h> + +LONGBOW_TEST_RUNNER(parc_AtomicUint8) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Macros); + LONGBOW_RUN_TEST_FIXTURE(Performance); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_AtomicUint8) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_AtomicUint8) +{ + 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) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + assertNotNull(instance, "Expeced non-null result from parcAtomicUint8_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcAtomicUint8_Acquire, instance); + + parcAtomicUint8_Release(&instance); + assertNull(instance, "Expected null result from parcAtomicUint8_Release();"); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_Compare); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_Copy); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_Equals); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_HashCode); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_IsValid); + + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_AddImpl); + LONGBOW_RUN_TEST_CASE(Global, parcAtomicUint8_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_Compare) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + PARCAtomicUint8 *high = parcAtomicUint8_Create(8); + PARCAtomicUint8 *low = parcAtomicUint8_Create(6); + PARCAtomicUint8 *equal = parcAtomicUint8_Create(7); + + int actual = parcAtomicUint8_Compare(instance, high); + assertTrue(actual < 0, "Expected < 0"); + actual = parcAtomicUint8_Compare(instance, low); + assertTrue(actual > 0, "Expected > 0"); + actual = parcAtomicUint8_Compare(instance, equal); + assertTrue(actual == 0, "Expected == 0"); + + parcAtomicUint8_Release(&instance); + parcAtomicUint8_Release(&high); + parcAtomicUint8_Release(&low); + parcAtomicUint8_Release(&equal); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_Copy) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + PARCAtomicUint8 *copy = parcAtomicUint8_Copy(instance); + + assertTrue(parcAtomicUint8_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcAtomicUint8_Release(&instance); + parcAtomicUint8_Release(©); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_Equals) +{ + PARCAtomicUint8 *x = parcAtomicUint8_Create(7); + PARCAtomicUint8 *y = parcAtomicUint8_Create(7); + PARCAtomicUint8 *z = parcAtomicUint8_Create(7); + PARCAtomicUint8 *u1 = parcAtomicUint8_Create(6); + + parcObjectTesting_AssertEquals(x, y, z, u1, NULL); + + parcAtomicUint8_Release(&x); + parcAtomicUint8_Release(&y); + parcAtomicUint8_Release(&z); + parcAtomicUint8_Release(&u1); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_HashCode) +{ + PARCAtomicUint8 *x = parcAtomicUint8_Create(7); + parcAtomicUint8_HashCode(x); + parcAtomicUint8_Release(&x); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_IsValid) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + assertTrue(parcAtomicUint8_IsValid(instance), "Expected parcAtomicUint8_Create to result in a valid instance."); + + parcAtomicUint8_Release(&instance); + assertFalse(parcAtomicUint8_IsValid(instance), "Expected parcAtomicUint8_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_SubtractImpl) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + + parcAtomicUint8_SubtractImpl(instance, 1); + + uint8_t actual = parcAtomicUint8_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu8, actual); + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_AddImpl) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + + parcAtomicUint8_AddImpl(instance, 1); + + uint8_t actual = parcAtomicUint8_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu8, actual); + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcAtomicUint8_CompareAndSwapImpl) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + + bool actual = parcAtomicUint8_CompareAndSwapImpl(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint8_CompareAndSwapImpl to return true"); + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Macros) +{ + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint8_Subtract); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint8_Add); + LONGBOW_RUN_TEST_CASE(Macros, parcAtomicUint8_CompareAndSwap); +} + +LONGBOW_TEST_FIXTURE_SETUP(Macros) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Macros) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint8_Subtract) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + + parcAtomicUint8_Subtract(instance, 1); + + uint8_t actual = parcAtomicUint8_GetValue(instance); + + assertTrue(actual == 6, "Expected 6, actual %" PRIu8, actual); + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint8_Add) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + + parcAtomicUint8_Add(instance, 1); + + uint8_t actual = parcAtomicUint8_GetValue(instance); + + assertTrue(actual == 8, "Expected 8, actual %" PRIu8, actual); + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Macros, parcAtomicUint8_CompareAndSwap) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(7); + + bool actual = parcAtomicUint8_CompareAndSwap(instance, 7, 8); + + assertTrue(actual, "Expected parcAtomicUint8_CompareAndSwap to return true"); + parcAtomicUint8_Release(&instance); +} + + +LONGBOW_TEST_FIXTURE_OPTIONS(Performance, .enabled = false) +{ + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint8_Subtract_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint8_Add_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint8_CompareAndSwap_MACRO); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint8_SubtractImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint8_AddImpl); + LONGBOW_RUN_TEST_CASE(Performance, parcAtomicUint8_CompareAndSwapImpl); +} + +LONGBOW_TEST_FIXTURE_SETUP(Performance) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Performance) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint8_Subtract_MACRO) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(255); + + while (parcAtomicUint8_Subtract(instance, 1) > 0) { + ; + } + + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint8_Add_MACRO) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(1); + + while (parcAtomicUint8_Add(instance, 1) < 255) { + ; + } + + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint8_CompareAndSwap_MACRO) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(0); + + for (uint8_t i = 0; i < 255; i++) { + bool actual = parcAtomicUint8_CompareAndSwap(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint8_CompareAndSwap to return true"); + } + + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint8_SubtractImpl) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(255); + + while (parcAtomicUint8_SubtractImpl(instance, 1) > 0) { + ; + } + + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint8_AddImpl) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(1); + + while (parcAtomicUint8_AddImpl(instance, 1) < 255) { + ; + } + + parcAtomicUint8_Release(&instance); +} + +LONGBOW_TEST_CASE(Performance, parcAtomicUint8_CompareAndSwapImpl) +{ + PARCAtomicUint8 *instance = parcAtomicUint8_Create(0); + + for (uint8_t i = 0; i < 255; i++) { + bool actual = parcAtomicUint8_CompareAndSwapImpl(instance, i, i + 1); + assertTrue(actual, "Expected parcAtomicUint8_CompareAndSwapImpl to return true"); + } + + parcAtomicUint8_Release(&instance); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_AtomicUint8); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_FutureTask.c b/libparc/parc/concurrent/test/test_parc_FutureTask.c new file mode 100644 index 00000000..c30d2cae --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_FutureTask.c @@ -0,0 +1,317 @@ +/* + * 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 "../parc_FutureTask.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(parc_FutureTask) +{ + // 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(parc_FutureTask) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_FutureTask) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(CreateAcquireRelease) +{ + LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, CreateRelease); + LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, CreateRelease_PARCObject); +} + +LONGBOW_TEST_FIXTURE_SETUP(CreateAcquireRelease) +{ + longBowTestCase_SetInt(testCase, "initialAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(CreateAcquireRelease) +{ + int initialAllocations = longBowTestCase_GetInt(testCase, "initialAllocations"); + + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +static void * +_function(PARCFutureTask *task, void *parameter) +{ + return parameter; +} + +LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease) +{ + PARCFutureTask *instance = parcFutureTask_Create(_function, _function); + assertNotNull(instance, "Expected non-null result from parcFutureTask_Create(_function, _function);"); + + parcObjectTesting_AssertAcquireReleaseContract(parcFutureTask_Acquire, instance); + + parcFutureTask_Release(&instance); + assertNull(instance, "Expected null result from parcFutureTask_Release();"); +} + +LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease_PARCObject) +{ + PARCBuffer *object = parcBuffer_Allocate(10); + + PARCFutureTask *instance = parcFutureTask_Create(_function, object); + parcBuffer_Release(&object); + + assertNotNull(instance, "Expected non-null result from parcFutureTask_Create(_function, object);"); + + parcObjectTesting_AssertAcquireReleaseContract(parcFutureTask_Acquire, instance); + + parcFutureTask_Release(&instance); + assertNull(instance, "Expected null result from parcFutureTask_Release();"); +} + +LONGBOW_TEST_FIXTURE(Object) +{ + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_Compare); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_Copy); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_Display); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_Equals); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_HashCode); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_IsValid); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_ToJSON); + LONGBOW_RUN_TEST_CASE(Object, parcFutureTask_ToString); +} + +LONGBOW_TEST_FIXTURE_SETUP(Object) +{ + longBowTestCase_SetInt(testCase, "initialAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Object) +{ + int initialAllocations = longBowTestCase_GetInt(testCase, "initialAllocations"); + + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_Compare) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_Copy) +{ + PARCFutureTask *instance = parcFutureTask_Create(_function, _function); + PARCFutureTask *copy = parcFutureTask_Copy(instance); + assertTrue(parcFutureTask_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcFutureTask_Release(&instance); + parcFutureTask_Release(©); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_Display) +{ + PARCFutureTask *instance = parcFutureTask_Create(_function, _function); + parcFutureTask_Display(instance, 0); + parcFutureTask_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_Equals) +{ + PARCFutureTask *x = parcFutureTask_Create(_function, _function); + PARCFutureTask *y = parcFutureTask_Create(_function, _function); + PARCFutureTask *z = parcFutureTask_Create(_function, _function); + PARCFutureTask *u1 = parcFutureTask_Create(_function, NULL); + + parcObjectTesting_AssertEquals(x, y, z, u1, NULL); + + parcFutureTask_Release(&x); + parcFutureTask_Release(&y); + parcFutureTask_Release(&z); + parcFutureTask_Release(&u1); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_HashCode) +{ + PARCFutureTask *x = parcFutureTask_Create(_function, _function); + PARCFutureTask *y = parcFutureTask_Create(_function, _function); + + parcObjectTesting_AssertHashCode(x, y); + + parcFutureTask_Release(&x); + parcFutureTask_Release(&y); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_IsValid) +{ + PARCFutureTask *instance = parcFutureTask_Create(_function, _function); + assertTrue(parcFutureTask_IsValid(instance), "Expected parcFutureTask_Create to result in a valid instance."); + + parcFutureTask_Release(&instance); + assertFalse(parcFutureTask_IsValid(instance), "Expected parcFutureTask_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_ToJSON) +{ + PARCFutureTask *instance = parcFutureTask_Create(_function, _function); + + PARCJSON *json = parcFutureTask_ToJSON(instance); + + parcJSON_Release(&json); + + parcFutureTask_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcFutureTask_ToString) +{ + PARCFutureTask *instance = parcFutureTask_Create(_function, _function); + + char *string = parcFutureTask_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcFutureTask_ToString"); + + parcMemory_Deallocate((void **) &string); + parcFutureTask_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Specialization) +{ + LONGBOW_RUN_TEST_CASE(Specialization, parcFutureTask_Cancel); + LONGBOW_RUN_TEST_CASE(Specialization, parcFutureTask_Get); + LONGBOW_RUN_TEST_CASE(Specialization, parcFutureTask_IsCancelled); + LONGBOW_RUN_TEST_CASE(Specialization, parcFutureTask_IsDone); + LONGBOW_RUN_TEST_CASE(Specialization, parcFutureTask_Run); + LONGBOW_RUN_TEST_CASE(Specialization, parcFutureTask_RunAndReset); +} + +LONGBOW_TEST_FIXTURE_SETUP(Specialization) +{ + longBowTestCase_SetInt(testCase, "initialAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Specialization) +{ + int initialAllocations = longBowTestCase_GetInt(testCase, "initialAllocations"); + + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Specialization, parcFutureTask_Cancel) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + bool parcFutureTask_Cancel(PARCFutureTask *task, bool mayInterruptIfRunning); + + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Specialization, parcFutureTask_Get) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCFutureTaskResult result = parcFutureTask_Get(task, PARCTimeout_Immediate); + + assertTrue(parcExecution_Is(result.execution, PARCExecution_Timeout), "Expected Timeout, actual %s", + parcExecution_GetMessage(result.execution)); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Specialization, parcFutureTask_IsCancelled) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + bool actual = parcFutureTask_IsCancelled(task); + assertFalse(actual, "Expected true."); + + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Specialization, parcFutureTask_IsDone) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + bool actual = parcFutureTask_IsDone(task); + + assertFalse(actual, "Expected false."); + + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Specialization, parcFutureTask_Run) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + parcFutureTask_Run(task); + + PARCFutureTaskResult actual = parcFutureTask_Get(task, PARCTimeout_Immediate); + + assertTrue(parcFutureTask_IsDone(task), "Expected parcFutureTask_IsDone to be true."); + assertTrue(parcExecution_Is(actual.execution, PARCExecution_OK), + "Expected OK, actual %s", parcExecution_GetMessage(actual.execution)); + assertTrue(actual.value == _function, "Expected actual to point to _function"); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Specialization, parcFutureTask_RunAndReset) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + bool actual = parcFutureTask_RunAndReset(task); + + assertTrue(actual, "Expectd parcFutureTask_RunAndReset to return true."); + assertFalse(parcFutureTask_IsDone(task), "Expected parcFutureTask_IsDone to be false"); + parcFutureTask_Release(&task); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_FutureTask); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_Lock.c b/libparc/parc/concurrent/test/test_parc_Lock.c new file mode 100644 index 00000000..731df04a --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_Lock.c @@ -0,0 +1,352 @@ +/* + * 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 "../parc_Lock.c" + +#include <stdio.h> + +#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(parc_Lock) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Locking); + LONGBOW_RUN_TEST_FIXTURE(WaitNotify); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_Lock) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_Lock) +{ + 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) +{ + PARCLock *instance = parcLock_Create(); + assertNotNull(instance, "Expected non-null result from parcLock_Create()."); + + parcObjectTesting_AssertAcquire(instance); + + parcObjectTesting_AssertAcquireReleaseContract(parcLock_Acquire, instance); + + parcLock_Release(&instance); + assertNull(instance, "Expected null result from parcLock_Release()."); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcLock_Display); + LONGBOW_RUN_TEST_CASE(Global, parcLock_IsValid); + LONGBOW_RUN_TEST_CASE(Global, parcLock_ToString); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s mismanaged memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcLock_Display) +{ + PARCLock *lock = parcLock_Create(); + parcLock_Display(lock, 0); + parcLock_Release(&lock); +} + +LONGBOW_TEST_CASE(Global, parcLock_IsValid) +{ + PARCLock *instance = parcLock_Create(); + assertTrue(parcLock_IsValid(instance), "Expected parcLock_Create to result in a valid instance."); + + parcLock_Release(&instance); + assertFalse(parcLock_IsValid(instance), "Expected parcLock_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Global, parcLock_ToString) +{ + PARCLock *instance = parcLock_Create(); + + char *string = parcLock_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcLock_ToString"); + + parcMemory_Deallocate((void **) &string); + parcLock_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Locking) +{ + LONGBOW_RUN_TEST_CASE(Locking, parcLock_TryLock_Unlock); + LONGBOW_RUN_TEST_CASE(Locking, parcLock_TryLock_AlreadyLocked); + LONGBOW_RUN_TEST_CASE(Locking, parcLock_Lock_Unlock); + LONGBOW_RUN_TEST_CASE(Locking, parcLock_Lock_AlreadyLocked); + LONGBOW_RUN_TEST_CASE(Locking, parcLock_Lock_AlreadyLocked); +} + +LONGBOW_TEST_FIXTURE_SETUP(Locking) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Locking) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestRunner_GetName(testRunner), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Locking, parcLock_TryLock_Unlock) +{ + PARCLock *lock = parcLock_Create(); + + bool actual = parcLock_TryLock(lock); + + assertTrue(actual, "Expected parcObject_TryLock to succeed."); + + actual = parcLock_IsLocked(lock); + assertTrue(actual, "Expected parcObject_IsLocked to be true."); + + actual = parcLock_Unlock(lock); + assertTrue(actual, "Expected parcObject_Unlock to succeed."); + + actual = parcLock_IsLocked(lock); + assertTrue(actual, "Expected parcObject_IsLocked to be false."); + + parcLock_Release((PARCLock **) &lock); +} + +LONGBOW_TEST_CASE(Locking, parcLock_Lock_Unlock) +{ + PARCLock *lock = parcLock_Create(); + + bool actual = parcLock_Lock(lock); + + assertTrue(actual, "Expected parcObject_Lock to succeed."); + + actual = parcLock_IsLocked(lock); + assertTrue(actual, "Expected parcObject_IsLocked to be true."); + + actual = parcLock_Unlock(lock); + assertTrue(actual, "Expected parcObject_Unlock to succeed."); + + actual = parcLock_IsLocked(lock); + assertTrue(actual, "Expected parcObject_IsLocked to be false."); + + parcLock_Release((PARCLock **) &lock); +} + +LONGBOW_TEST_CASE(Locking, parcLock_TryLock_AlreadyLocked) +{ + PARCLock *lock = parcLock_Create(); + + bool actual = parcLock_TryLock(lock); + + assertTrue(actual, "Expected parcObject_TryLock to succeed."); + + actual = parcLock_TryLock(lock); + + assertFalse(actual, "Expected parcObject_TryLock to fail when already locked."); + + actual = parcLock_Unlock(lock); + assertTrue(actual, "Expected parcObject_Unlock to succeed."); + + parcLock_Release((PARCLock **) &lock); +} + +LONGBOW_TEST_CASE(Locking, parcLock_Lock_AlreadyLocked) +{ + PARCLock *lock = parcLock_Create(); + + bool actual = parcLock_Lock(lock); + + assertTrue(actual, "Expected parcObject_Lock to succeed."); + + actual = parcLock_Lock(lock); + + assertFalse(actual, "Expected parcObject_Lock to fail when already locked by the same thread."); + + actual = parcLock_Unlock(lock); + assertTrue(actual, "Expected parcObject_Unlock to succeed."); + + parcLock_Release((PARCLock **) &lock); +} + +LONGBOW_TEST_FIXTURE(WaitNotify) +{ + LONGBOW_RUN_TEST_CASE(WaitNotify, parcLock_WaitNotify); + LONGBOW_RUN_TEST_CASE(WaitNotify, parcLock_WaitNotify2); +} + +LONGBOW_TEST_FIXTURE_SETUP(WaitNotify) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(WaitNotify) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestRunner_GetName(testRunner), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +static int _sharedValue; + +static void * +waiter(void *data) +{ + PARCLock *lock = data; + + while (parcLock_TryLock(lock) == false) { + ; + } + parcLock_Wait(lock); + + _sharedValue++; + parcLock_Unlock(lock); + + return data; +} + +LONGBOW_TEST_CASE(WaitNotify, parcLock_WaitNotify) +{ + PARCLock *lock = parcLock_Create(); + + _sharedValue = 0; + + pthread_t thread_A; + pthread_t thread_B; + pthread_t thread_C; + pthread_create(&thread_A, NULL, waiter, lock); + pthread_create(&thread_B, NULL, waiter, lock); + pthread_create(&thread_C, NULL, waiter, lock); + + while (_sharedValue != 3) { + while (parcLock_TryLock(lock) == false) { + ; + } + parcLock_Notify(lock); + parcLock_Unlock(lock); + } + + pthread_join(thread_A, NULL); + + parcLock_Release((PARCLock **) &lock); +} + +static void * +decrement(void *data) +{ + PARCLock *lock = data; + + while (parcLock_TryLock(lock) == false) { + assertTrue(write(1, ".", 1) == 1, "Write failed."); + } + while (_sharedValue < 12) { + parcLock_Wait(lock); + _sharedValue--; + } + parcLock_Unlock(lock); + + return data; +} + +LONGBOW_TEST_CASE(WaitNotify, parcLock_WaitNotify2) +{ + PARCLock *lock = parcLock_Create(); + + _sharedValue = 0; + + pthread_t thread_A; + pthread_create(&thread_A, NULL, decrement, lock); + + _sharedValue = 2; + while (parcLock_TryLock(lock) == false) { + assertTrue(write(1, ".", 1) == 1, "Write failed."); + } + while (_sharedValue <= 12) { + printf("%d\n", _sharedValue); + parcLock_Notify(lock); + _sharedValue += 2; + } + parcLock_Unlock(lock); + + parcLock_Notify(lock); + pthread_join(thread_A, NULL); + + parcLock_Release((PARCLock **) &lock); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Lock); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_Notifier.c b/libparc/parc/concurrent/test/test_parc_Notifier.c new file mode 100755 index 00000000..97ce6615 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_Notifier.c @@ -0,0 +1,267 @@ +/* + * 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 "../parc_Notifier.c" + +#include <sys/time.h> +#include <pthread.h> +#include <poll.h> + +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(parc_Notifier) +{ + // 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(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_Notifier) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_Notifier) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_Acquire); + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_Create_Release); + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_PauseEvent_NotPaused); + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_PauseEvent_AlreadyPaused); + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_StartEvents); + + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_Notify_First); + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_Notify_Twice); + + LONGBOW_RUN_TEST_CASE(Global, parcNotifier_ThreadedTest); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ------ +typedef struct test_data { + volatile int barrier; + PARCNotifier *notifier; + + unsigned notificationsToSend; + unsigned notificationsSent; + + unsigned notificationsToRecieve; + unsigned notificationsReceived; + + pthread_t producerThread; + pthread_t consumerThread; +} TestData; + + +void * +consumer(void *p) +{ + TestData *data = (TestData *) p; + --data->barrier; + while (data->barrier) { + ; + } + + struct pollfd pfd; + pfd.fd = parcNotifier_Socket(data->notifier); + pfd.events = POLLIN; + + while (data->notificationsReceived < data->notificationsToRecieve) { + if (poll(&pfd, 1, -1)) { + data->notificationsReceived++; + parcNotifier_PauseEvents(data->notifier); + usleep(rand() % 1024 + 1024); + printf("skipped = %d\n", data->notifier->skippedNotify); + parcNotifier_StartEvents(data->notifier); + } + } + + --data->barrier; + + printf("Consumer exiting: received %d\n", data->notificationsReceived); + pthread_exit((void *) NULL); +} + +void * +producer(void *p) +{ + TestData *data = (TestData *) p; + --data->barrier; + while (data->barrier) { + ; + } + + while (data->barrier == 0) { + if (parcNotifier_Notify(data->notifier)) { + } + data->notificationsSent++; + usleep(rand() % 1024 + 512); + } + + printf("Producer exiting: sent %d\n", data->notificationsSent); + pthread_exit((void *) NULL); +} + +LONGBOW_TEST_CASE(Global, parcNotifier_Acquire) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Global, parcNotifier_Create_Release) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Global, parcNotifier_PauseEvent_NotPaused) +{ + PARCNotifier *notifier = parcNotifier_Create(); + + parcNotifier_PauseEvents(notifier); + assertTrue(notifier->paused == 1, "Not paused, got %d expected %d", notifier->paused, 1); + assertTrue(notifier->skippedNotify == 0, "Wrong skipped, got %d expected %d", notifier->skippedNotify, 0); + + parcNotifier_Release(¬ifier); +} + +LONGBOW_TEST_CASE(Global, parcNotifier_PauseEvent_AlreadyPaused) +{ + PARCNotifier *notifier = parcNotifier_Create(); + + parcNotifier_PauseEvents(notifier); + + // now pause again + parcNotifier_PauseEvents(notifier); + + assertTrue(notifier->paused == 1, "Not paused, got %d expected %d", notifier->paused, 1); + assertTrue(notifier->skippedNotify == 0, "Wrong skipped, got %d expected %d", notifier->skippedNotify, 0); + + parcNotifier_Release(¬ifier); +} + + +LONGBOW_TEST_CASE(Global, parcNotifier_ThreadedTest) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData)); + + data->notifier = parcNotifier_Create(); + data->notificationsToSend = 10; + data->notificationsToRecieve = data->notificationsToSend; + data->notificationsSent = 0; + data->notificationsReceived = 0; + data->barrier = 2; + + pthread_create(&data->consumerThread, NULL, consumer, data); + pthread_create(&data->producerThread, NULL, producer, data); + + // wait for them to exit + pthread_join(data->producerThread, NULL); + pthread_join(data->consumerThread, NULL); + + assertTrue(data->notificationsReceived >= data->notificationsToRecieve, + "Did not write all items got %u expected %u\n", + data->notificationsReceived, + data->notificationsToRecieve); + + parcNotifier_Release(&data->notifier); + parcMemory_Deallocate((void **) &data); +} + +LONGBOW_TEST_CASE(Global, parcNotifier_StartEvents) +{ + testUnimplemented("unimplemented"); +} + +LONGBOW_TEST_CASE(Global, parcNotifier_Notify_First) +{ + PARCNotifier *notifier = parcNotifier_Create(); + + bool success = parcNotifier_Notify(notifier); + assertTrue(success, "Did not succeed on first notify"); + assertTrue(notifier->paused == 1, "Not paused, got %d expected %d", notifier->paused, 1); + assertTrue(notifier->skippedNotify == 0, "Wrong skipped, got %d expected %d", notifier->skippedNotify, 0); + + parcNotifier_Release(¬ifier); +} + + +LONGBOW_TEST_CASE(Global, parcNotifier_Notify_Twice) +{ + PARCNotifier *notifier = parcNotifier_Create(); + + parcNotifier_Notify(notifier); + + bool success = parcNotifier_Notify(notifier); + assertFalse(success, "Should have failed on second notify"); + assertTrue(notifier->paused == 1, "Not paused, got %d expected %d", notifier->paused, 1); + assertTrue(notifier->skippedNotify == 1, "Wrong skipped, got %d expected %d", notifier->skippedNotify, 1); + + parcNotifier_Release(¬ifier); +} + +// =============================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Notifier); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_RingBuffer_1x1.c b/libparc/parc/concurrent/test/test_parc_RingBuffer_1x1.c new file mode 100755 index 00000000..a977dfbc --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_RingBuffer_1x1.c @@ -0,0 +1,325 @@ +/* + * 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 "../parc_RingBuffer_1x1.c" + +#include <sys/time.h> + +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(parc_RingBuffer_1x1) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_RingBuffer_1x1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_RingBuffer_1x1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Acquire); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Create_Release); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Create_NonPower2); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Get_Put); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Remaining_Empty); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Remaining_Half); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Remaining_Full); + LONGBOW_RUN_TEST_CASE(Global, parcRingBuffer1x1_Put_ToCapacity); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ------ +typedef struct test_ringbuffer { + unsigned itemsToWrite; + volatile unsigned itemsWritten; + volatile unsigned itemsRead; + volatile bool blocked; + + PARCRingBuffer1x1 *producerBuffer; + PARCRingBuffer1x1 *consumerBuffer; + + pthread_t producerThread; + pthread_t consumerThread; +} TestRingBuffer; + + +void * +consumer(void *p) +{ + TestRingBuffer *trb = (TestRingBuffer *) p; + + while (trb->blocked) { + // nothing to do. + } + + while (trb->itemsRead < trb->itemsToWrite) { + uint32_t *data; + bool success = parcRingBuffer1x1_Get(trb->consumerBuffer, (void **) &data); + if (success) { + assertTrue(*data == trb->itemsRead, "Got out of order item %u expected %u\n", *data, trb->itemsRead); + parcMemory_Deallocate((void **) &data); + trb->itemsRead++; + } + } + + pthread_exit((void *) NULL); +} + +void * +producer(void *p) +{ + TestRingBuffer *trb = (TestRingBuffer *) p; + + while (trb->blocked) { + // nothing to do + } + + while (trb->itemsWritten < trb->itemsToWrite) { + uint32_t *data = parcMemory_Allocate(sizeof(uint32_t)); + assertNotNull(data, "parcMemory_Allocate(%zu) returned NULL", sizeof(uint32_t)); + *data = trb->itemsWritten; + + bool success = false; + do { + success = parcRingBuffer1x1_Put(trb->producerBuffer, data); + } while (!success); + trb->itemsWritten++; + } + + pthread_exit((void *) NULL); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Acquire) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE_EXPECTS(Global, parcRingBuffer1x1_Create_NonPower2, .event = &LongBowAssertEvent) +{ + // this will assert because the number of elements is not a power of 2 + parcRingBuffer1x1_Create(3, NULL); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Create_Release) +{ + PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(1024, NULL); + parcRingBuffer1x1_Release(&ring); + assertTrue(parcMemory_Outstanding() == 0, "Non-zero memory balance: %u", parcMemory_Outstanding()); + + printf("ring buffer entry size: %zu\n", sizeof(PARCRingBuffer1x1)); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Get_Put) +{ + TestRingBuffer *trb = parcMemory_AllocateAndClear(sizeof(TestRingBuffer)); + assertNotNull(trb, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestRingBuffer)); + trb->producerBuffer = parcRingBuffer1x1_Create(128, NULL); + trb->consumerBuffer = parcRingBuffer1x1_Acquire(trb->producerBuffer); + + trb->itemsToWrite = 100000; + trb->blocked = true; + + pthread_create(&trb->consumerThread, NULL, consumer, trb); + pthread_create(&trb->producerThread, NULL, producer, trb); + + struct timeval t0, t1; + + gettimeofday(&t0, NULL); + trb->blocked = false; + + // wait for them to exit + pthread_join(trb->producerThread, NULL); + pthread_join(trb->consumerThread, NULL); + gettimeofday(&t1, NULL); + + timersub(&t1, &t0, &t1); + + assertTrue(trb->itemsWritten == trb->itemsToWrite, + "Did not write all items got %u expected %u\n", + trb->itemsWritten, + trb->itemsToWrite); + + assertTrue(trb->itemsRead == trb->itemsToWrite, + "Did not read all items got %u expected %u\n", + trb->itemsRead, + trb->itemsToWrite); + + double sec = t1.tv_sec + t1.tv_usec * 1E-6; + + printf("Passed %u items in %.6f seconds, %.2f items/sec\n", + trb->itemsWritten, + sec, + trb->itemsWritten / sec); + + parcRingBuffer1x1_Release(&trb->consumerBuffer); + parcRingBuffer1x1_Release(&trb->producerBuffer); + parcMemory_Deallocate((void **) &trb); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Remaining_Empty) +{ + uint32_t capacity = 128; + PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(capacity, NULL); + uint32_t remaining = parcRingBuffer1x1_Remaining(ring); + parcRingBuffer1x1_Release(&ring); + + // -1 because the ring buffer is always -1 + assertTrue(remaining == capacity - 1, "Got wrong remaining, got %u expecting %u\n", remaining, capacity); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Remaining_Half) +{ + uint32_t capacity = 128; + PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(capacity, NULL); + for (int i = 0; i < capacity / 2; i++) { + parcRingBuffer1x1_Put(ring, &i); + } + + uint32_t remaining = parcRingBuffer1x1_Remaining(ring); + parcRingBuffer1x1_Release(&ring); + + // -1 because the ring buffer is always -1 + assertTrue(remaining == capacity / 2 - 1, "Got wrong remaining, got %u expecting %u\n", remaining, capacity / 2 - 1); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Remaining_Full) +{ + uint32_t capacity = 128; + PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(capacity, NULL); + for (int i = 0; i < capacity - 1; i++) { + parcRingBuffer1x1_Put(ring, &i); + } + + uint32_t remaining = parcRingBuffer1x1_Remaining(ring); + parcRingBuffer1x1_Release(&ring); + + assertTrue(remaining == 0, "Got wrong remaining, got %u expecting %u\n", remaining, 0); +} + +LONGBOW_TEST_CASE(Global, parcRingBuffer1x1_Put_ToCapacity) +{ + uint32_t capacity = 128; + PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(capacity, NULL); + for (int i = 0; i < capacity - 1; i++) { + parcRingBuffer1x1_Put(ring, &i); + } + + // this next put should fail + bool success = parcRingBuffer1x1_Put(ring, &capacity); + + parcRingBuffer1x1_Release(&ring); + + assertFalse(success, "Should have failed on final put because data structure is full\n"); +} + +LONGBOW_TEST_FIXTURE(Local) +{ + LONGBOW_RUN_TEST_CASE(Local, _create); + LONGBOW_RUN_TEST_CASE(Local, _destroy); + LONGBOW_RUN_TEST_CASE(Local, _isPowerOfTwo); +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Local, _create) +{ + testUnimplemented(""); +} + +static void +_testDestoryer(void **ptr) +{ + parcBuffer_Release((PARCBuffer **) ptr); +} + +LONGBOW_TEST_CASE(Local, _destroy) +{ + // put something in the ring and don't remove it. Make sure the destroyer catches it. + + uint32_t capacity = 128; + PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(capacity, _testDestoryer); + + PARCBuffer *buffer = parcBuffer_Allocate(5); + parcRingBuffer1x1_Put(ring, buffer); + + parcRingBuffer1x1_Release(&ring); + assertTrue(parcMemory_Outstanding() == 0, "Memory imbalance, expected 0 got %u", parcMemory_Outstanding()); +} + +LONGBOW_TEST_CASE(Local, _isPowerOfTwo) +{ + struct test_struct { + uint32_t value; + bool isPow2; + } test_vector[] = { { 0, false }, { 1, true }, { 2, true }, { 15, false }, { 16, true }, { 32, true }, { UINT32_MAX, true } }; + + for (int i = 0; test_vector[i].value != UINT32_MAX; i++) { + bool test = _isPowerOfTwo(test_vector[i].value); + assertTrue(test == test_vector[i].isPow2, "Got wrong result for value %u, got %d expected %d\n", test_vector[i].value, test, test_vector[i].isPow2); + } +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_RingBuffer_1x1); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_RingBuffer_NxM.c b/libparc/parc/concurrent/test/test_parc_RingBuffer_NxM.c new file mode 100755 index 00000000..974da053 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_RingBuffer_NxM.c @@ -0,0 +1,106 @@ +/* + * 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 "../parc_RingBuffer_NxM.c" + +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(parc_RingBuffer_NxM) +{ + // 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(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_RingBuffer_NxM) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_RingBuffer_NxM) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("Tests leak memory by %d allocations\n", outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Local) +{ + LONGBOW_RUN_TEST_CASE(Local, _destroy); +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +static void +_testDestoryer(void **ptr) +{ + parcBuffer_Release((PARCBuffer **) ptr); +} + +LONGBOW_TEST_CASE(Local, _destroy) +{ + // put something in the ring and don't remove it. Make sure the destroyer catches it. + + uint32_t capacity = 128; + PARCRingBufferNxM *ring = parcRingBufferNxM_Create(capacity, _testDestoryer); + + PARCBuffer *buffer = parcBuffer_Allocate(5); + parcRingBufferNxM_Put(ring, buffer); + + parcRingBufferNxM_Release(&ring); + assertTrue(parcMemory_Outstanding() == 0, "Memory imbalance, expected 0 got %u", parcMemory_Outstanding()); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_RingBuffer_NxM); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_ScheduledTask.c b/libparc/parc/concurrent/test/test_parc_ScheduledTask.c new file mode 100644 index 00000000..3655be93 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_ScheduledTask.c @@ -0,0 +1,244 @@ +/* + * 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 "../parc_ScheduledTask.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(parc_ScheduledTask) +{ + // 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(parc_ScheduledTask) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_ScheduledTask) +{ + 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; +} + +void * +_function(PARCFutureTask *task, void *parameter) +{ + return parameter; +} + +LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *instance = parcScheduledTask_Create(task, 0); + assertNotNull(instance, "Expected non-null result from parcScheduledTask_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcScheduledTask_Acquire, instance); + + parcScheduledTask_Release(&instance); + assertNull(instance, "Expected null result from parcScheduledTask_Release();"); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_FIXTURE(Object) +{ + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_Compare); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_Copy); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_Display); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_Equals); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_HashCode); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_IsValid); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_ToJSON); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledTask_ToString); +} + +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, parcScheduledTask_Compare) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_Copy) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *instance = parcScheduledTask_Create(task, 0); + PARCScheduledTask *copy = parcScheduledTask_Copy(instance); + assertTrue(parcScheduledTask_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcScheduledTask_Release(&instance); + parcScheduledTask_Release(©); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_Display) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *instance = parcScheduledTask_Create(task, 0); + parcScheduledTask_Display(instance, 0); + parcScheduledTask_Release(&instance); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_Equals) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *x = parcScheduledTask_Create(task, 0); + PARCScheduledTask *y = parcScheduledTask_Create(task, 0); + PARCScheduledTask *z = parcScheduledTask_Create(task, 0); + + parcObjectTesting_AssertEquals(x, y, z, NULL); + + parcScheduledTask_Release(&x); + parcScheduledTask_Release(&y); + parcScheduledTask_Release(&z); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_HashCode) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *x = parcScheduledTask_Create(task, 0); + PARCScheduledTask *y = parcScheduledTask_Create(task, 0); + + parcObjectTesting_AssertHashCode(x, y); + + parcScheduledTask_Release(&x); + parcScheduledTask_Release(&y); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_IsValid) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *instance = parcScheduledTask_Create(task, 0); + assertTrue(parcScheduledTask_IsValid(instance), "Expected parcScheduledTask_Create to result in a valid instance."); + + parcScheduledTask_Release(&instance); + assertFalse(parcScheduledTask_IsValid(instance), "Expected parcScheduledTask_Release to result in an invalid instance."); + + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_ToJSON) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *instance = parcScheduledTask_Create(task, 0); + + PARCJSON *json = parcScheduledTask_ToJSON(instance); + + parcJSON_Release(&json); + + parcScheduledTask_Release(&instance); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_CASE(Object, parcScheduledTask_ToString) +{ + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + PARCScheduledTask *instance = parcScheduledTask_Create(task, 0); + + char *string = parcScheduledTask_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcScheduledTask_ToString"); + + parcMemory_Deallocate((void **) &string); + parcScheduledTask_Release(&instance); + parcFutureTask_Release(&task); +} + +LONGBOW_TEST_FIXTURE(Specialization) +{ +} + +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; +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_ScheduledTask); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + diff --git a/libparc/parc/concurrent/test/test_parc_ScheduledThreadPool.c b/libparc/parc/concurrent/test/test_parc_ScheduledThreadPool.c new file mode 100644 index 00000000..f466d72a --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_ScheduledThreadPool.c @@ -0,0 +1,301 @@ +/* + * 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 "../parc_ScheduledThreadPool.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(parc_ScheduledThreadPool) +{ + // 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(parc_ScheduledThreadPool) +{ + 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(parc_ScheduledThreadPool) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(CreateAcquireRelease) +{ + LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, CreateRelease); +} + +LONGBOW_TEST_FIXTURE_SETUP(CreateAcquireRelease) +{ + longBowTestCase_SetInt(testCase, "initalAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(CreateAcquireRelease) +{ + int initialAllocations = longBowTestCase_GetInt(testCase, "initalAllocations"); + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease) +{ + PARCScheduledThreadPool *instance = parcScheduledThreadPool_Create(3); + assertNotNull(instance, "Expected non-null result from parcScheduledThreadPool_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcScheduledThreadPool_Acquire, instance); + parcScheduledThreadPool_ShutdownNow(instance); + + assertTrue(parcObject_GetReferenceCount(instance) == 1, "Expected 1 reference count. Actual %llu", parcObject_GetReferenceCount(instance)); + + parcScheduledThreadPool_Release(&instance); + assertNull(instance, "Expected null result from parcScheduledThreadPool_Release();"); +} + +LONGBOW_TEST_FIXTURE(Object) +{ + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_Compare); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_Copy); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_Display); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_Equals); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_HashCode); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_IsValid); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_ToJSON); + LONGBOW_RUN_TEST_CASE(Object, parcScheduledThreadPool_ToString); +} + +LONGBOW_TEST_FIXTURE_SETUP(Object) +{ + longBowTestCase_SetInt(testCase, "initalAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Object) +{ + int initialAllocations = longBowTestCase_GetInt(testCase, "initalAllocations"); + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_Compare) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_Copy) +{ + PARCScheduledThreadPool *instance = parcScheduledThreadPool_Create(3); + PARCScheduledThreadPool *copy = parcScheduledThreadPool_Copy(instance); + assertTrue(parcScheduledThreadPool_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcScheduledThreadPool_ShutdownNow(instance); + parcScheduledThreadPool_ShutdownNow(copy); + + parcScheduledThreadPool_Release(&instance); + parcScheduledThreadPool_Release(©); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_Display) +{ + PARCScheduledThreadPool *instance = parcScheduledThreadPool_Create(2); + parcScheduledThreadPool_Display(instance, 0); + parcScheduledThreadPool_ShutdownNow(instance); + parcScheduledThreadPool_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_Equals) +{ + PARCScheduledThreadPool *x = parcScheduledThreadPool_Create(2); + PARCScheduledThreadPool *y = parcScheduledThreadPool_Create(2); + PARCScheduledThreadPool *z = parcScheduledThreadPool_Create(2); + PARCScheduledThreadPool *u1 = parcScheduledThreadPool_Create(3); + + parcObjectTesting_AssertEquals(x, y, z, u1, NULL); + + parcScheduledThreadPool_ShutdownNow(x); + parcScheduledThreadPool_ShutdownNow(y); + parcScheduledThreadPool_ShutdownNow(z); + parcScheduledThreadPool_ShutdownNow(u1); + + parcScheduledThreadPool_Release(&x); + parcScheduledThreadPool_Release(&y); + parcScheduledThreadPool_Release(&z); + parcScheduledThreadPool_Release(&u1); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_HashCode) +{ + PARCScheduledThreadPool *x = parcScheduledThreadPool_Create(2); + PARCScheduledThreadPool *y = parcScheduledThreadPool_Create(2); + + parcObjectTesting_AssertHashCode(x, y); + + parcScheduledThreadPool_ShutdownNow(x); + parcScheduledThreadPool_ShutdownNow(y); + + parcScheduledThreadPool_Release(&x); + parcScheduledThreadPool_Release(&y); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_IsValid) +{ + PARCScheduledThreadPool *instance = parcScheduledThreadPool_Create(2); + assertTrue(parcScheduledThreadPool_IsValid(instance), "Expected parcScheduledThreadPool_Create to result in a valid instance."); + + parcScheduledThreadPool_ShutdownNow(instance); + + parcScheduledThreadPool_Release(&instance); + assertFalse(parcScheduledThreadPool_IsValid(instance), "Expected parcScheduledThreadPool_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_ToJSON) +{ + PARCScheduledThreadPool *instance = parcScheduledThreadPool_Create(2); + + PARCJSON *json = parcScheduledThreadPool_ToJSON(instance); + + parcJSON_Release(&json); + + parcScheduledThreadPool_ShutdownNow(instance); + parcScheduledThreadPool_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcScheduledThreadPool_ToString) +{ + PARCScheduledThreadPool *instance = parcScheduledThreadPool_Create(2); + + char *string = parcScheduledThreadPool_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcScheduledThreadPool_ToString"); + + parcMemory_Deallocate((void **) &string); + parcScheduledThreadPool_ShutdownNow(instance); + parcScheduledThreadPool_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Specialization) +{ + LONGBOW_RUN_TEST_CASE(Specialization, OneJob); + LONGBOW_RUN_TEST_CASE(Specialization, Idle); + LONGBOW_RUN_TEST_CASE(Specialization, parcScheduledThreadPool_Schedule); +} + +LONGBOW_TEST_FIXTURE_SETUP(Specialization) +{ + longBowTestCase_SetInt(testCase, "initalAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Specialization) +{ + int initialAllocations = longBowTestCase_GetInt(testCase, "initalAllocations"); + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Specialization, Idle) +{ + PARCScheduledThreadPool *pool = parcScheduledThreadPool_Create(3); + + sleep(2); + + parcScheduledThreadPool_ShutdownNow(pool); + + parcScheduledThreadPool_Release(&pool); +} + +static void * +_function(PARCFutureTask *task, void *parameter) +{ + printf("Hello World\n"); + return parameter; +} + +LONGBOW_TEST_CASE(Specialization, OneJob) +{ + PARCScheduledThreadPool *pool = parcScheduledThreadPool_Create(3); + + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + parcScheduledThreadPool_Schedule(pool, task, parcTimeout_MilliSeconds(2000)); + printf("references %lld\n", parcObject_GetReferenceCount(task)); + parcFutureTask_Release(&task); + + sleep(5); + + parcScheduledThreadPool_ShutdownNow(pool); + + parcScheduledThreadPool_Release(&pool); +} + +LONGBOW_TEST_CASE(Specialization, parcScheduledThreadPool_Schedule) +{ + PARCScheduledThreadPool *pool = parcScheduledThreadPool_Create(3); + + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + + parcScheduledThreadPool_Schedule(pool, task, parcTimeout_MilliSeconds(2000)); + + parcFutureTask_Release(&task); + + parcScheduledThreadPool_Shutdown(pool); +// parcScheduledThreadPool_AwaitTermination(pool, PARCTimeout_Never); + +// uint64_t count = parcScheduledThreadPool_GetCompletedTaskCount(pool); +// assertTrue(count == 5, "Expected 5, actual %lld", count); + + parcScheduledThreadPool_ShutdownNow(pool); + + parcScheduledThreadPool_Release(&pool); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_ScheduledThreadPool); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/concurrent/test/test_parc_Synchronizer.c b/libparc/parc/concurrent/test/test_parc_Synchronizer.c new file mode 100755 index 00000000..34d9c711 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_Synchronizer.c @@ -0,0 +1,179 @@ +/* + * 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 "../parc_Synchronizer.c" + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/algol/parc_SafeMemory.h> +#include <parc/testing/parc_MemoryTesting.h> +#include <parc/testing/parc_ObjectTesting.h> + +LONGBOW_TEST_RUNNER(parc_Synchronizer) +{ + // 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(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_Synchronizer) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_Synchronizer) +{ + 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) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + assertNotNull(instance, "Expeced non-null result from parcSynchronizer_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcSynchronizer_Acquire, instance); + + parcSynchronizer_Release(&instance); + assertNull(instance, "Expeced null result from parcSynchronizer_Release();"); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcSynchronizer_Display); + LONGBOW_RUN_TEST_CASE(Global, parcSynchronizer_IsValid); + + LONGBOW_RUN_TEST_CASE(Global, parcSynchronizer_TryLock); + LONGBOW_RUN_TEST_CASE(Global, parcSynchronizer_LockUnlock); + LONGBOW_RUN_TEST_CASE(Global, parcSynchronizer_TryLock_Fail); + LONGBOW_RUN_TEST_CASE(Global, parcSynchronizer_IsLocked); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcSynchronizer_Display) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + assertTrue(parcSynchronizer_IsValid(instance), "Expected parcSynchronizer_Create to result in a valid instance."); + + parcSynchronizer_Display(instance, 0); + parcSynchronizer_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcSynchronizer_IsValid) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + assertTrue(parcSynchronizer_IsValid(instance), "Expected parcSynchronizer_Create to result in a valid instance."); + + parcSynchronizer_Release(&instance); + assertFalse(parcSynchronizer_IsValid(instance), "Expected parcSynchronizer_Create to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Global, parcSynchronizer_TryLock) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + + bool actual = parcSynchronizer_TryLock(instance); + assertTrue(actual, "Expected parcSynchronizer_TryLock to be successful."); + + parcSynchronizer_Unlock(instance); + parcSynchronizer_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcSynchronizer_TryLock_Fail) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + + parcSynchronizer_Lock(instance); + bool actual = parcSynchronizer_TryLock(instance); + assertFalse(actual, "Expected parcSynchronizer_TryLock to be unsuccessful."); + + parcSynchronizer_Unlock(instance); + parcSynchronizer_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcSynchronizer_LockUnlock) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + + parcSynchronizer_Lock(instance); + parcSynchronizer_Unlock(instance); + + parcSynchronizer_Release(&instance); +} + +LONGBOW_TEST_CASE(Global, parcSynchronizer_IsLocked) +{ + PARCSynchronizer *instance = parcSynchronizer_Create(); + assertFalse(parcSynchronizer_IsLocked(instance), "Expected the synchronizer to be unlocked."); + + parcSynchronizer_Lock(instance); + assertTrue(parcSynchronizer_IsLocked(instance), "Expected the synchronizer to be unlocked."); + + parcSynchronizer_Unlock(instance); + assertFalse(parcSynchronizer_IsLocked(instance), "Expected the synchronizer to be unlocked."); + + parcSynchronizer_Release(&instance); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Synchronizer); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + diff --git a/libparc/parc/concurrent/test/test_parc_Thread.c b/libparc/parc/concurrent/test/test_parc_Thread.c new file mode 100644 index 00000000..22ca31bf --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_Thread.c @@ -0,0 +1,264 @@ +/* + * 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 "../parc_ThreadPool.c" + +#include <stdio.h> + +#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(parc_Thread) +{ + // 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(parc_Thread) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_Thread) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(CreateAcquireRelease) +{ + LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, CreateRelease); +} + +LONGBOW_TEST_FIXTURE_SETUP(CreateAcquireRelease) +{ + longBowTestCase_SetInt(testCase, "initialAllocations", parcMemory_Outstanding()); + + PARCBuffer *buffer = parcBuffer_Allocate(10); + longBowTestCase_Set(testCase, "object", buffer); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(CreateAcquireRelease) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + parcBuffer_Release(&buffer); + + uint32_t initialAllocations = (uint32_t) longBowTestCase_Get(testCase, "initialAllocations"); + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +static void * +_function(PARCThread *thread, void *parameter) +{ + return NULL; +} + +LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *thread = parcThread_Create(_function, buffer); + + assertNotNull(thread, "Expected non-null result from parcThread_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcThread_Acquire, thread); + + parcThread_Release(&thread); + assertNull(thread, "Expected null result from parcThread_Release();"); +} + +LONGBOW_TEST_FIXTURE(Object) +{ + LONGBOW_RUN_TEST_CASE(Object, parcThread_Compare); + LONGBOW_RUN_TEST_CASE(Object, parcThread_Copy); + LONGBOW_RUN_TEST_CASE(Object, parcThread_Display); + LONGBOW_RUN_TEST_CASE(Object, parcThread_Equals); + LONGBOW_RUN_TEST_CASE(Object, parcThread_HashCode); + LONGBOW_RUN_TEST_CASE(Object, parcThread_IsValid); + LONGBOW_RUN_TEST_CASE(Object, parcThread_ToJSON); + LONGBOW_RUN_TEST_CASE(Object, parcThread_ToString); +} + +LONGBOW_TEST_FIXTURE_SETUP(Object) +{ + longBowTestCase_SetInt(testCase, "initialAllocations", parcMemory_Outstanding()); + PARCBuffer *buffer = parcBuffer_Allocate(10); + longBowTestCase_Set(testCase, "object", buffer); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Object) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + parcBuffer_Release(&buffer); + + uint32_t initialAllocations = (uint32_t) longBowTestCase_Get(testCase, "initialAllocations"); + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Object, parcThread_Compare) +{ +// testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Object, parcThread_Copy) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *instance = parcThread_Create(_function, buffer); + PARCThread *copy = parcThread_Copy(instance); + + assertTrue(parcThread_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcThread_Release(&instance); + parcThread_Release(©); +} + +LONGBOW_TEST_CASE(Object, parcThread_Display) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *instance = parcThread_Create(_function, buffer); + parcThread_Display(instance, 0); + + + parcThread_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcThread_Equals) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *x = parcThread_Create(_function, buffer); + PARCThread *y = parcThread_Create(_function, buffer); + PARCThread *z = parcThread_Create(_function, buffer); + + parcObjectTesting_AssertEquals(x, y, z, NULL); + + parcThread_Release(&x); + parcThread_Release(&y); + parcThread_Release(&z); +} + +LONGBOW_TEST_CASE(Object, parcThread_HashCode) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *x = parcThread_Create(_function, buffer); + PARCThread *y = parcThread_Create(_function, buffer); + + parcObjectTesting_AssertHashCode(x, y); + + parcThread_Release(&x); + parcThread_Release(&y); +} + +LONGBOW_TEST_CASE(Object, parcThread_IsValid) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *instance = parcThread_Create(_function, buffer); + assertTrue(parcThread_IsValid(instance), "Expected parcThread_Create to result in a valid instance."); + + + parcThread_Release(&instance); + assertFalse(parcThread_IsValid(instance), "Expected parcThread_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Object, parcThread_ToJSON) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *instance = parcThread_Create(_function, buffer); + + PARCJSON *json = parcThread_ToJSON(instance); + + parcJSON_Release(&json); + + + parcThread_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcThread_ToString) +{ + PARCBuffer *buffer = longBowTestCase_Get(testCase, "object"); + PARCThread *instance = parcThread_Create(_function, buffer); + + char *string = parcThread_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcThread_ToString"); + + parcMemory_Deallocate((void **) &string); + + parcThread_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Specialization) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + LONGBOW_RUN_TEST_CASE(Object, parcThread_Execute); +} + +LONGBOW_TEST_FIXTURE_SETUP(Specialization) +{ + longBowTestCase_SetInt(testCase, "initialAllocations", parcMemory_Outstanding()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Specialization) +{ + uint32_t initialAllocations = (uint32_t) longBowTestCase_Get(testCase, "initialAllocations"); + if (!parcMemoryTesting_ExpectedOutstanding(initialAllocations, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Object, parcThread_Execute) +{ +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Thread); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + diff --git a/libparc/parc/concurrent/test/test_parc_ThreadPool.c b/libparc/parc/concurrent/test/test_parc_ThreadPool.c new file mode 100644 index 00000000..6ed6e4d3 --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_ThreadPool.c @@ -0,0 +1,273 @@ +/* + * 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 "../parc_ThreadPool.c" + +#include <stdio.h> + +#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(parc_ThreadPool) +{ + // 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(parc_ThreadPool) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_ThreadPool) +{ + 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) +{ + PARCThreadPool *pool = parcThreadPool_Create(6); + assertNotNull(pool, "Expected non-null result from parcThreadPool_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcThreadPool_Acquire, pool); + + parcThreadPool_ShutdownNow(pool); + + parcThreadPool_Release(&pool); + assertNull(pool, "Expected null result from parcThreadPool_Release();"); +} + +LONGBOW_TEST_FIXTURE(Object) +{ + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_Compare); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_Copy); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_Display); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_Equals); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_HashCode); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_IsValid); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_ToJSON); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_ToString); +} + +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, parcThreadPool_Compare) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_Copy) +{ + PARCThreadPool *instance = parcThreadPool_Create(6); + PARCThreadPool *copy = parcThreadPool_Copy(instance); + assertTrue(parcThreadPool_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcThreadPool_ShutdownNow(instance); + parcThreadPool_ShutdownNow(copy); + + parcThreadPool_Release(&instance); + parcThreadPool_Release(©); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_Display) +{ + PARCThreadPool *instance = parcThreadPool_Create(6); + parcThreadPool_Display(instance, 0); + + parcThreadPool_ShutdownNow(instance); + + parcThreadPool_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_Equals) +{ + PARCThreadPool *x = parcThreadPool_Create(6); + PARCThreadPool *y = parcThreadPool_Create(6); + PARCThreadPool *z = parcThreadPool_Create(6); + + parcObjectTesting_AssertEquals(x, y, z, NULL); + + parcThreadPool_ShutdownNow(x); + parcThreadPool_ShutdownNow(y); + parcThreadPool_ShutdownNow(z); + + parcThreadPool_Release(&x); + parcThreadPool_Release(&y); + parcThreadPool_Release(&z); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_HashCode) +{ + PARCThreadPool *x = parcThreadPool_Create(6); + PARCThreadPool *y = parcThreadPool_Create(6); + + parcObjectTesting_AssertHashCode(x, y); + + parcThreadPool_ShutdownNow(x); + parcThreadPool_ShutdownNow(y); + + parcThreadPool_Release(&x); + parcThreadPool_Release(&y); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_IsValid) +{ + PARCThreadPool *instance = parcThreadPool_Create(6); + assertTrue(parcThreadPool_IsValid(instance), "Expected parcThreadPool_Create to result in a valid instance."); + + parcThreadPool_ShutdownNow(instance); + + parcThreadPool_Release(&instance); + assertFalse(parcThreadPool_IsValid(instance), "Expected parcThreadPool_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_ToJSON) +{ + PARCThreadPool *instance = parcThreadPool_Create(6); + + PARCJSON *json = parcThreadPool_ToJSON(instance); + + parcJSON_Release(&json); + + parcThreadPool_ShutdownNow(instance); + + parcThreadPool_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_ToString) +{ + PARCThreadPool *instance = parcThreadPool_Create(6); + + char *string = parcThreadPool_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcThreadPool_ToString"); + + parcMemory_Deallocate((void **) &string); + + parcThreadPool_ShutdownNow(instance); + + parcThreadPool_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Specialization) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + LONGBOW_RUN_TEST_CASE(Object, parcThreadPool_Execute); +} + +LONGBOW_TEST_FIXTURE_SETUP(Specialization) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Specialization) +{ + if (!parcMemoryTesting_ExpectedOutstanding(0, "%s mismanaged memory.", longBowTestCase_GetFullName(testCase))) { + parcSafeMemory_ReportAllocation(1); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +void * +_function(PARCFutureTask *task, void *parameter) +{ + printf("Hello World\n"); + return parameter; +} + +LONGBOW_TEST_CASE(Object, parcThreadPool_Execute) +{ + dprintf(1, "-----\n"); + PARCThreadPool *pool = parcThreadPool_Create(6); + + PARCFutureTask *task = parcFutureTask_Create(_function, _function); + parcThreadPool_Execute(pool, task); + parcThreadPool_Execute(pool, task); + parcThreadPool_Execute(pool, task); + parcThreadPool_Execute(pool, task); + parcThreadPool_Execute(pool, task); + parcFutureTask_Release(&task); + + parcThreadPool_Shutdown(pool); + bool shutdownSuccess = parcThreadPool_AwaitTermination(pool, PARCTimeout_Never); + + assertTrue(shutdownSuccess, "parcThreadPool_AwaitTermination timed-out"); + + uint64_t count = parcThreadPool_GetCompletedTaskCount(pool); + assertTrue(count == 5, "Expected 5, actual %lld", count); + + + parcThreadPool_Release(&pool); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_ThreadPool); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + diff --git a/libparc/parc/concurrent/test/test_parc_Timer.c b/libparc/parc/concurrent/test/test_parc_Timer.c new file mode 100644 index 00000000..5bc7ae6c --- /dev/null +++ b/libparc/parc/concurrent/test/test_parc_Timer.c @@ -0,0 +1,213 @@ +/* + * 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 "../parc_Timer.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(parc_Timer) +{ + // 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(parc_Timer) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_Timer) +{ + 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) +{ + PARCTimer *instance = parcTimer_Create(); + assertNotNull(instance, "Expected non-null result from parcTimer_Create();"); + + parcObjectTesting_AssertAcquireReleaseContract(parcTimer_Acquire, instance); + + parcTimer_Release(&instance); + assertNull(instance, "Expected null result from parcTimer_Release();"); +} + +LONGBOW_TEST_FIXTURE(Object) +{ + LONGBOW_RUN_TEST_CASE(Object, parcTimer_Compare); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_Copy); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_Display); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_Equals); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_HashCode); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_IsValid); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_ToJSON); + LONGBOW_RUN_TEST_CASE(Object, parcTimer_ToString); +} + +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, parcTimer_Compare) +{ + testUnimplemented(""); +} + +LONGBOW_TEST_CASE(Object, parcTimer_Copy) +{ + PARCTimer *instance = parcTimer_Create(); + PARCTimer *copy = parcTimer_Copy(instance); + assertTrue(parcTimer_Equals(instance, copy), "Expected the copy to be equal to the original"); + + parcTimer_Release(&instance); + parcTimer_Release(©); +} + +LONGBOW_TEST_CASE(Object, parcTimer_Display) +{ + PARCTimer *instance = parcTimer_Create(); + parcTimer_Display(instance, 0); + parcTimer_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcTimer_Equals) +{ + PARCTimer *x = parcTimer_Create(); + PARCTimer *y = parcTimer_Create(); + PARCTimer *z = parcTimer_Create(); + + parcObjectTesting_AssertEquals(x, y, z, NULL); + + parcTimer_Release(&x); + parcTimer_Release(&y); + parcTimer_Release(&z); +} + +LONGBOW_TEST_CASE(Object, parcTimer_HashCode) +{ + PARCTimer *x = parcTimer_Create(); + PARCTimer *y = parcTimer_Create(); + + parcObjectTesting_AssertHashCode(x, y); + + parcTimer_Release(&x); + parcTimer_Release(&y); +} + +LONGBOW_TEST_CASE(Object, parcTimer_IsValid) +{ + PARCTimer *instance = parcTimer_Create(); + assertTrue(parcTimer_IsValid(instance), "Expected parcTimer_Create to result in a valid instance."); + + parcTimer_Release(&instance); + assertFalse(parcTimer_IsValid(instance), "Expected parcTimer_Release to result in an invalid instance."); +} + +LONGBOW_TEST_CASE(Object, parcTimer_ToJSON) +{ + PARCTimer *instance = parcTimer_Create(); + + PARCJSON *json = parcTimer_ToJSON(instance); + + parcJSON_Release(&json); + + parcTimer_Release(&instance); +} + +LONGBOW_TEST_CASE(Object, parcTimer_ToString) +{ + PARCTimer *instance = parcTimer_Create(); + + char *string = parcTimer_ToString(instance); + + assertNotNull(string, "Expected non-NULL result from parcTimer_ToString"); + + parcMemory_Deallocate((void **) &string); + parcTimer_Release(&instance); +} + +LONGBOW_TEST_FIXTURE(Specialization) +{ +} + +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; +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Timer); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + |