// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include #include "umock_c/umock_c_negative_tests.h" #include "umock_c/umock_c.h" #include "umock_c/umockcall.h" #include "umock_c/umockcallrecorder.h" #include "umock_c/umock_log.h" static UMOCKCALLRECORDER_HANDLE snapshot_call_recorder; typedef enum UMOCK_C_NEGATIVE_TESTS_STATE_TAG { UMOCK_C_NEGATIVE_TESTS_STATE_NOT_INITIALIZED, UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED } UMOCK_C_NEGATIVE_TESTS_STATE; static UMOCK_C_NEGATIVE_TESTS_STATE umock_c_negative_tests_state = UMOCK_C_NEGATIVE_TESTS_STATE_NOT_INITIALIZED; int umock_c_negative_tests_init(void) { int result; if (umock_c_negative_tests_state != UMOCK_C_NEGATIVE_TESTS_STATE_NOT_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_005: [ If the module has already been initialized, umock_c_negative_tests_init shall return a non-zero value. ]*/ UMOCK_LOG("umock_c_negative_tests_init: Already initialized."); result = __LINE__; } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_001: [ umock_c_negative_tests_init shall initialize the umock_c negative tests library. ]*/ /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_004: [ On success, umock_c_negative_tests_init shall return 0. ]*/ umock_c_negative_tests_state = UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED; result = 0; } return result; } void umock_c_negative_tests_deinit(void) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_003: [ If the module was not previously initialized, umock_c_negative_tests_deinit shall do nothing. ]*/ if (umock_c_negative_tests_state == UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_002: [ umock_c_negative_tests_deinit shall free all resources associated with the negative tests module. ]*/ if (snapshot_call_recorder != NULL) { umockcallrecorder_destroy(snapshot_call_recorder); snapshot_call_recorder = NULL; } umock_c_negative_tests_state = UMOCK_C_NEGATIVE_TESTS_STATE_NOT_INITIALIZED; } } /* Codes_SRS_UMOCK_C_LIB_01_167: [ umock_c_negative_tests_snapshot shall take a snapshot of the current setup of expected calls (a.k.a happy path). ]*/ /* Codes_SRS_UMOCK_C_LIB_01_168: [ If umock_c_negative_tests_snapshot is called without the module being initialized, it shall do nothing. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_169: [ All errors shall be reported by calling the umock_c on error function. ]*/ /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_006: [ umock_c_negative_tests_snapshot shall make a copy of the current call recorder for umock_c with all its recorded calls. ]*/ void umock_c_negative_tests_snapshot(void) { if (umock_c_negative_tests_state != UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_015: [ If the module was not previously initialized, umock_c_negative_tests_snapshot shall do nothing. ]*/ UMOCK_LOG("umock_c_negative_tests_snapshot: Not initialized."); } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_007: [ The current call recorder shall be obtained by calling umock_c_get_call_recorder. ]*/ UMOCKCALLRECORDER_HANDLE current_call_recorder = umock_c_get_call_recorder(); if (current_call_recorder == NULL) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_009: [ If getting the call recorder fails, umock_c_negative_tests_snapshot shall indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_snapshot: Error getting the current call recorder."); umock_c_indicate_error(UMOCK_C_ERROR); } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_008: [ The copy of the recorder shall be made by calling umockcallrecorder_clone. ]*/ UMOCKCALLRECORDER_HANDLE new_call_recorder = umockcallrecorder_clone(current_call_recorder); if (new_call_recorder == NULL) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_010: [ If copying the call recorder fails, umock_c_negative_tests_snapshot shall indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_snapshot: Error cloning the call recorder."); umock_c_indicate_error(UMOCK_C_ERROR); } else { if (snapshot_call_recorder != NULL) { umockcallrecorder_destroy(snapshot_call_recorder); } snapshot_call_recorder = new_call_recorder; } } } } /* Codes_SRS_UMOCK_C_LIB_01_170: [ umock_c_negative_tests_reset shall bring umock_c expected and actual calls to the state recorded when umock_c_negative_tests_snapshot was called. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_171: [ If umock_c_negative_tests_reset is called without the module being initialized, it shall do nothing. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_172: [ All errors shall be reported by calling the umock_c on error function. ]*/ void umock_c_negative_tests_reset(void) { if (umock_c_negative_tests_state != UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_016: [ If the module was not previously initialized, umock_c_negative_tests_reset shall do nothing. ]*/ UMOCK_LOG("umock_c_negative_tests_reset: Not initialized."); } else { if (snapshot_call_recorder == NULL) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_012: [ If no call has been made to umock_c_negative_tests_snapshot, umock_c_negative_tests_reset shall indicate a failure via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_reset: No snapshot was done, use umock_c_negative_tests_snapshot."); umock_c_indicate_error(UMOCK_C_ERROR); } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_011: [ umock_c_negative_tests_reset shall reset the call recorder used by umock_c to the call recorder stored in umock_c_negative_tests_reset. ]*/ /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_013: [ The reset shall be done by calling umock_c_set_call_recorder and passing the call recorder stored in umock_c_negative_tests_reset as argument. ]*/ if (umock_c_set_call_recorder(snapshot_call_recorder) != 0) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_014: [ If umock_c_set_call_recorder fails, umock_c_negative_tests_reset shall indicate a failure via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_reset: Failed setting the call recorder to the snapshot one."); umock_c_indicate_error(UMOCK_C_ERROR); } } } } /* Codes_SRS_UMOCK_C_LIB_01_173: [ umock_c_negative_tests_fail_call shall instruct the negative tests module to fail a specific call. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_174: [ If umock_c_negative_tests_fail_call is called without the module being initialized, it shall do nothing. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_175: [ All errors shall be reported by calling the umock_c on error function. ]*/ void umock_c_negative_tests_fail_call(size_t index) { if (umock_c_negative_tests_state != UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_020: [ If the module was not previously initialized, umock_c_negative_tests_fail_call shall do nothing. ]*/ UMOCK_LOG("umock_c_negative_tests_fail_call: Not initialized."); } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_017: [ umock_c_negative_tests_fail_call shall call umockcallrecorder_fail_call on the currently used call recorder used by umock_c. ]*/ /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_018: [ The currently used recorder shall be obtained by calling umock_c_get_call_recorder. ]*/ UMOCKCALLRECORDER_HANDLE call_recorder = umock_c_get_call_recorder(); if (call_recorder == NULL) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_019: [ If umock_c_get_call_recorder fails, umock_c_negative_tests_fail_call shall indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_fail_call: Cannot get call recorder."); umock_c_indicate_error(UMOCK_C_ERROR); } else { if (umockcallrecorder_fail_call(call_recorder, index) != 0) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_025: [ If failing the call by calling umockcallrecorder_fail_call fails, umock_c_negative_tests_fail_call shall indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_fail_call: Cannot get call recorder."); umock_c_indicate_error(UMOCK_C_ERROR); } } } } /* Codes_SRS_UMOCK_C_LIB_01_176: [ umock_c_negative_tests_call_count shall provide the number of expected calls, so that the test code can iterate through all negative cases. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_177: [ If umock_c_negative_tests_fail_call is called without the module being initialized, it shall return 0. ]*/ /* Codes_SRS_UMOCK_C_LIB_01_178: [ All errors shall be reported by calling the umock_c on error function. ]*/ size_t umock_c_negative_tests_call_count(void) { size_t result; if (umock_c_negative_tests_state != UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_024: [ If the module was not previously initialized, umock_c_negative_tests_call_count shall return 0. ]*/ UMOCK_LOG("umock_c_negative_tests_call_count: Not initialized."); result = 0; } else { if (snapshot_call_recorder == NULL) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_022: [ If no call has been made to umock_c_negative_tests_snapshot, umock_c_negative_tests_fail_call shall return 0 and indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_call_count: No snapshot, use umock_c_negative_tests_snapshot."); umock_c_indicate_error(UMOCK_C_ERROR); result = 0; } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_021: [ umock_c_negative_tests_call_count shall return the count of expected calls for the current snapshot call recorder by calling umockcallrecorder_get_expected_call_count. ]*/ if (umockcallrecorder_get_expected_call_count(snapshot_call_recorder, &result) != 0) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_01_023: [ If umockcallrecorder_get_expected_call_count fails, umock_c_negative_tests_fail_call shall return 0 and indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_call_count: Getting the expected call count from the recorder failed."); umock_c_indicate_error(UMOCK_C_ERROR); result = 0; } } } return result; } int umock_c_negative_tests_can_call_fail(size_t index) { int can_call_fail = 1; if (umock_c_negative_tests_state != UMOCK_C_NEGATIVE_TESTS_STATE_INITIALIZED) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_31_026: [ If the module was not previously initialized, umock_c_negative_tests_can_call_fail shall return 1. ]*/ UMOCK_LOG("umock_c_negative_tests_fail_call: Not initialized."); umock_c_indicate_error(UMOCK_C_ERROR); } else { UMOCKCALLRECORDER_HANDLE call_recorder = umock_c_get_call_recorder(); if (call_recorder == NULL) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_31_027: [ If umock_c_get_call_recorder fails, umock_c_negative_tests_can_call_fail shall indicate the error via the umock error callback with error code UMOCK_C_ERROR. ]*/ UMOCK_LOG("umock_c_negative_tests_fail_call: Cannot get call recorder."); umock_c_indicate_error(UMOCK_C_ERROR); } else { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_31_028: [ Whether the call can fail for the given index shall made by calling umockcallrecorder_can_call_fail. ]*/ if (umockcallrecorder_can_call_fail(call_recorder, index, &can_call_fail) != 0) { /* Codes_SRS_UMOCK_C_NEGATIVE_TESTS_31_029: [ If umockcallrecorder_can_call_fail fails, umock_c_negative_tests_fail_call shall indicate the error via the umock error callback with error code UMOCK_C_ERROR and return 1. ]*/ can_call_fail = 1; UMOCK_LOG("umock_c_negative_tests_fail_call: Cannot get call can fail."); umock_c_indicate_error(UMOCK_C_ERROR); } } } return can_call_fail; }