ThrowTheSwitch / CMock

CMock - Mock/stub generator for C
http://throwtheswitch.org
MIT License
653 stars 269 forks source link

ReturnThruPtr always returns 0 when datatype is a float #410

Closed Gmann45 closed 3 months ago

Gmann45 commented 1 year ago

I am testing getter functions which return are supposed to return values from a database. When the datatype is anything other than a float, it returns the value as expected using the ReturnThruPtr functions. Below is the project file.

:project:
  :use_exceptions: FALSE
  :use_test_preprocessor: TRUE
  :use_auxiliary_dependencies: TRUE
  :build_root: build
#  :release_build: TRUE
  :test_file_prefix: test_
  :which_ceedling: gem
  :ceedling_version: 0.31.1
  :default_tasks:
    - test:all

:environment:

:extension:
  :executable: .out

:paths:
  :test:
    - +:test/**
    - -:test/support
  :source:
    - +:../../**

  :support:
    - test/support
  :libraries: []

:defines:
  # in order to add common defines:
  #  1) remove the trailing [] from the :common: section
  #  2) add entries to the :common: section (e.g. :test: has TEST defined)
  :common: &common_defines
    - EFR32MG12P432F1024IM48=1
    - TEST
    - LC_STATIC=/**/
  :test:
    - *common_defines
  :test_preprocess:
    - *common_defines

:unity:
  :defines:
    - UNITY_INCLUDE_FLOAT

:cmock:
  :mock_prefix: mock_
  :when_no_prototypes: :warn
  :enforce_strict_ordering: TRUE
  :plugins:
    - :ignore
    - :callback
    - :ignore_arg
    - :return_thru_ptr
    - :expect_any_args
    - :array
  :treat_as:
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8
  :includes:
    - application_properties.h
    - btl_interface_parser.h

:gcov:
  :utilities:
    - gcovr
  :reports:
    - HtmlDetailed

:tools:
  :test_compiler:
     :executable: gcc              #exists in system search path
     :name: 'test_compiler'
     :stderr_redirect: NONE
     :background_exec: NONE
     :optional: false
     :arguments:
        - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR    #expands to -I search paths
        - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE                #expands to -I search paths
        - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR                       #expands to all -D defined symbols
        - -DGNU_COMPILER
        - -g
        - -Wno-implicit-function-declaration
        - -c "${1}"                                                     #source code input file (Ruby method call param list sub)
        - -o "${2}"                                                     #object file output (Ruby method call param list sub)
        - -MMD
        - -MF "${4}"
# Ceedling defaults to using gcc for compiling, linking, etc.
# As [:tools] is blank, gcc will be used (so long as it's in your system path)
# See documentation to configure a given toolchain for use

# LIBRARIES
# These libraries are automatically injected into the build process. Those specified as
# common will be used in all types of builds. Otherwise, libraries can be injected in just
# tests or releases. These options are MERGED with the options in supplemental yaml files.
:libraries:
  :placement: :end
  :flag: "-l${1}"
  :path_flag: "-L ${1}"
  :system: []    # for example, you might list 'm' to grab the math library
  :test: []
  :release: []

:plugins:
  :load_paths:
    - "#{Ceedling.load_path}"
  :enabled:
    - stdout_pretty_tests_report
    - module_generator
    - gcov

Source file:

LC_STATIC float _le__get_le_float(le_key_t key)
{
    int rc = 0;
    float value = 0;

    rc = le_get(key, (void*)(&value), sizeof(value), CONVERT_NONE);
    if (rc < 0) {
        app_log_error("%s|Failed to read value\r\n", LE__MODULE_NAME);
        return 0;
    }

    return value;
}

Test file:

void test__le__get_le_float(void)
{
    float value = 67.0;
    le_key_t key = (le_key_t)(const uint32_t[]){32};

    le_get_ExpectAndReturn(key, NULL, sizeof(float), CONVERT_NONE, 0);
    le_get_IgnoreArg_data();
    le_get_ReturnMemThruPtr_data(&value, sizeof(value));
    TEST_ASSERT_EQUAL_FLOAT(value, _le__get_le_float(key));

}

Below is the test output:

Compiling test_module_light_engine_runner.c...
  Test: test__le__get_le_float
  At line (72): "Expected 67 Was 0"

--------------------
OVERALL TEST SUMMARY
--------------------
TESTED:  11
PASSED:  10
FAILED:   1
IGNORED:  0

---------------------
BUILD FAILURE SUMMARY
---------------------
Unit test failures.
Letme commented 1 year ago

Hm, I know its been some time and you have not received any reply, so I am taking a guess: have you tried treat_as: float: UINT32?

mvandervoord commented 1 year ago

You didn't provide the function prototype being mocked, but from the casting, I assume the pointer is a void? You're specifying the length, so it seems like it should have still copied the entire dereferenced float (byte by byte). I'll dig into `void` behavior a bit more and see if something seems amiss.

mvandervoord commented 3 months ago

Cannot reproduce. :(