diff --git a/interfaces/inc/c_pal/uuid.h b/interfaces/inc/c_pal/uuid.h index 19955fb..3def7eb 100644 --- a/interfaces/inc/c_pal/uuid.h +++ b/interfaces/inc/c_pal/uuid.h @@ -5,12 +5,14 @@ #define UUID_H #include +#include #ifdef WIN32 #include "windows.h" #endif -typedef unsigned char UUID_T[16]; /*introduces UUID_T as "array of 16 bytes"*/ +#define UUID_T_LENGTH 16 +typedef unsigned char UUID_T[UUID_T_LENGTH]; /*introduces UUID_T as "array of 16 bytes"*/ #include "macro_utils/macro_utils.h" #include "umock_c/umock_c_prod.h" @@ -19,6 +21,7 @@ extern "C" { #endif MOCKABLE_FUNCTION(, int, uuid_produce, UUID_T, destination); + MOCKABLE_FUNCTION(, bool, is_uuid_nil, const UUID_T, uuid_value); #ifdef WIN32 /*some functions, format specifiers only exists in Windows realm*/ MOCKABLE_FUNCTION(, int, uuid_from_GUID, UUID_T, destination, const GUID*, source); diff --git a/linux/devdoc/uuid_linux_requirements.md b/linux/devdoc/uuid_linux_requirements.md index a194670..6b03753 100644 --- a/linux/devdoc/uuid_linux_requirements.md +++ b/linux/devdoc/uuid_linux_requirements.md @@ -1,6 +1,7 @@ # uuid requirements ## Overview + The uuid module generates unique IDs. ## References @@ -8,10 +9,12 @@ The uuid module generates unique IDs. [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) ## Exposed API + ```C typedef unsigned char UUID_T[16]; /*introduces UUID_T as "array of 16 bytes"*/ MOCKABLE_FUNCTION(, int, uuid_produce, UUID_T, destination); +MOCKABLE_FUNCTION(, bool, is_uuid_nil, const UUID_T, uuid_value); /* These 2 strings can be conveniently used directly in printf-like statements Notice that PRI_UUID has to be used like any other print format specifier, meaning it @@ -28,10 +31,10 @@ MOCKABLE_FUNCTION(, int, uuid_produce, UUID_T, destination); ((uuid) == NULL) ? 0 : (uuid)[4], ((uuid) == NULL) ? 0 : (uuid)[5], ((uuid) == NULL) ? 0 : (uuid)[6], ((uuid) == NULL) ? 0 : (uuid)[7], \ ((uuid) == NULL) ? 0 : (uuid)[8], ((uuid) == NULL) ? 0 : (uuid)[9], ((uuid) == NULL) ? 0 : (uuid)[10], ((uuid) == NULL) ? 0 : (uuid)[11], \ ((uuid) == NULL) ? 0 : (uuid)[12], ((uuid) == NULL) ? 0 : (uuid)[13], ((uuid) == NULL) ? 0 : (uuid)[14], ((uuid) == NULL) ? 0 : (uuid)[15] \ - - ``` -### uuid_produce + +### uuid_produce + ```C MOCKABLE_FUNCTION(, int, uuid_produce, UUID_T, destination); ``` @@ -42,4 +45,18 @@ MOCKABLE_FUNCTION(, int, uuid_produce, UUID_T, destination); **SRS_UUID_LINUX_02_002: [** `uuid_produce` shall call `uuid_generate` to generate a `UUID`. **]** -**SRS_UUID_LINUX_02_004: [** `uuid_produce` shall succeed and return 0. **]** \ No newline at end of file +**SRS_UUID_LINUX_02_004: [** `uuid_produce` shall succeed and return 0. **]** + +### is_uuid_nil + +```C +MOCKABLE_FUNCTION(, bool, is_uuid_nil, const UUID_T, uuid_value); +``` + +`is_uuid_nil` determined if the specified uuid `uuid_value` is `NULL`. + +**SRS_UUID_LINUX_11_001: [** if `uuid_value` is `NULL` then `is_uuid_nil` shall fail and return `true`. **]** + +**SRS_UUID_LINUX_11_002: [** If all the values of `is_uuid_nil` are `0` then `is_uuid_nil` shall return `true`. **]** + +**SRS_UUID_LINUX_11_003: [** If any the values of `is_uuid_nil` are not `0` then `is_uuid_nil` shall return `false`. **]** diff --git a/linux/linux_reals/real_uuid.h b/linux/linux_reals/real_uuid.h index e38abc6..755cfe2 100644 --- a/linux/linux_reals/real_uuid.h +++ b/linux/linux_reals/real_uuid.h @@ -3,13 +3,16 @@ #ifndef REAL_UUID_H #define REAL_UUID_H +#include + #include "macro_utils/macro_utils.h" #define R2(X) REGISTER_GLOBAL_MOCK_HOOK(X, real_##X); -#define REGISTER_UUID_GLOBAL_MOCK_HOOK() \ - MU_FOR_EACH_1(R2, \ - uuid_produce \ +#define REGISTER_UUID_GLOBAL_MOCK_HOOK() \ + MU_FOR_EACH_1(R2, \ + uuid_produce, \ + is_uuid_nil \ ) #ifdef __cplusplus @@ -17,6 +20,7 @@ extern "C" { #endif int real_uuid_produce(UUID_T destination); + bool real_is_uuid_nil(const UUID_T uuid_value); #ifdef __cplusplus } diff --git a/linux/linux_reals/real_uuid_renames.h b/linux/linux_reals/real_uuid_renames.h index b3897f9..5b94e64 100644 --- a/linux/linux_reals/real_uuid_renames.h +++ b/linux/linux_reals/real_uuid_renames.h @@ -1,4 +1,4 @@ // Copyright (c) Microsoft. All rights reserved. #define uuid_produce real_uuid_produce - +#define is_uuid_nil real_is_uuid_nil diff --git a/linux/src/uuid_linux.c b/linux/src/uuid_linux.c index 2d8cc28..69005ad 100644 --- a/linux/src/uuid_linux.c +++ b/linux/src/uuid_linux.c @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include +#include #include @@ -35,3 +36,45 @@ int uuid_produce(UUID_T destination) } return result; } + +bool is_uuid_nil(const UUID_T uuid_value) +{ + bool result; + // Codes_SRS_UUID_LINUX_11_001: [ if uuid_value is NULL then is_uuid_nil shall fail and return true. ] + if (uuid_value == NULL) + { + LogError("invalid argument UUID_T uuid_value=%p", uuid_value); + result = true; + } + else + { + if ( + uuid_value[0] == 0 && + uuid_value[1] == 0 && + uuid_value[2] == 0 && + uuid_value[3] == 0 && + uuid_value[4] == 0 && + uuid_value[5] == 0 && + uuid_value[6] == 0 && + uuid_value[7] == 0 && + uuid_value[8] == 0 && + uuid_value[9] == 0 && + uuid_value[10] == 0 && + uuid_value[11] == 0 && + uuid_value[12] == 0 && + uuid_value[13] == 0 && + uuid_value[14] == 0 && + uuid_value[15] == 0 + ) + { + // Codes_SRS_UUID_LINUX_11_002: [ If all the values of is_uuid_nil are 0 then is_uuid_nil shall return true. ] + result = true; + } + else + { + // Codes_SRS_UUID_LINUX_11_003: [ If any the values of is_uuid_nil are not 0 then is_uuid_nil shall return false. ] + result = false; + } + } + return result; +} diff --git a/linux/tests/uuid_linux_ut/uuid_linux_ut.c b/linux/tests/uuid_linux_ut/uuid_linux_ut.c index 32c7150..b5d0ecf 100644 --- a/linux/tests/uuid_linux_ut/uuid_linux_ut.c +++ b/linux/tests/uuid_linux_ut/uuid_linux_ut.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -119,7 +120,6 @@ static int umock_copy_uuid_t(uuid_t* destination, const uuid_t* source) static void umock_free_uuid_t(uuid_t* value) { - } BEGIN_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE) @@ -131,7 +131,6 @@ TEST_SUITE_INITIALIZE(suite_init) REGISTER_UMOCK_VALUE_TYPE(uuid_t); REGISTER_GLOBAL_MOCK_HOOK(mocked_uuid_generate, hook_uuid_generate); - } TEST_SUITE_CLEANUP(suite_cleanup) @@ -195,8 +194,50 @@ TEST_FUNCTION(uuid_produce_succeeds) ASSERT_ARE_EQUAL(uint8_t, TEST_DATA_13, u[13]); ASSERT_ARE_EQUAL(uint8_t, TEST_DATA_14, u[14]); ASSERT_ARE_EQUAL(uint8_t, TEST_DATA_15, u[15]); - } +// is_uuid_nil + +// Tests_SRS_UUID_LINUX_11_001: [ if uuid_value is NULL then is_uuid_nil shall fail and return true. ] +TEST_FUNCTION(is_uuid_nil_uuid_is_NULL) +{ + ///arrange + + ///act + bool result = is_uuid_nil(NULL); + + ///assert + ASSERT_IS_TRUE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} + +// Tests_SRS_UUID_LINUX_11_002: [ If all the values of is_uuid_nil are 0 then is_uuid_nil shall return true. ] +TEST_FUNCTION(is_uuid_nil_on_valid_uuid) +{ + ///arrange + UUID_T valid_uuid; + hook_uuid_generate(valid_uuid); + + ///act + bool result = is_uuid_nil(valid_uuid); + + ///assert + ASSERT_IS_FALSE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} + +// Tests_SRS_UUID_LINUX_11_003: [ If any the values of is_uuid_nil are not 0 then is_uuid_nil shall return false. ] +TEST_FUNCTION(is_uuid_nil_on_nil_uuid) +{ + ///arrange + UUID_T valid_uuid = { 0 }; + + ///act + bool result = is_uuid_nil(valid_uuid); + + ///assert + ASSERT_IS_TRUE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE) diff --git a/win32/devdoc/uuid_win32_requirements.md b/win32/devdoc/uuid_win32_requirements.md index 1060e0f..23a5617 100644 --- a/win32/devdoc/uuid_win32_requirements.md +++ b/win32/devdoc/uuid_win32_requirements.md @@ -12,6 +12,7 @@ The uuid module generates unique IDs. ```c typedef unsigned char UUID_T[16]; /*introduces UUID_T as "array of 16 bytes"*/ MOCKABLE_FUNCTION(, int, uuid_produce, UUID_T, destination); + MOCKABLE_FUNCTION(, bool, is_uuid_nil, const UUID_T, uuid_value); #ifdef WIN32 /*some functions only exists in Windows realm*/ MOCKABLE_FUNCTION(, int, uuid_from_GUID, UUID_T, destination, const GUID*, source); @@ -75,4 +76,18 @@ MOCKABLE_FUNCTION(, int, uuid_from_GUID, UUID_T, destination, const GUID*, sourc **SRS_UUID_WIN32_02_010: [** If `source` is `NULL` then `GUID_from_uuid` shall fail and return a non-zero value. **]** -**SRS_UUID_WIN32_02_011: [** `GUID_from_uuid` shall convert `UUID_T` to `GUID`, succeed and return 0. **]** \ No newline at end of file +**SRS_UUID_WIN32_02_011: [** `GUID_from_uuid` shall convert `UUID_T` to `GUID`, succeed and return 0. **]** + +### is_uuid_nil + +```C +MOCKABLE_FUNCTION(, bool, is_uuid_nil, const UUID_T, uuid_value); +``` + +`is_uuid_nil` determined if the specified uuid `uuid_value` is `NULL`. + +**SRS_UUID_WIN32_11_001: [** if `uuid_value` is `NULL` then `is_uuid_nil` shall fail and return `true`. **]** + +**SRS_UUID_WIN32_11_002: [** If all the values of `is_uuid_nil` are `0` then `is_uuid_nil` shall return `true`. **]** + +**SRS_UUID_WIN32_11_003: [** If any the values of `is_uuid_nil` are not `0` then `is_uuid_nil` shall return `false`. **]** diff --git a/win32/reals/real_uuid.h b/win32/reals/real_uuid.h index d426782..419ad77 100644 --- a/win32/reals/real_uuid.h +++ b/win32/reals/real_uuid.h @@ -3,13 +3,16 @@ #ifndef REAL_UUID_H #define REAL_UUID_H +#include + #include "macro_utils/macro_utils.h" #define R2(X) REGISTER_GLOBAL_MOCK_HOOK(X, real_##X); -#define REGISTER_UUID_GLOBAL_MOCK_HOOK() \ - MU_FOR_EACH_1(R2, \ - uuid_produce \ +#define REGISTER_UUID_GLOBAL_MOCK_HOOK() \ + MU_FOR_EACH_1(R2, \ + uuid_produce, \ + is_uuid_nil \ ) #ifdef __cplusplus @@ -17,6 +20,7 @@ extern "C" { #endif int real_uuid_produce(UUID_T destination); + bool real_is_uuid_nil(const UUID_T uuid_value); #ifdef WIN32 /*some functions only exists in Windows realm*/ int real_uuid_from_GUID(UUID_T destination, const GUID* source); diff --git a/win32/reals/real_uuid_renames.h b/win32/reals/real_uuid_renames.h index 92fcac1..c47f040 100644 --- a/win32/reals/real_uuid_renames.h +++ b/win32/reals/real_uuid_renames.h @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. #define uuid_produce real_uuid_produce +#define is_uuid_nil real_is_uuid_nil #ifdef WIN32 /*some functions only exists in Windows realm*/ #define uuid_from_GUID real_uuid_from_GUID diff --git a/win32/src/uuid_win32.c b/win32/src/uuid_win32.c index 0b90270..10f464d 100644 --- a/win32/src/uuid_win32.c +++ b/win32/src/uuid_win32.c @@ -1,6 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +#include + #include "rpc.h" #include "macro_utils/macro_utils.h" @@ -128,3 +130,45 @@ int GUID_from_uuid(GUID* destination, const UUID_T source) } return result; } + +bool is_uuid_nil(const UUID_T uuid_value) +{ + bool result; + // Codes_SRS_UUID_WIN32_11_001: [ if uuid_value is NULL then is_uuid_nil shall fail and return true. ] + if (uuid_value == NULL) + { + LogError("invalid argument UUID_T uuid_value=%p", uuid_value); + result = true; + } + else + { + if ( + uuid_value[0] == 0 && + uuid_value[1] == 0 && + uuid_value[2] == 0 && + uuid_value[3] == 0 && + uuid_value[4] == 0 && + uuid_value[5] == 0 && + uuid_value[6] == 0 && + uuid_value[7] == 0 && + uuid_value[8] == 0 && + uuid_value[9] == 0 && + uuid_value[10] == 0 && + uuid_value[11] == 0 && + uuid_value[12] == 0 && + uuid_value[13] == 0 && + uuid_value[14] == 0 && + uuid_value[15] == 0 + ) + { + // Codes_SRS_UUID_WIN32_11_002: [ If all the values of is_uuid_nil are 0 then is_uuid_nil shall return true. ] + result = true; + } + else + { + // Codes_SRS_UUID_WIN32_11_003: [ If any the values of is_uuid_nil are not 0 then is_uuid_nil shall return false. ] + result = false; + } + } + return result; +} diff --git a/win32/tests/uuid_win32_ut/uuid_win32_ut.c b/win32/tests/uuid_win32_ut/uuid_win32_ut.c index b697e95..85bac6e 100644 --- a/win32/tests/uuid_win32_ut/uuid_win32_ut.c +++ b/win32/tests/uuid_win32_ut/uuid_win32_ut.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "rpc.h" @@ -138,7 +139,6 @@ TEST_FUNCTION(uuid_produce_succeeds_1) /*when it returns default RPC_S_OK*/ ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); } - /*Tests_SRS_UUID_WIN32_02_002: [ uuid_produce shall call UuidCreate to generate a UUID. ]*/ /*Tests_SRS_UUID_WIN32_02_003: [ uuid_produce shall copy the generated UUID's bytes in destination. ]*/ /*Tests_SRS_UUID_WIN32_02_004: [ uuid_produce shall succeed and return 0. ]*/ @@ -318,7 +318,75 @@ TEST_FUNCTION(GUID_from_uuid_succeeds) ASSERT_IS_TRUE(TEST_DATA_3 == destination.Data3); ASSERT_IS_TRUE(0 == memcmp(source+8, destination.Data4, 8)); ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} +// is_uuid_nil + +// Tests_SRS_UUID_WIN32_11_001: [ if uuid_value is NULL then is_uuid_nil shall fail and return true. ] +TEST_FUNCTION(is_uuid_nil_uuid_is_NULL) +{ + ///arrange + + ///act + bool result = is_uuid_nil(NULL); + + ///assert + ASSERT_IS_TRUE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} + +// Tests_SRS_UUID_WIN32_11_002: [ If all the values of is_uuid_nil are 0 then is_uuid_nil shall return true. ] +TEST_FUNCTION(is_uuid_nil_on_valid_uuid) +{ + ///arrange + UUID_T valid_uuid = { + ((TEST_DATA_1 >> 24) & 0xFF), + ((TEST_DATA_1 >> 16) & 0xFF), + ((TEST_DATA_1 >> 8) & 0xFF), + ((TEST_DATA_1) & 0xFF), + ((TEST_DATA_2 >> 8) & 0xFF), + ((TEST_DATA_2) & 0xFF), + ((TEST_DATA_3 >> 8) & 0xFF), + ((TEST_DATA_3) & 0xFF), + TEST_DATA_4_0, TEST_DATA_4_1, TEST_DATA_4_2, TEST_DATA_4_3, TEST_DATA_4_4, TEST_DATA_4_5, TEST_DATA_4_6, TEST_DATA_4_7 }; + + ///act + bool result = is_uuid_nil(valid_uuid); + + ///assert + ASSERT_IS_FALSE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} + +// Tests_SRS_UUID_WIN32_11_003: [ If any the values of is_uuid_nil are not 0 then is_uuid_nil shall return false. ] +TEST_FUNCTION(is_uuid_nil_on_nil_uuid) +{ + ///arrange + UUID_T valid_uuid = { 0 }; + + ///act + bool result = is_uuid_nil(valid_uuid); + + ///assert + ASSERT_IS_TRUE(result); + ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls()); +} + +TEST_FUNCTION(is_uuid_nil_on_individual_valid_uuid) +{ + ///arrange + for (size_t index = 0; index < 16; index++) + { + UUID_T valid_uuid = { 0 }; + + valid_uuid[index] = 0x2; + + ///act + bool result = is_uuid_nil(valid_uuid); + + ///assert + ASSERT_IS_FALSE(result); + } } END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)