Add test cases from vi-firmware.
authorChristopher Peplin <chris.peplin@rhubarbtech.com>
Tue, 24 Dec 2013 17:00:20 +0000 (12:00 -0500)
committerChristopher Peplin <chris.peplin@rhubarbtech.com>
Tue, 24 Dec 2013 17:00:20 +0000 (12:00 -0500)
.gitignore [new file with mode: 0644]
Makefile
src/bitfield/bitfield.h
src/canutil/read.h
src/canutil/write.c
src/canutil/write.h
tests/read_tests.c [new file with mode: 0644]
tests/tests.bin [deleted file]
tests/write_tests.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..b4225c0
--- /dev/null
@@ -0,0 +1,4 @@
+*.o
+.DS_Store
+*~
+*.bin
index 8385c3a..49e22f2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,15 +19,16 @@ SRC = $(wildcard src/**/*.c)
 OBJS = $(SRC:.c=.o)
 TEST_SRC = $(wildcard $(TEST_DIR)/*.c)
 TEST_OBJS = $(TEST_SRC:.c=.o)
+TESTS=$(patsubst %.c,%.bin,$(TEST_SRC))
 
 all: $(OBJS)
 
-test: $(TEST_DIR)/tests.bin
+test: $(TESTS)
        @set -o $(TEST_SET_OPTS) >/dev/null 2>&1
        @export SHELLOPTS
        @sh runtests.sh $(TEST_DIR)
 
-$(TEST_DIR)/tests.bin: $(TEST_OBJS) $(OBJS)
+$(TEST_DIR)/%.bin: $(TEST_DIR)/%.o $(OBJS)
        @mkdir -p $(dir $@)
        $(CC) $(LDFLAGS) $(CC_SYMBOLS) $(INCLUDES) -o $@ $^ $(LDLIBS)
 
index 2776673..7d9f399 100644 (file)
@@ -4,6 +4,10 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Public: Reads a subset of bits from a byte array.
  *
  * data - the bytes in question.
@@ -55,4 +59,8 @@ void setBitField(uint64_t* data, uint64_t value, int startPos, int numBits);
  */
 uint8_t nthByte(uint64_t source, int byteNum);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif // __BITFIELD_H__
index 815f26b..6ac4eeb 100644 (file)
@@ -4,10 +4,26 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Public: Parse a CAN signal from a message and apply required transformation.
+ *
+ * signal - The details of the signal to decode and forward.
+ * data   - The raw bytes of the CAN message that contains the signal, assumed
+ *      to be in big-endian byte order from CAN.
+ *
+ * Returns the final, transformed value of the signal.
+ */
 float parseFloat(uint64_t data, uint8_t bitPosition, uint8_t bitSize,
         float factor, float offset);
 
 bool parseBoolean(uint64_t data, uint8_t bitPosition, uint8_t bitSize,
         float factor, float offset);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif // __READ_H__
index fdcba1f..741778c 100644 (file)
@@ -1,18 +1,18 @@
 #include "write.h"
 
-uint64_t encodeFloat(float value, float offset, float factor, uint8_t bitPosition,
-        uint8_t bitSize) {
+uint64_t encodeFloat(float value, uint8_t bitPosition, uint8_t bitSize,
+        float factor, float offset) {
     float rawValue = (value - offset) / factor;
     if(rawValue > 0) {
         // round up to avoid losing precision when we cast to an int
         rawValue += 0.5;
     }
     uint64_t result = 0;
-    setBitField(&result, rawValue, bitPosition, bitSize);
+    setBitField(&result, (uint64_t)rawValue, bitPosition, bitSize);
     return result;
 }
 
-uint64_t encodeBoolean(bool value, float offset, float factor,
-                uint8_t bitPosition, uint8_t bitSize) {
-        return encodeFloat(value, offset, factor, bitPosition, bitSize);
+uint64_t encodeBoolean(bool value, uint8_t bitPosition, uint8_t bitSize,
+        float factor, float offset) {
+    return encodeFloat(value, offset, factor, bitPosition, bitSize);
 }
index 85a5c1a..1b086db 100644 (file)
@@ -4,10 +4,18 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-uint64_t encodeFloat(float value, float offset, float factor, uint8_t bitPosition,
-        uint8_t bitSize);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-uint64_t encodeBoolean(bool value, float offset, float factor,
-                uint8_t bitPosition, uint8_t bitSize);
+uint64_t encodeFloat(float value, uint8_t bitPosition, uint8_t bitSize,
+                float factor, float offset);
+
+uint64_t encodeBoolean(bool value, uint8_t bitPosition, uint8_t bitSize,
+                float factor, float offset);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif // __WRITE_H__
diff --git a/tests/read_tests.c b/tests/read_tests.c
new file mode 100644 (file)
index 0000000..f5f0f0c
--- /dev/null
@@ -0,0 +1,36 @@
+#include <check.h>
+#include <stdint.h>
+#include <canutil/read.h>
+
+const uint64_t BIG_ENDIAN_TEST_DATA = __builtin_bswap64(0xEB00000000000000);
+
+START_TEST (test_parse_float)
+{
+    float result = parseFloat(BIG_ENDIAN_TEST_DATA, 2, 4, 1001.0, -30000.0);
+    float correctResult = 0xA * 1001.0 - 30000.0;
+    fail_unless(result == correctResult,
+            "parse is incorrect: %f but should be %f", result, correctResult);
+}
+END_TEST
+
+Suite* canreadSuite(void) {
+    Suite* s = suite_create("read");
+    TCase *tc_core = tcase_create("core");
+    tcase_add_checked_fixture(tc_core, NULL, NULL);
+    tcase_add_test(tc_core, test_parse_float);
+    suite_add_tcase(s, tc_core);
+
+    return s;
+}
+
+int main(void) {
+    int numberFailed;
+    Suite* s = canreadSuite();
+    SRunner *sr = srunner_create(s);
+    // Don't fork so we can actually use gdb
+    srunner_set_fork_status(sr, CK_NOFORK);
+    srunner_run_all(sr, CK_NORMAL);
+    numberFailed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+    return (numberFailed == 0) ? 0 : 1;
+}
diff --git a/tests/tests.bin b/tests/tests.bin
deleted file mode 100755 (executable)
index 5fd0916..0000000
Binary files a/tests/tests.bin and /dev/null differ
diff --git a/tests/write_tests.c b/tests/write_tests.c
new file mode 100644 (file)
index 0000000..da5ee89
--- /dev/null
@@ -0,0 +1,40 @@
+#include <canutil/write.h>
+#include <check.h>
+#include <stdint.h>
+
+START_TEST (test_encode_can_signal)
+{
+    uint64_t value = encodeFloat(0, 1, 3, 1, 0);
+    ck_assert_int_eq(value, 0);
+}
+END_TEST
+
+START_TEST (test_encode_can_signal_rounding_precision)
+{
+    uint64_t value = encodeFloat(50, 2, 19, 0.001, 0);
+    ck_assert_int_eq(value, 0x061a800000000000LLU);
+}
+END_TEST
+
+Suite* canwriteSuite(void) {
+    Suite* s = suite_create("write");
+    TCase *tc_core = tcase_create("core");
+    tcase_add_checked_fixture(tc_core, NULL, NULL);
+    tcase_add_test(tc_core, test_encode_can_signal);
+    tcase_add_test(tc_core, test_encode_can_signal_rounding_precision);
+    suite_add_tcase(s, tc_core);
+
+    return s;
+}
+
+int main(void) {
+    int numberFailed;
+    Suite* s = canwriteSuite();
+    SRunner *sr = srunner_create(s);
+    // Don't fork so we can actually use gdb
+    srunner_set_fork_status(sr, CK_NOFORK);
+    srunner_run_all(sr, CK_NORMAL);
+    numberFailed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+    return (numberFailed == 0) ? 0 : 1;
+}