summaryrefslogtreecommitdiff
path: root/deps/fff/examples/weak_linking
diff options
context:
space:
mode:
Diffstat (limited to 'deps/fff/examples/weak_linking')
-rw-r--r--deps/fff/examples/weak_linking/CMakeLists.txt54
-rw-r--r--deps/fff/examples/weak_linking/config/config.h.in5
-rw-r--r--deps/fff/examples/weak_linking/include/bus.h6
-rw-r--r--deps/fff/examples/weak_linking/include/display.h5
-rw-r--r--deps/fff/examples/weak_linking/include/error.h7
-rw-r--r--deps/fff/examples/weak_linking/include/sensor.h6
-rw-r--r--deps/fff/examples/weak_linking/src/bus.c30
-rw-r--r--deps/fff/examples/weak_linking/src/display.c29
-rw-r--r--deps/fff/examples/weak_linking/src/error.c10
-rw-r--r--deps/fff/examples/weak_linking/src/main.c27
-rw-r--r--deps/fff/examples/weak_linking/src/sensor.c29
-rw-r--r--deps/fff/examples/weak_linking/test/include/bus.fake.h10
-rw-r--r--deps/fff/examples/weak_linking/test/include/display.fake.h10
-rw-r--r--deps/fff/examples/weak_linking/test/include/error.fake.h10
-rw-r--r--deps/fff/examples/weak_linking/test/include/sensor.fake.h13
-rw-r--r--deps/fff/examples/weak_linking/test/include/test_common.h13
-rw-r--r--deps/fff/examples/weak_linking/test/src/bus.fake.c4
-rw-r--r--deps/fff/examples/weak_linking/test/src/display.fake.c4
-rw-r--r--deps/fff/examples/weak_linking/test/src/display.test.c24
-rw-r--r--deps/fff/examples/weak_linking/test/src/error.fake.c4
-rw-r--r--deps/fff/examples/weak_linking/test/src/main.test.c26
-rw-r--r--deps/fff/examples/weak_linking/test/src/sensor.fake.c11
-rw-r--r--deps/fff/examples/weak_linking/test/src/sensor.test.c23
-rw-r--r--deps/fff/examples/weak_linking/test/src/test_common.c33
24 files changed, 393 insertions, 0 deletions
diff --git a/deps/fff/examples/weak_linking/CMakeLists.txt b/deps/fff/examples/weak_linking/CMakeLists.txt
new file mode 100644
index 0000000..b1d5679
--- /dev/null
+++ b/deps/fff/examples/weak_linking/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright 2022 Google LLC
+# SPDX-License-Identifier: Apache-2.0
+
+# Skip these tests for Windows
+if(WIN32)
+ message(STATUS "Weak linking requires __attribute__((weak)) which isn't supported on MS VS, skipping tests")
+ return()
+endif()
+
+# Set the global FFF_GCC_FUNCTION_ATTRIBUTES for config.h
+set(FFF_GCC_FUNCTION_ATTRIBUTES "__attribute__((weak))")
+configure_file(config/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
+# Create a libfakes static library that will be used in the executables below.
+# This library will depend on the above generated config.h which will add the
+# FFF 'weak' function attributes.
+add_library(libfakes STATIC
+ test/src/bus.fake.c
+ test/src/display.fake.c
+ test/src/error.fake.c
+ test/src/sensor.fake.c
+ test/src/test_common.c
+)
+target_precompile_headers(libfakes PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+target_include_directories(libfakes PUBLIC include test/include)
+target_link_libraries(libfakes PUBLIC fff)
+
+# Create the main test binary
+add_executable(test_main src/main.c test/src/main.test.c)
+target_link_libraries(test_main PRIVATE libfakes)
+
+# Create the sensor test binary
+add_executable(test_sensor src/sensor.c test/src/sensor.test.c)
+target_link_libraries(test_sensor PRIVATE libfakes)
+
+# Create the display test binary
+add_executable(test_display src/display.c test/src/display.test.c ${LIBFAKES_SRCS})
+target_link_libraries(test_display PRIVATE libfakes)
+
+# Add tests to ctest
+add_test(
+ NAME test_main
+ COMMAND $<TARGET_FILE:test_main>
+)
+
+add_test(
+ NAME test_sensor
+ COMMAND $<TARGET_FILE:test_sensor>
+)
+
+add_test(
+ NAME test_display
+ COMMAND $<TARGET_FILE:test_display>
+)
diff --git a/deps/fff/examples/weak_linking/config/config.h.in b/deps/fff/examples/weak_linking/config/config.h.in
new file mode 100644
index 0000000..30121ce
--- /dev/null
+++ b/deps/fff/examples/weak_linking/config/config.h.in
@@ -0,0 +1,5 @@
+/* Copyright 2022 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#cmakedefine FFF_GCC_FUNCTION_ATTRIBUTES @FFF_GCC_FUNCTION_ATTRIBUTES@
diff --git a/deps/fff/examples/weak_linking/include/bus.h b/deps/fff/examples/weak_linking/include/bus.h
new file mode 100644
index 0000000..84a56cf
--- /dev/null
+++ b/deps/fff/examples/weak_linking/include/bus.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "error.h"
+
+bool bus_read_write( uint8_t dev, uint8_t registry, uint8_t* buffer, int len, bool assume_echo );
+bool bus_write( uint8_t dev, uint8_t registry, const uint8_t* buffer, int len, bool assume_echo );
diff --git a/deps/fff/examples/weak_linking/include/display.h b/deps/fff/examples/weak_linking/include/display.h
new file mode 100644
index 0000000..da1ee1f
--- /dev/null
+++ b/deps/fff/examples/weak_linking/include/display.h
@@ -0,0 +1,5 @@
+#pragma once
+#include "error.h"
+
+bool display_init();
+void display_update( const char* info );
diff --git a/deps/fff/examples/weak_linking/include/error.h b/deps/fff/examples/weak_linking/include/error.h
new file mode 100644
index 0000000..dd52269
--- /dev/null
+++ b/deps/fff/examples/weak_linking/include/error.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+void runtime_error( const char* msg );
+char* runtime_error_nice_print( const char* msg );
diff --git a/deps/fff/examples/weak_linking/include/sensor.h b/deps/fff/examples/weak_linking/include/sensor.h
new file mode 100644
index 0000000..e199e45
--- /dev/null
+++ b/deps/fff/examples/weak_linking/include/sensor.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "error.h"
+
+bool sensor_init();
+float sensor_read();
diff --git a/deps/fff/examples/weak_linking/src/bus.c b/deps/fff/examples/weak_linking/src/bus.c
new file mode 100644
index 0000000..5706932
--- /dev/null
+++ b/deps/fff/examples/weak_linking/src/bus.c
@@ -0,0 +1,30 @@
+#pragma once
+
+uint16_t* BUS_REGISTER_BASE = (uint16_t*)0xDEADBEEF;
+
+typedef struct
+{
+ uint16_t action;
+ uint16_t reg;
+ uint8_t input;
+ uint8_t output
+} BusDevice;
+
+BusDevice* BUS = (BusDevice*)BUS_REGISTER_BASE;
+
+bool bus_read_write( uint8_t dev, uint8_t registry, uint8_t* buffer, int len, bool assume_echo )
+{
+ // Something that we dont want to run, since the emulation would be hard.
+ BUS->action = 0x01;
+ BUS->reg = registry;
+ for ( int loop =0 ; loop < len; loop ++ )
+ {
+ char output = buffer[loop];
+ BUS->output = output;
+ buffer[loop] = BUS->input;
+
+ if ( ( assume_echo ) && ( buffer[loop] != output ) )
+ return false;
+ }
+ return true;
+}
diff --git a/deps/fff/examples/weak_linking/src/display.c b/deps/fff/examples/weak_linking/src/display.c
new file mode 100644
index 0000000..1b9a7d6
--- /dev/null
+++ b/deps/fff/examples/weak_linking/src/display.c
@@ -0,0 +1,29 @@
+#include <string.h>
+
+#include "display.h"
+#include "bus.h"
+
+#define DISPLAY_ADDRESS 0xAF
+#define DISPLAY_REG_INIT 0x10
+#define DISPLAY_REG_UPDATE 0x20
+
+bool display_init()
+{
+ char init_config[] = { 0xDE, 0xFE, 0x00 };
+ bus_read_write( DISPLAY_ADDRESS, DISPLAY_REG_INIT, (uint8_t*)init_config, 3, false );
+
+ if (init_config[2] != 0x10)
+ return false;
+
+ return true;
+}
+
+void display_update( const char* info )
+{
+ int len = strlen( info );
+
+ if ( bus_write( DISPLAY_ADDRESS, DISPLAY_REG_UPDATE, (const uint8_t*)info, len, true ) != true )
+ {
+ runtime_error("display update failed!");
+ }
+}
diff --git a/deps/fff/examples/weak_linking/src/error.c b/deps/fff/examples/weak_linking/src/error.c
new file mode 100644
index 0000000..5e7db63
--- /dev/null
+++ b/deps/fff/examples/weak_linking/src/error.c
@@ -0,0 +1,10 @@
+#include <assert.h>
+#include "error.h"
+
+char* runtime_error_nice_print( const char* msg )
+{
+ char* buffer = malloc(512);
+ snprintf(buffer, 512, "Got error: %s", msg );
+ buffer[511] = 0;
+ return buffer;
+}
diff --git a/deps/fff/examples/weak_linking/src/main.c b/deps/fff/examples/weak_linking/src/main.c
new file mode 100644
index 0000000..88be84c
--- /dev/null
+++ b/deps/fff/examples/weak_linking/src/main.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "display.h"
+#include "sensor.h"
+
+void give_error( const char* msg )
+{
+ char* buffer = runtime_error_nice_print( msg );
+ runtime_error( buffer );
+ free(buffer);
+}
+
+int update_main( void )
+{
+ if ( !sensor_init() )
+ runtime_error("sensor init failed");
+
+ if ( !display_init() )
+ runtime_error("display init failed");
+
+ char buffer[32];
+ float reading = sensor_read();
+ snprintf( buffer, 32, "Sensor: %0.1f", reading );
+ display_update( buffer );
+ return 0;
+}
diff --git a/deps/fff/examples/weak_linking/src/sensor.c b/deps/fff/examples/weak_linking/src/sensor.c
new file mode 100644
index 0000000..bff6642
--- /dev/null
+++ b/deps/fff/examples/weak_linking/src/sensor.c
@@ -0,0 +1,29 @@
+#include <string.h>
+
+#include "sensor.h"
+#include "bus.h"
+
+#define SENSOR_ADDRESS 0xAA
+#define SENSOR_REG_READ 0xF0
+
+float LOCAL_buffer[4];
+
+bool sensor_init()
+{
+ memset( LOCAL_buffer, 0x00, sizeof(LOCAL_buffer));
+ return true;
+}
+
+float sensor_read()
+{
+ char data[4] = { 0xFF, 0xFF, 0x00, 0x00 };
+ bus_read_write( SENSOR_ADDRESS, SENSOR_REG_READ, (uint8_t*)&data, 4, false );
+
+ if (data[0] != 0x10)
+ {
+ runtime_error("sensor read failed");
+ }
+
+ float ret_value = data[1] + data[2] / 256.0;
+ return ret_value;
+}
diff --git a/deps/fff/examples/weak_linking/test/include/bus.fake.h b/deps/fff/examples/weak_linking/test/include/bus.fake.h
new file mode 100644
index 0000000..170e45a
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/include/bus.fake.h
@@ -0,0 +1,10 @@
+#ifndef _AUTOFAKE_BUS_H
+#define _AUTOFAKE_BUS_H
+
+#include "fff.h"
+#include "bus.h"
+
+DECLARE_FAKE_VALUE_FUNC( bool, bus_read_write, uint8_t, uint8_t, uint8_t*, int, bool );
+DECLARE_FAKE_VALUE_FUNC( bool, bus_write, uint8_t, uint8_t, const uint8_t*, int, bool );
+
+#endif // _AUTOFAKE_BUS_H
diff --git a/deps/fff/examples/weak_linking/test/include/display.fake.h b/deps/fff/examples/weak_linking/test/include/display.fake.h
new file mode 100644
index 0000000..ef2adae
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/include/display.fake.h
@@ -0,0 +1,10 @@
+#ifndef _AUTOFAKE_DISPLAY_H
+#define _AUTOFAKE_DISPLAY_H
+
+#include "fff.h"
+#include "display.h"
+
+DECLARE_FAKE_VALUE_FUNC( bool, display_init );
+DECLARE_FAKE_VOID_FUNC( display_update, const char* );
+
+#endif // _AUTOFAKE_DISPLAY_H
diff --git a/deps/fff/examples/weak_linking/test/include/error.fake.h b/deps/fff/examples/weak_linking/test/include/error.fake.h
new file mode 100644
index 0000000..ee127ec
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/include/error.fake.h
@@ -0,0 +1,10 @@
+#ifndef _AUTOFAKE_ERROR_H
+#define _AUTOFAKE_ERROR_H
+
+#include "fff.h"
+#include "error.h"
+
+DECLARE_FAKE_VOID_FUNC( runtime_error, const char* );
+DECLARE_FAKE_VALUE_FUNC( char*, runtime_error_nice_print, const char* );
+
+#endif // _AUTOFAKE_ERROR_H
diff --git a/deps/fff/examples/weak_linking/test/include/sensor.fake.h b/deps/fff/examples/weak_linking/test/include/sensor.fake.h
new file mode 100644
index 0000000..ae363f8
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/include/sensor.fake.h
@@ -0,0 +1,13 @@
+
+#ifndef _AUTOMOCK_SENSOR_H
+#define _AUTOMOCK_SENSOR_H
+
+#include "fff.h"
+#include "sensor.h"
+
+DECLARE_FAKE_VALUE_FUNC( bool, sensor_init );
+DECLARE_FAKE_VALUE_FUNC( float, sensor_read );
+
+void TEST_sensor_generate_data( char* buffer, float value );
+
+#endif // _AUTOMOCK_SENSOR_H
diff --git a/deps/fff/examples/weak_linking/test/include/test_common.h b/deps/fff/examples/weak_linking/test/include/test_common.h
new file mode 100644
index 0000000..a282dd1
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/include/test_common.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "fff.h"
+#include "bus.fake.h"
+#include "error.fake.h"
+
+
+void init_tests();
+
+extern char GLOBAL_TEST_bus_read_ret[32];
diff --git a/deps/fff/examples/weak_linking/test/src/bus.fake.c b/deps/fff/examples/weak_linking/test/src/bus.fake.c
new file mode 100644
index 0000000..e3a9f76
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/bus.fake.c
@@ -0,0 +1,4 @@
+#include "bus.fake.h"
+
+DEFINE_FAKE_VALUE_FUNC( bool, bus_read_write, uint8_t, uint8_t, uint8_t*, int, bool );
+DEFINE_FAKE_VALUE_FUNC( bool, bus_write, uint8_t, uint8_t, const uint8_t*, int, bool );
diff --git a/deps/fff/examples/weak_linking/test/src/display.fake.c b/deps/fff/examples/weak_linking/test/src/display.fake.c
new file mode 100644
index 0000000..f8dec66
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/display.fake.c
@@ -0,0 +1,4 @@
+#include "display.fake.h"
+
+DEFINE_FAKE_VALUE_FUNC( bool, display_init );
+DEFINE_FAKE_VOID_FUNC( display_update, const char* );
diff --git a/deps/fff/examples/weak_linking/test/src/display.test.c b/deps/fff/examples/weak_linking/test/src/display.test.c
new file mode 100644
index 0000000..269ae32
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/display.test.c
@@ -0,0 +1,24 @@
+#include "test_common.h"
+#include "display.h"
+
+DEFINE_FFF_GLOBALS;
+
+
+int main(void)
+{
+ init_tests(); // Resets common and hook errors to asserts.
+
+ GLOBAL_TEST_bus_read_ret[2] = 0x10;
+ assert( display_init() == true );
+ assert( bus_read_write_fake.call_count == 1);
+
+ display_update( "TEST INFO" );
+ assert( bus_read_write_fake.call_count == 1 );
+ assert( bus_write_fake.call_count == 1 );
+
+ GLOBAL_TEST_bus_read_ret[2] = 0x00;
+ assert( display_init() == false );
+
+ printf("Test " __FILE__ " ok\n");
+ return 0;
+}
diff --git a/deps/fff/examples/weak_linking/test/src/error.fake.c b/deps/fff/examples/weak_linking/test/src/error.fake.c
new file mode 100644
index 0000000..0a39478
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/error.fake.c
@@ -0,0 +1,4 @@
+#include "error.fake.h"
+
+DEFINE_FAKE_VOID_FUNC( runtime_error, const char* );
+DEFINE_FAKE_VALUE_FUNC( char*, runtime_error_nice_print, const char* );
diff --git a/deps/fff/examples/weak_linking/test/src/main.test.c b/deps/fff/examples/weak_linking/test/src/main.test.c
new file mode 100644
index 0000000..6ac023c
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/main.test.c
@@ -0,0 +1,26 @@
+
+#include "display.fake.h"
+#include "sensor.fake.h"
+#include "test_common.h"
+
+DEFINE_FFF_GLOBALS;
+
+
+int update_main( void );
+
+int main(void)
+{
+ init_tests(); // Resets common and hook errors to asserts.
+
+ sensor_init_fake.return_val = true;
+ display_init_fake.return_val = true;
+
+ update_main();
+
+ assert( sensor_init_fake.call_count == 1 );
+ assert( display_init_fake.call_count == 1 );
+ assert( display_update_fake.call_count == 1 );
+
+ printf("Test " __FILE__ " ok\n");
+ return 0;
+}
diff --git a/deps/fff/examples/weak_linking/test/src/sensor.fake.c b/deps/fff/examples/weak_linking/test/src/sensor.fake.c
new file mode 100644
index 0000000..4fdaa66
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/sensor.fake.c
@@ -0,0 +1,11 @@
+#include "sensor.fake.h"
+
+DEFINE_FAKE_VALUE_FUNC( bool, sensor_init );
+DEFINE_FAKE_VALUE_FUNC( float, sensor_read );
+
+void TEST_sensor_generate_data( char* buffer, float value )
+{
+ buffer[0] = 0x10;
+ buffer[1] = (int)(value);
+ buffer[2] = (value - buffer[1])*255;
+}
diff --git a/deps/fff/examples/weak_linking/test/src/sensor.test.c b/deps/fff/examples/weak_linking/test/src/sensor.test.c
new file mode 100644
index 0000000..8126cb6
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/sensor.test.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#include "test_common.h"
+
+#include "sensor.h"
+#include "sensor.fake.h"
+
+DEFINE_FFF_GLOBALS;
+
+
+int main(void)
+{
+ init_tests();
+
+ assert( sensor_init() == true );
+
+ TEST_sensor_generate_data( GLOBAL_TEST_bus_read_ret, 1.5f );
+ float value = sensor_read();
+ float value_error = value - 1.5f;
+ assert( value_error < 0.1f && value_error > -0.1f );
+ printf("Test " __FILE__ " ok\n");
+ return 0;
+}
diff --git a/deps/fff/examples/weak_linking/test/src/test_common.c b/deps/fff/examples/weak_linking/test/src/test_common.c
new file mode 100644
index 0000000..58c3b44
--- /dev/null
+++ b/deps/fff/examples/weak_linking/test/src/test_common.c
@@ -0,0 +1,33 @@
+#include "test_common.h"
+#include <assert.h>
+#include <stdio.h>
+
+char GLOBAL_TEST_bus_read_ret[32];
+
+
+void spoof_runtime_error( const char* info )
+{
+ fprintf(stderr, "Runtime error: %s\n", info );
+ assert(0);
+}
+
+bool spoof_bus_read_write( uint8_t dev, uint8_t registry, uint8_t* buffer, int len, bool assume_echo )
+{
+ memcpy( buffer, GLOBAL_TEST_bus_read_ret, len );
+ fprintf(stderr, "bus spoof %d %d\n", (int)dev, (int)registry );
+ return true;
+}
+
+void init_tests()
+{
+ memset( GLOBAL_TEST_bus_read_ret, 0x00, sizeof(GLOBAL_TEST_bus_read_ret));
+ FFF_RESET_HISTORY();
+
+ RESET_FAKE(bus_read_write);
+ RESET_FAKE(bus_write);
+ RESET_FAKE(runtime_error);
+
+ runtime_error_fake.custom_fake = spoof_runtime_error;
+ bus_read_write_fake.custom_fake = spoof_bus_read_write;
+ bus_write_fake.return_val = true;
+} \ No newline at end of file