Giter Site home page Giter Site logo

smalti / gmock-win32 Goto Github PK

View Code? Open in Web Editor NEW
4.0 1.0 3.0 95 KB

The library implements gmock functionality for global win32 functions.

Home Page: https://smalti.github.io/gmock-win32/

License: MIT License

C++ 100.00%
gmock mock win32 cpp test win32api library mocking mocking-library cpp-lib

gmock-win32's People

Contributors

alex0vsky avatar gtbx avatar smalti avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

gmock-win32's Issues

Very late report for a missed expectation

Unexpected behavior

  • Unexpected behavior after completing a single test..
  • Double "Reporting" on single API hook.

Description

I’m writing about two at once, because one follows from the other and it’s difficult to separate them.

Unexpected behavior after completing a single test..

Leads to: it is impossible to detect an error/failure after the completion of a particular test, there is no process termination error code to be processed, and there are also no error records in the xml/json output file.

Double "Reporting" on single API hook.

Leads to: additional reporting of false expectations.


Additional context

1

After complete single test

Expected Behavior 1

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from verifyAndClear_unexpectedBehavior_reportAfterTests
[ RUN      ] verifyAndClear_unexpectedBehavior_reportAfterTests.gmockWin32
C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\expectedButFail.cpp(13): error: Actual function call count doesn't match EXPECT_CALL(mock_module_GetActiveWindow::instance(), GetActiveWindow())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] verifyAndClear_unexpectedBehavior_reportAfterTests.gmockWin32 (2 ms)
[----------] 1 test from verifyAndClear_unexpectedBehavior_reportAfterTests (5 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (11 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] verifyAndClear_unexpectedBehavior_reportAfterTests.gmockWin32

 1 FAILED TEST

C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\bin\x64\Debug\expectedButFail.exe (process 5816) exited with code 1.
Press any key to close this window . . .

Note: (process Xxx) exited with code 1 !

Actual Behavior 1

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from verifyAndClear_unexpectedBehavior_reportAfterTests
[ RUN      ] verifyAndClear_unexpectedBehavior_reportAfterTests.gmockWin32
[       OK ] verifyAndClear_unexpectedBehavior_reportAfterTests.gmockWin32 (0 ms)
[----------] 1 test from verifyAndClear_unexpectedBehavior_reportAfterTests (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (3 ms total)
[  PASSED  ] 1 test.
C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\expectedButFail.cpp(13): error: Actual function call count doesn't match EXPECT_CALL(mock_module_GetActiveWindow::instance(), GetActiveWindow())...
         Expected: to be called once
           Actual: never called - unsatisfied and active

C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\bin\x64\Debug\expectedButFail.exe (process 7920) exited with code 0.
Press any key to close this window . . .

Note: (process Xxx) exited with code 0 !.

Steps to Reproduce the Problem 1

1.1. Source code
expectedButFail.cpp

#pragma comment( lib, "kernel32" )
#pragma comment( lib, "user32" )
#include "..\src\gtest\gtest-all.cc"
#include "..\src\gmock\gmock-all.cc"
#include "..\..\src\gmock-win32.cpp"
#include "..\include\gtest\gtest-spi.h" 
int main(int argc, char **argv) {
	const gmock_win32::init_scope gmockWin32{ };
	return ::testing::InitGoogleTest( &argc, argv ), RUN_ALL_TESTS( );
}
MOCK_CDECL_FUNC( HWND, GetCapture );
TEST(verifyAndClear_unexpectedBehavior_reportAfterTests, gmockWin32) { 
	EXPECT_MODULE_FUNC_CALL( GetCapture );
//	bool result = true;
//	EXPECT_NONFATAL_FAILURE( 
//			VERIFY_AND_CLEAR_MODULE_FUNC( GetCapture )
//			, "Actual function call count doesn't match EXPECT_CALL(mock_module_GetCapture::instance(), GetCapture())..."
//		);
//	ASSERT_TRUE( result );
}

2.1. Building in cmd line

Include path to googletest(NuGet) and current project

set googletest=googletest\gmock\include
set gmock-win32=gmock-win32\include

Building for cl from Msvc 2019

cl expectedButFail.cpp /EHsc /I"%googletest%" /I"%gmock-win32%"

3.1. Run expectedButFail.exe

2

Double report

Expected Behavior 2

[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from verifyAndClear_unexpectedBehavior_doubleReport
[ RUN      ] verifyAndClear_unexpectedBehavior_doubleReport.addingToInternals
C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\verifyAndClear.cpp(13): error: Actual function call count doesn't match EXPECT_CALL(mock_module_GetACP::instance(), GetACP())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] verifyAndClear_unexpectedBehavior_doubleReport.addingToInternals (1 ms)
[ RUN      ] verifyAndClear_unexpectedBehavior_doubleReport.forCurrentGetACP_and_previousGetACP
C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\verifyAndClear.cpp(17): error: Actual function call count doesn't match EXPECT_CALL(mock_module_GetACP::instance(), GetACP())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] verifyAndClear_unexpectedBehavior_doubleReport.forCurrentGetACP_and_previousGetACP (0 ms)

Actual Behavior 2

[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from verifyAndClear_unexpectedBehavior_doubleReport
[ RUN      ] verifyAndClear_unexpectedBehavior_doubleReport.addingToInternals
[       OK ] verifyAndClear_unexpectedBehavior_doubleReport.addingToInternals (1 ms)
[ RUN      ] verifyAndClear_unexpectedBehavior_doubleReport.forCurrentGetACP_and_previousGetACP
C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\doubleReport.cpp(13): error: Actual function call count doesn't match EXPECT_CALL(mock_module_GetACP::instance(), GetACP())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
C:\Prj\_PullRequest\gmock-win32\_changes\verifyAndClear\doubleReport.cpp(17): error: Actual function call count doesn't match EXPECT_CALL(mock_module_GetACP::instance(), GetACP())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] verifyAndClear_unexpectedBehavior_doubleReport.forCurrentGetACP_and_previousGetACP (1 ms)

Steps to Reproduce the Problem 2

2.1. Source code
doubleReport.cpp

#pragma comment( lib, "kernel32" )
#pragma comment( lib, "user32" )
#include "..\src\gtest\gtest-all.cc"
#include "..\src\gmock\gmock-all.cc"
#include "..\..\src\gmock-win32.cpp"
#include "..\include\gtest\gtest-spi.h" 
int main(int argc, char **argv) {
	const gmock_win32::init_scope gmockWin32{ };
	return ::testing::InitGoogleTest( &argc, argv ), RUN_ALL_TESTS( );
}
MOCK_MODULE_FUNC( UINT, GetACP );
TEST(verifyAndClear_unexpectedBehavior_doubleReport, addingToInternals) { 
	EXPECT_MODULE_FUNC_CALL( GetACP );
	//VERIFY_AND_CLEAR_MODULE_FUNC( GetACP );
}
TEST(verifyAndClear_unexpectedBehavior_doubleReport, forCurrentGetACP_and_previousGetACP) { 
	EXPECT_MODULE_FUNC_CALL( GetACP );
	VERIFY_AND_CLEAR_MODULE_FUNC( GetACP );
}

2.2. Building in cmd line

Include path to googletest(NuGet) and current project

set googletest=googletest\gmock\include
set gmock-win32=gmock-win32\include

Building for cl from Msvc 2019

cl doubleReport.cpp /EHsc /I"%googletest%" /I"%gmock-win32%"

3.2. Run doubleReport.exe

Specifications

  • Version: latest
  • Platform: Windows
  • Subsystem: Visual Studio Community 2019

Adding CI from GitHubActions for tests

Conversation from #23:

Can I do checks in CI from GitHubAction? I understand this a little.

Yes, it's a good idea, we require CI for writing and executing tests.

About writing tests, from the top of my head:

  1. EXPECT_MODULE_FUNC_CALL and ON_MODULE_FUNC_CALL
    for the WinApi function starting from zero arguments up to 12 from for example CreateWindowExA().
  2. Handling initialization errors
  3. Handling hook errors, set and unset
  4. GTest conflict workaround/bypass
  5. Others such as RESTORE_MODULE_FUNC and VERIFY_AND_CLEAR_MODULE_FUNC_EXPECTATIONS

It would be enough?

Deadlock in the setup of expectations for the mocked `GetCurrentThreadId` function

This issue occurred during the instantiation of a static NiceMock object, which, in turn, invokes the GetCurrentThreadId function (referenced in testing::internal::Mutex::Lock). Environment: GoogleTest 1.14.0, Win10.

Minimal sample to reproduce:

#include <gmock/gmock.h>
#include <gmock-win32.h>

using namespace std;
using namespace testing;
	
MOCK_STDCALL_FUNC(DWORD, GetCurrentThreadId);

int main(int argc, char* argv[])
{
    ON_MODULE_FUNC_CALL(GetCurrentThreadId).WillByDefault(Return(1));
    return 0;
}

Support from additional windows library

Hi,
I am a big fan of this library and it has saved me heaps of time. However, I am now trying other functions from the WIN32 which are not in the windows.h library. For example: physicalmonitorenumerationapi.h.

Is there already a process to support this type of library?

Thanks

Macro expansion for WinApi, proxied when implementing a 64-bit architecture

Using GetWindowLongPtr to get a stored pointer is quite common.

Additional context

From <WinUser.h> if !UNICODE

WINUSERAPI
LONG
WINAPI
GetWindowLongA(
    _In_ HWND hWnd,
    _In_ int nIndex);
#ifdef _WIN64
WINUSERAPI
LONG_PTR
WINAPI
GetWindowLongPtrA(
    _In_ HWND hWnd,
    _In_ int nIndex);
#    define GetWindowLongPtr  GetWindowLongPtrA
#else  /* _WIN64 */
#    define GetWindowLongPtrA   GetWindowLongA
#endif /* _WIN64 */

Along with this: wrong to use GetWindowLongA() on x64, pointer will be 32bit.


Expected Behavior

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from expander_x86_64_macro
[ RUN      ] expander_x86_64_macro.test
[       OK ] expander_x86_64_macro.test (10 ms)
[----------] 1 test from expander_x86_64_macro (13 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (16 ms total)
[  PASSED  ] 1 test.

Actual Behavior

Compile error issue

expander_x86_64_macro.cpp(12,2): error C3861: 'patchModuleFunc_GetWindowLongPtrA': identifier not found
expander_x86_64_macro.cpp(12,2): error C2653: 'mock_module_GetWindowLongPtrA': is not a class or namespace name
expander_x86_64_macro.cpp(12,2): error C3861: 'instance': identifier not found
expander_x86_64_macro.cpp(12,2): error C2672: 'gmock_win32::detail::make_proxy': no matching overloaded function found

Steps to Reproduce

  1. Source code

expander_x86_64_macro.cpp

#include "gtest\gtest.h"
#include "gmock\gmock.h"
#include "gmock-win32.h"
#include <Windows.h>

// in x86 to `mock_module_GetWindowLongA`
// in x64 to `mock_module_GetWindowLongPtrA`
MOCK_STDCALL_FUNC( LONG_PTR, GetWindowLongPtrA, HWND hWnd, int nIndex );
TEST(expander_x86_64_macro, test) {
	// in x86 to `patchModuleFunc_GetWindowLongPtrA`
	// in x64 to `patchModuleFunc_GetWindowLongPtrA`
	EXPECT_MODULE_FUNC_CALL( GetWindowLongPtrA, 0, 0 );
	GetWindowLongPtrA( 0, 0 );
}
  1. Building in cmd line

Include path to googletest and current project

set googletest=googletest\gmock\include
set gmock-win32=gmock-win32\include

Building launch for x86

cl expander_x86_64_macro.cpp /EHsc /I"%googletest%" /I"%gmock-win32%"
  1. Run expander_x86_64_macro.exe

Specifications

  • Version: latest
  • Platform: Windows
  • Subsystem: Visual Studio Community 2019

Add support for Windows ApiSet DLL redirections

The current approach to IAT patching lacks support for certain system functions, such as the RoInitialize function (see the Windows API set redirection mechanism). We need to fix our IAT patching approach to support functions that have been redirected to other DLLs.

Multiple *.cpp supporting

Often tests are located in several *.cpp files, but are compiled into one *.exe.


Expected Behavior

[==========] Running 2 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 1 test from Bar
[ RUN      ] Bar.test
[       OK ] Bar.test (2 ms)
[----------] 1 test from Bar (7 ms total)

[----------] 1 test from Foo
[ RUN      ] Foo.test
[       OK ] Foo.test (1 ms)
[----------] 1 test from Foo (2 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 2 test suites ran. (25 ms total)
[  PASSED  ] 2 tests.

Actual Behavior

Link error issue

Foo.obj : error LNK2005: "public: static void * mock_module_GetACP::oldFn_" (?oldFn_@mock_module_GetACP@@2PEAXEA) already defined in Bar.obj
multiply_defined.exe : fatal error LNK1169: one or more multiply defined symbols found

Steps to Reproduce

  1. Two *.cpp files with tests and main file

Foo.cpp

#include "gtest\gtest.h"
#include "gmock\gmock.h"
#include "gmock-win32.h"
#include <Windows.h>
MOCK_STDCALL_FUNC(UINT, GetACP);
TEST(Foo, test) { 
	EXPECT_MODULE_FUNC_CALL( GetACP );
	GetACP( );
}

Bar.cpp

#include "gtest\gtest.h"
#include "gmock\gmock.h"
#include "gmock-win32.h"
#include <Windows.h>
MOCK_STDCALL_FUNC(UINT, GetACP);
TEST(Bar, test) { 
	EXPECT_MODULE_FUNC_CALL( GetACP );
	GetACP( );
}

multiply_defined.cpp

#include "..\src\gtest\src\gtest_main.cc"
#include "..\src\gtest\gtest-all.cc"
#include "..\src\gmock\gmock-all.cc"
#include "..\..\src\gmock-win32.cpp"
  1. Building in cmd line

Include path to googletest and current project

set googletest=googletest\gmock\include
set gmock-win32=gmock-win32\include

Building launch

cl /c Foo.cpp /EHsc /I"%googletest%" /I"%gmock-win32%"
cl /c Bar.cpp /EHsc /I"%googletest%" /I"%gmock-win32%"
cl /c multiply_defined.cpp /EHsc /I"%googletest%" /I"%gmock-win32%"
link multiply_defined Bar Foo
  1. Run multiply_defined.exe

Specifications

  • Version: latest
  • Platform: Windows
  • Subsystem: Visual Studio Community 2019

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.