xoseperez / espurna

Home automation firmware for ESP8266-based devices
http://tinkerman.cat
GNU General Public License v3.0
2.97k stars 635 forks source link

Test utility functions #1898

Open mcspr opened 4 years ago

mcspr commented 4 years ago

Is your feature request related to a problem? Please describe.

ref #1864 , there needs to be a concise way to check that utility functions (brightness calculation, channel setting, value conversion etc.) work without problems with some set of expected inputs and outputs.

Describe the solution you'd like

Additional context

https://tinkerman.cat/post/automated-unit-testing-metal https://github.com/esp8266/Arduino/tree/master/tests/device https://github.com/esp8266/Arduino/tree/master/tests/host https://github.com/SuperHouse/esp-open-rtos/tree/master/tests https://docs.platformio.org/en/latest/plus/unit-testing.html#test-types

cc @xoseperez

mcspr commented 4 years ago

Current implementation via https://github.com/bxparks/UnixHostDuino in the https://github.com/xoseperez/espurna/tree/dev/code/test To run host test, simply use pio test in the code/test directory. Only test at this time is for tuya module, making sure that DataFrame and DataProtocol classes work.

I also tried using https://github.com/arduino/ArduinoCore-API

mcspr commented 4 years ago

Also in regard to the ArduinoCore-API usage - because it is just an API reference, there are host functions missing: https://github.com/esp8266/Arduino/blob/master/tests/host/common/Arduino.cpp https://github.com/bxparks/UnixHostDuino/blob/bafce102e2c39f205e6cf527d7ca02fa19e9d8b5/Arduino.cpp#L27-L58 https://github.com/arduino/ArduinoCore-API/blob/398e70f188e2b861c10d9ffe5e2bfcb6a4a4f489/api/Common.h#L92-L128

And another small example of WiFi scanning, plus millis and delay implementation (but, for a proper esp8266 simulation, there should probably be two threads that will behave like CONT and SYS):

mcspr commented 4 years ago

While doing some research for the #2245 (tangentially related to the #2015), I noticed that we can use individual files in tests:

diff --git a/code/test/platformio.ini b/code/test/platformio.ini
index b7a74be1..23eeeba7 100644
--- a/code/test/platformio.ini
+++ b/code/test/platformio.ini
@@ -1,9 +1,13 @@
 [platformio]
 test_dir = unit
+src_dir = ../espurna

 [env:test]
 platform = native
 lib_compat_mode = off
+test_build_project_src = true
+src_filter =
+    +<../espurna/terminal_parsing.cpp>

Does not work with "espurna.h" includes though, I think (?) we need to include different Arduino header.

fwiw, I have been using Core mock libraries in the https://github.com/mcspr/rpnlib/blob/master/examples/host/CMakeLists.txt But we need to somehow point pio ini to the framework directory. I guess one option is to just copy framework files in the extra_script and put them into the test/lib every test run. pio should figure everything else by itself, like it does with unixhostduino files

I wish this was more straightforward 😴 ...and more common...

mcspr commented 4 years ago

we need to include different Arduino header.

... and pretty much every library used unconditionally, since we include stuff like JustWifi.h, ESP8266WiFi.h (jw depends on it, PIO tries to build it). So, maybe not, we still might want to only match Arduino API level. The very minimum we always want is String. Stream will be helpful in throwing in a bunch of library-level stuff (as Stringified stream is helpful with Tuya thing and Terminal in my specific case right now, since I do want to test things coming from the user)

mcspr commented 3 years ago

Funny 'bug' in the UnixHostDuino: https://github.com/bxparks/UnixHostDuino/blob/1936444e0097a37ad268e5e3d6e6cca8d957a86b/WString.cpp#L178 String::copy(const char* ptr, size_t length) ignores the length when reading the source ptr by using strcpy, making this method very dangerous when used with non-null-terminated blobs. For example, if we want to copy part of the string from some pointer or copy raw bytes from network packet as chars. In our case, this breaks StreamString :/

Seems to be inherited from the original Arduino implementations, as far as I can gather: https://github.com/arduino/ArduinoCore-samd/blob/b9b84b6850aee887c36bb8de9c0942f3eff2b617/cores/arduino/WString.cpp#L179 https://github.com/arduino/ArduinoCore-avr/blob/3055c1efa3c6980c864f661e6c8cc5d5ac773af4/cores/arduino/WString.cpp#L177 and etc.