// // Copyright © 2019-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include #include #include #include #include #include using namespace arm::pipe; TEST_SUITE("ProfilingGuidTests") { TEST_CASE("GuidTest") { ProfilingGuid guid0(0); ProfilingGuid guid1(1); ProfilingGuid guid2(1); CHECK(guid0 != guid1); CHECK(guid1 == guid2); CHECK(guid0 < guid1); CHECK(guid0 <= guid1); CHECK(guid1 <= guid2); CHECK(guid1 > guid0); CHECK(guid1 >= guid0); CHECK(guid1 >= guid2); } TEST_CASE("StaticGuidTest") { ProfilingStaticGuid guid0(0); ProfilingStaticGuid guid1(1); ProfilingStaticGuid guid2(1); CHECK(guid0 != guid1); CHECK(guid1 == guid2); CHECK(guid0 < guid1); CHECK(guid0 <= guid1); CHECK(guid1 <= guid2); CHECK(guid1 > guid0); CHECK(guid1 >= guid0); CHECK(guid1 >= guid2); } TEST_CASE("DynamicGuidTest") { ProfilingDynamicGuid guid0(0); ProfilingDynamicGuid guid1(1); ProfilingDynamicGuid guid2(1); CHECK(guid0 != guid1); CHECK(guid1 == guid2); CHECK(guid0 < guid1); CHECK(guid0 <= guid1); CHECK(guid1 <= guid2); CHECK(guid1 > guid0); CHECK(guid1 >= guid0); CHECK(guid1 >= guid2); } void CheckStaticGuid(uint64_t guid, uint64_t expectedGuid) { CHECK(guid == expectedGuid); CHECK(guid >= MIN_STATIC_GUID); } void CheckDynamicGuid(uint64_t guid, uint64_t expectedGuid) { CHECK(guid == expectedGuid); CHECK(guid < MIN_STATIC_GUID); } TEST_CASE("StaticGuidGeneratorCollisionTest") { ProfilingGuidGenerator generator; std::set guids; for ( int i = 0; i < 100000; ++i ) { std::stringstream ss; ss << i; std::string str = ss.str(); ProfilingStaticGuid guid = generator.GenerateStaticId(str.c_str()); if (guids.find(guid) != guids.end()) { // If we're running on a 32bit system it is more likely to get a GUID clash over 1 million executions. // We can generally detect this when the GUID turns out to be MIN_STATIC_GUID. Output a warning // message rather than error in this case. if (guid == ProfilingGuid(MIN_STATIC_GUID)) { WARN("MIN_STATIC_GUID returned more than once from GenerateStaticId."); } else { FAIL(fmt::format("GUID collision occurred: {} -> {}", str, guid)); } break; } guids.insert(guid); } } TEST_CASE("StaticGuidGeneratorTest") { ProfilingGuidGenerator generator; ProfilingStaticGuid staticGuid0 = generator.GenerateStaticId("name"); CheckStaticGuid(staticGuid0, LabelsAndEventClasses::NAME_GUID); CHECK(staticGuid0 != generator.GenerateStaticId("Name")); ProfilingStaticGuid staticGuid1 = generator.GenerateStaticId("type"); CheckStaticGuid(staticGuid1, LabelsAndEventClasses::TYPE_GUID); CHECK(staticGuid1 != generator.GenerateStaticId("Type")); ProfilingStaticGuid staticGuid2 = generator.GenerateStaticId("index"); CheckStaticGuid(staticGuid2, LabelsAndEventClasses::INDEX_GUID); CHECK(staticGuid2 != generator.GenerateStaticId("Index")); } TEST_CASE("DynamicGuidGeneratorTest") { ProfilingGuidGenerator generator; for (uint64_t i = 0; i < 100; ++i) { ProfilingDynamicGuid guid = generator.NextGuid(); CheckDynamicGuid(guid, i); } } void GenerateProfilingGUID(ProfilingGuidGenerator& guidGenerator) { for (int i = 0; i < 1000; ++i) { guidGenerator.NextGuid(); } } TEST_CASE("ProfilingGuidThreadTest") { ProfilingGuidGenerator profilingGuidGenerator; std::vector threads; for (unsigned int i = 0; i < 3; ++i) { threads.push_back(std::thread(GenerateProfilingGUID, std::ref(profilingGuidGenerator))); } std::for_each(threads.begin(), threads.end(), [](std::thread& theThread) { theThread.join(); }); uint64_t guid = profilingGuidGenerator.NextGuid(); uint64_t expected = 3000U; CHECK(guid == expected); } }