|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This file is provided under a dual BSD/GPLv2 license. When using or
|
|
Packit |
961e70 |
redistributing this file, you may do so under either license.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
GPL LICENSE SUMMARY
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Copyright(c) 2016 Intel Corporation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This program is free software; you can redistribute it and/or modify
|
|
Packit |
961e70 |
it under the terms of version 2 of the GNU General Public License as
|
|
Packit |
961e70 |
published by the Free Software Foundation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This program is distributed in the hope that it will be useful, but
|
|
Packit |
961e70 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
961e70 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
961e70 |
General Public License for more details.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Contact Information:
|
|
Packit |
961e70 |
Intel Corporation, www.intel.com
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
BSD LICENSE
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Copyright(c) 2016 Intel Corporation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
961e70 |
modification, are permitted provided that the following conditions
|
|
Packit |
961e70 |
are met:
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
* Redistributions of source code must retain the above copyright
|
|
Packit |
961e70 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
961e70 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit |
961e70 |
notice, this list of conditions and the following disclaimer in
|
|
Packit |
961e70 |
the documentation and/or other materials provided with the
|
|
Packit |
961e70 |
distribution.
|
|
Packit |
961e70 |
* Neither the name of Intel Corporation nor the names of its
|
|
Packit |
961e70 |
contributors may be used to endorse or promote products derived
|
|
Packit |
961e70 |
from this software without specific prior written permission.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
961e70 |
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
961e70 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
961e70 |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
961e70 |
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
961e70 |
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
961e70 |
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
961e70 |
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
961e70 |
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
961e70 |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
961e70 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#ifndef PSM2_MOCK_TESTING_H
|
|
Packit |
961e70 |
#define PSM2_MOCK_TESTING_H
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* PSM2_MOCK_TESTING being defined flips a couple of switches so that a
|
|
Packit |
961e70 |
* testable version of libpsm2.so is built. It'll make properly annotated
|
|
Packit |
961e70 |
* static functions be non-static, visible to the outside. Also, all mockable
|
|
Packit |
961e70 |
* functions will be replaced with function pointers which will originally
|
|
Packit |
961e70 |
* point to the actual implementation. However, those function pointers might
|
|
Packit |
961e70 |
* be reset by the test code, thus allowing for mocking selected PSM2 functions
|
|
Packit |
961e70 |
* for the purpose of the test.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* So far the following utilities have been introduced for enabling a
|
|
Packit |
961e70 |
* conditional compilation of the testable vs. production version of the library:
|
|
Packit |
961e70 |
* - ustatic: toggles function visibility
|
|
Packit |
961e70 |
* - MOCKABLE(): decorates function name so that it is visible after being mocked
|
|
Packit |
961e70 |
* - MOCK_DCL_EPILOGUE(): declares a function pointer which will be the seam
|
|
Packit |
961e70 |
* for mocking a function
|
|
Packit |
961e70 |
* - MOCK_DEF_EPILOGUE(): defines a function pointer which will be the seam
|
|
Packit |
961e70 |
* for mocking a function
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* If the declaration and definition of a static function @c foo reside in
|
|
Packit |
961e70 |
* different files, this would be the common use case:
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* @code
|
|
Packit |
961e70 |
* // somefile.c:
|
|
Packit |
961e70 |
* int MOCKABLE(foo)();
|
|
Packit |
961e70 |
* MOCK_DCL_EPILOGUE(foo);
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* // otherfile.c:
|
|
Packit |
961e70 |
* int MOCKABLE(foo)() {
|
|
Packit |
961e70 |
* printf("I am the original foo!\n");
|
|
Packit |
961e70 |
* }
|
|
Packit |
961e70 |
* MOCK_DEF_EPILOGUE(foo);
|
|
Packit |
961e70 |
* @endcode
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* If the production version of the library is being built, the following code
|
|
Packit |
961e70 |
* would result:
|
|
Packit |
961e70 |
* @code
|
|
Packit |
961e70 |
* // somefile.c:
|
|
Packit |
961e70 |
* int foo();
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* // otherfile.c:
|
|
Packit |
961e70 |
* int foo() {
|
|
Packit |
961e70 |
* printf("I am the original foo!\n");
|
|
Packit |
961e70 |
* }
|
|
Packit |
961e70 |
* @endcode
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* On the other hand, if a testable version of the libary is being build, it
|
|
Packit |
961e70 |
* would produce the following code:
|
|
Packit |
961e70 |
* @code
|
|
Packit |
961e70 |
* // somefile.c:
|
|
Packit |
961e70 |
* int foo_original_();
|
|
Packit |
961e70 |
* extern typeof(& foo_original_) foo;
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* // otherfile.c:
|
|
Packit |
961e70 |
* int foo_original_() {
|
|
Packit |
961e70 |
* printf("I am the original foo!\n");
|
|
Packit |
961e70 |
* }
|
|
Packit |
961e70 |
* typeof(& foo_original_) foo = foo_original_;
|
|
Packit |
961e70 |
* @endcode
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* If the function to be mocked is a static function residing in the header,
|
|
Packit |
961e70 |
* the following syntax would be used:
|
|
Packit |
961e70 |
* @code
|
|
Packit |
961e70 |
* // somefile.c:
|
|
Packit |
961e70 |
* ustatic int MOCKABLE(foo)() {
|
|
Packit |
961e70 |
* printf("I am the original foo!\n");
|
|
Packit |
961e70 |
* }
|
|
Packit |
961e70 |
* MOCK_DCL_EPILOGUE(foo);
|
|
Packit |
961e70 |
* MOCK_DEF_EPILOGUE(foo);
|
|
Packit |
961e70 |
* @endcode
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* If the production version of the library is being built, the following code
|
|
Packit |
961e70 |
* would result:
|
|
Packit |
961e70 |
* @code
|
|
Packit |
961e70 |
* // somefile.c:
|
|
Packit |
961e70 |
* static int foo() {
|
|
Packit |
961e70 |
* printf("I am the original foo!\n");
|
|
Packit |
961e70 |
* }
|
|
Packit |
961e70 |
* @endcode
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* Similarly, if a testable version of the libary is being build, it would
|
|
Packit |
961e70 |
* produce the following code:
|
|
Packit |
961e70 |
* @code
|
|
Packit |
961e70 |
* // somefile.c:
|
|
Packit |
961e70 |
* int foo_original_();
|
|
Packit |
961e70 |
* extern typeof(& foo_original_) foo;
|
|
Packit |
961e70 |
* typeof(& foo_original_) foo = foo_original_;
|
|
Packit |
961e70 |
* @endcode
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
#ifndef PSM2_MOCK_TESTING
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* If no testing is being done, ustatic resolves to regular "static" */
|
|
Packit |
961e70 |
#define ustatic static
|
|
Packit |
961e70 |
/* If no testing is being done, no indirection is introduced */
|
|
Packit |
961e70 |
#define MOCKABLE(fname) fname
|
|
Packit |
961e70 |
/* If no testing is being done, no declaration epilogue is needed */
|
|
Packit |
961e70 |
#define MOCK_DCL_EPILOGUE(fname)
|
|
Packit |
961e70 |
/* If no testing is being done, no definition epilogue is needed */
|
|
Packit |
961e70 |
#define MOCK_DEF_EPILOGUE(fname)
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#else /* ndef PSM2_MOCK_TESTING */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* For the testable version, all _ustatic_ function will NOT be static */
|
|
Packit |
961e70 |
#define ustatic
|
|
Packit |
961e70 |
/* TODO override inline directives in the same fashion as static */
|
|
Packit |
961e70 |
/* For the testable version, the actual implementation function is renamed */
|
|
Packit |
961e70 |
#define MOCKABLE(x) x ## _original_
|
|
Packit |
961e70 |
/* For the testable version, we declare the function pointer which will be the
|
|
Packit |
961e70 |
* point of indirection for calls to that function. It must be delared after
|
|
Packit |
961e70 |
* the declaration of the actual function happens.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
#define MOCK_DCL_EPILOGUE(x) extern typeof(& x ## _original_) x;
|
|
Packit |
961e70 |
/* For the testable version, we define the function pointer which will be the
|
|
Packit |
961e70 |
* point of indirection for calls to that function. It must be delared after
|
|
Packit |
961e70 |
* the definition of the actual function happens.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
#define MOCK_DEF_EPILOGUE(x) typeof(& x ## _original_) x = x ## _original_;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#endif /* ndef PSM2_MOCK_TESTING */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#endif /* PSM2_MOCK_TESTING_H */
|
|
Packit |
961e70 |
|