Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion thread_notifications_lackey_dll/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ set(thread_notifications_lackey_dll_def_files

add_library(thread_notifications_lackey_dll SHARED ${thread_notifications_lackey_dll_c_files} ${thread_notifications_lackey_dll_h_files} ${thread_notifications_lackey_dll_def_files})
target_include_directories(thread_notifications_lackey_dll PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/inc>)
target_link_libraries(thread_notifications_lackey_dll c_logging_v2 c_pal)
target_link_libraries(thread_notifications_lackey_dll c_pal)

function(copy_thread_notifications_lackey_outputs target output_directory)
add_custom_command(TARGET ${target} POST_BUILD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

`DllMain` implements the DLL main entry point.

**SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [** If `fdwReason` is `DLL_PROCESS_ATTACH`: **]**

- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_006: [** `DllMain` shall call `logger_init` to initialize logging for the module. **]**
`DllMain` runs under the loader lock and, at process exit, other DLLs may have already been detached. For this reason it does not initialize or clean up anything (including logging) for process attach/detach.

- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_008: [** If `logger_init` fails, `DllMain` shall return FALSE. **]**
**SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [** If `fdwReason` is `DLL_PROCESS_ATTACH`: **]**

- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [** Otherwise, `DllMain` shall initialize the callback maintained by the module with `NULL` and return `TRUE`. **]**
- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [** `DllMain` shall return `TRUE`. **]**

**SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [** If `fdwReason` is `DLL_PROCESS_DETACH`: **]**

- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [** `DllMain` shall call `logger_deinit` and return `TRUE`. **]**
- **SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [** `DllMain` shall return `TRUE`. **]**

**SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_011: [** If `fdwReason` is `DLL_THREAD_ATTACH`: **]**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

#include "macro_utils/macro_utils.h"

#include "c_logging/logger.h"

#include "c_pal/interlocked.h"
#include "c_pal/ps_util.h"

Expand All @@ -23,7 +21,6 @@ int thread_notifications_lackey_dll_init_callback(THREAD_NOTIFICATIONS_LACKEY_DL
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_001: [ If thread_notification_cb is NULL, thread_notifications_lackey_set_callback shall fail and return a non-zero value. ]*/
if (thread_notifications_cb == NULL)
{
LogError("Invalid arguments: THREAD_NOTIFICATIONS_LACKEY_DLL_CALLBACK_FUNC thread_notifications_cb=%p", thread_notifications_cb);
result = MU_FAILURE;
}
else
Expand All @@ -33,7 +30,6 @@ int thread_notifications_lackey_dll_init_callback(THREAD_NOTIFICATIONS_LACKEY_DL
if (existing_callback != NULL)
{
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_003: [ If the callback was already initialized, thread_notifications_lackey_dll_init_callback shall fail and return a non-zero value. ] */
LogError("User error: callback already set to %p, thread_notifications_cb=%p", existing_callback, thread_notifications_cb);
result = MU_FAILURE;
}
else
Expand Down Expand Up @@ -61,6 +57,8 @@ BOOL WINAPI DllMain(
(void)hinstDLL;
(void)lpvReserved;

/* DllMain runs under the loader lock and, at process exit, after other DLLs may already have detached.
It therefore does no initialization or cleanup, only forwards thread notifications. */
switch (fdwReason)
{
default:
Expand All @@ -70,17 +68,8 @@ BOOL WINAPI DllMain(

/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [ If fdwReason is DLL_PROCESS_ATTACH: ]*/
case DLL_PROCESS_ATTACH:
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_006: [ DllMain shall call logger_init to initialize logging for the module. ]*/
if (logger_init() != 0)
{
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_008: [ If logger_init fails, DllMain shall return FALSE. ]*/
result = FALSE;
}
else
{
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ Otherwise, DllMain shall initialize the callback maintained by the module with NULL and return TRUE. ]*/
result = TRUE;
}
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ DllMain shall return TRUE. ]*/
result = TRUE;
break;

/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_011: [ If fdwReason is DLL_THREAD_ATTACH: ]*/
Expand Down Expand Up @@ -114,8 +103,7 @@ BOOL WINAPI DllMain(

/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [ If fdwReason is DLL_PROCESS_DETACH: ]*/
case DLL_PROCESS_DETACH:
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [DllMain shall call logger_deinit and return TRUE.]*/
logger_deinit();
/* Codes_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [ DllMain shall return TRUE. ]*/
result = TRUE;
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@

#include "thread_notif_lackey_dll_wo_init_ut_pch.h"

#include "umock_c/umock_c_ENABLE_MOCKS.h" // ============================== ENABLE_MOCKS
#undef ENABLE_MOCKS_DECL
#include "umock_c/umock_c_prod.h"
MOCK_FUNCTION_WITH_CODE(, int, mock_logger_init);
MOCK_FUNCTION_END(0)

MOCK_FUNCTION_WITH_CODE(, void, mock_logger_deinit);
MOCK_FUNCTION_END()
#include "umock_c/umock_c_DISABLE_MOCKS.h" // ============================== DISABLE_MOCKS

MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)

static void on_umock_c_error(UMOCK_C_ERROR_CODE error_code)
Expand All @@ -26,15 +16,10 @@ TEST_SUITE_INITIALIZE(suite_init)
{
ASSERT_ARE_EQUAL(int, 0, umock_c_init(on_umock_c_error), "umock_c_init failed");
ASSERT_ARE_EQUAL(int, 0, umocktypes_windows_register_types(), "umocktypes_windows_register_types failed");

REGISTER_GLOBAL_MOCK_FAIL_RETURN(mock_logger_init, MU_FAILURE);

ASSERT_ARE_EQUAL(int, 0, umock_c_negative_tests_init());
}

TEST_SUITE_CLEANUP(suite_cleanup)
{
umock_c_negative_tests_deinit();
umock_c_deinit();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@
#include "macro_utils/macro_utils.h"
#include "testrunnerswitcher.h"

#include "c_logging/logger.h"

#include "umock_c/umock_c.h"
#include "umock_c/umocktypes_windows.h"
#include "umock_c/umock_c_negative_tests.h"

#include "c_pal/interlocked.h"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.See LICENSE file in the project root for full license information.

#define logger_init mock_logger_init
#define logger_deinit mock_logger_deinit

// Since we mightbe running in an environment where a DllMain exists (like running under VS CppUnittest)
// we want to rename it to something else
#define DllMain DllMain_under_test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.See LICENSE file in the project root for full license information.

#define logger_init mock_logger_init
#define logger_deinit mock_logger_deinit

// Since we mightbe running in an environment where a DllMain exists (like running under VS CppUnittest)
// we want to rename it to something else
#define DllMain DllMain_under_test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ MOCK_FUNCTION_END()

MOCK_FUNCTION_WITH_CODE(, void, test_thread_notifications_callback_2, THREAD_NOTIFICATIONS_LACKEY_DLL_REASON, reason);
MOCK_FUNCTION_END()

MOCK_FUNCTION_WITH_CODE(, int, mock_logger_init);
MOCK_FUNCTION_END(0)

MOCK_FUNCTION_WITH_CODE(, void, mock_logger_deinit);
MOCK_FUNCTION_END()
#include "umock_c/umock_c_DISABLE_MOCKS.h" // ============================== DISABLE_MOCKS

static HMODULE test_module_handle = (HMODULE)0x42;
Expand All @@ -36,15 +30,11 @@ TEST_SUITE_INITIALIZE(suite_init)
ASSERT_ARE_EQUAL(int, 0, umock_c_init(on_umock_c_error), "umock_c_init failed");
ASSERT_ARE_EQUAL(int, 0, umocktypes_windows_register_types(), "umocktypes_windows_register_types failed");

REGISTER_GLOBAL_MOCK_FAIL_RETURN(mock_logger_init, MU_FAILURE);
REGISTER_TYPE(THREAD_NOTIFICATIONS_LACKEY_DLL_REASON, THREAD_NOTIFICATIONS_LACKEY_DLL_REASON);

ASSERT_ARE_EQUAL(int, 0, umock_c_negative_tests_init());
}

TEST_SUITE_CLEANUP(suite_cleanup)
{
umock_c_negative_tests_deinit();
umock_c_deinit();
}

Expand Down Expand Up @@ -135,12 +125,10 @@ TEST_FUNCTION(thread_notifications_lackey_dll_deinit_callback_when_not_initializ
/* DllMain */

/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_005: [ If fdwReason is DLL_PROCESS_ATTACH: ]*/
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_006: [ DllMain shall call logger_init to initialize logging for the module. ]*/
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ Otherwise, DllMain shall initialize the callback maintained by the module with NULL and return TRUE. ]*/
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_007: [ DllMain shall return TRUE. ]*/
TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_ATTACH_returns_TRUE)
{
// arrange
STRICT_EXPECTED_CALL(mock_logger_init());

// act
BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_ATTACH, NULL);
Expand All @@ -150,39 +138,29 @@ TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_ATTACH_return
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
}

/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_008: [ If logger_init fails, DllMain shall return FALSE. ]*/
TEST_FUNCTION(when_underlying_calls_fail_thread_notifications_lackey_DllMain_with_DLL_PROCESS_ATTACH_returns_FALSE)
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [ If fdwReason is DLL_PROCESS_DETACH: ]*/
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [ DllMain shall return TRUE. ]*/
TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_DETACH_on_dynamic_unload_returns_TRUE)
{
// arrange
STRICT_EXPECTED_CALL(mock_logger_init());

umock_c_negative_tests_snapshot();

for (size_t i = 0; i < umock_c_negative_tests_call_count(); i++)
{
if (umock_c_negative_tests_can_call_fail(i))
{
umock_c_negative_tests_reset();
umock_c_negative_tests_fail_call(i);

// act
BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_ATTACH, NULL);
// act
BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_DETACH, NULL);

// assert
ASSERT_IS_FALSE(result);
}
}
// assert
ASSERT_IS_TRUE(result);
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
}

/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_009: [ If fdwReason is DLL_PROCESS_DETACH: ]*/
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [DllMain shall call logger_deinit and return TRUE.]*/
TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_DETACH_returns_TRUE)
/* Tests_SRS_THREAD_NOTIFICATIONS_LACKEY_DLL_01_010: [ DllMain shall return TRUE. ]*/
TEST_FUNCTION(thread_notifications_lackey_DllMain_with_DLL_PROCESS_DETACH_during_process_termination_returns_TRUE)
{
// arrange
STRICT_EXPECTED_CALL(mock_logger_deinit());
int process_termination_context = 0;

// act
BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_DETACH, NULL);
BOOL result = DllMain_under_test(test_module_handle, DLL_PROCESS_DETACH, &process_termination_context);

// assert
ASSERT_IS_TRUE(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@
#include "macro_utils/macro_utils.h"
#include "testrunnerswitcher.h"

#include "c_logging/logger.h"

#include "umock_c/umock_c.h"
#include "umock_c/umocktypes_windows.h"
#include "umock_c/umock_c_negative_tests.h"

#include "c_pal/interlocked.h"

Expand Down
Loading