From 26df11fc4770a1ae0a971e496fb19cc565bfa626 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Wed, 19 Jun 2019 22:26:38 +0200 Subject: [PATCH] Added tests. Start them by sending a message to MQTT_TOPIC/run_tests. First test will test all effects for memory leaks. --- include/effects.h | 2 +- include/tests.h | 6 +++++ src/effect_cycle.cpp | 3 ++- src/effects.cpp | 52 +++++++++++++++++++++++--------------------- src/mqtt.cpp | 4 ++++ src/tests.cpp | 28 ++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 27 deletions(-) create mode 100644 include/tests.h create mode 100644 src/tests.cpp diff --git a/include/effects.h b/include/effects.h index 5c2e8f7..05376e4 100644 --- a/include/effects.h +++ b/include/effects.h @@ -11,7 +11,7 @@ extern uint8_t cycle_effects_count; extern Effect* current_effect; extern ClockEffect effect_clock; -Effect* string_to_effect(String s); +Effect* select_effect(uint32_t c); bool change_current_effect(String s); void setup_effects(); diff --git a/include/tests.h b/include/tests.h new file mode 100644 index 0000000..e8a7ae0 --- /dev/null +++ b/include/tests.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tests { + void run(); + void test_effects_for_memory_leaks(); +} diff --git a/src/effect_cycle.cpp b/src/effect_cycle.cpp index 927b265..9791d8b 100644 --- a/src/effect_cycle.cpp +++ b/src/effect_cycle.cpp @@ -1,5 +1,6 @@ #include "effect_cycle.h" #include "effects.h" +#include CycleEffect::CycleEffect() { changeEffect(); @@ -23,7 +24,7 @@ void CycleEffect::changeEffect() { if (effect) delete effect; LOGln("CycleEffect * Searching for new effect '%s'", cycle_effects[new_id]); delay(25); - effect = string_to_effect(cycle_effects[new_id]); + effect = select_effect( crc32String(cycle_effects[new_id]) ); effect_id = new_id; effectSince = millis(); } diff --git a/src/effects.cpp b/src/effects.cpp index fbbb6c1..fb6f641 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -22,32 +22,34 @@ Effect* current_effect; ClockEffect effect_clock; -Effect* string_to_effect(String name) { - uint32_t crc = crc32String(name.c_str()); - switch (crc) { +Effect* select_effect(uint32_t code) { + switch (code) { // use e.g. https://crccalc.com/ for the conversion of name to crc. - case 0xD682E3C8 /* sinematrix3 */ : return new Sinematrix3Effect(); - case 0x90A887DA /* big_clock */ : return new BigClockEffect(); - case 0xBE7BBE92 /* clock */ : return new ClockEffect(); - case 0x733BE087 /* bell */ : return new BellEffect(); - case 0x2BBC5D43 /* off */ : return new StaticEffect(0x000000); - case 0x1D84F231 /* koopa */ : return new AnimationEffect("/koopa.pia", new CRGB(0x000000), 0, 0); - case 0xAC43BCF1 /* couple_rain */ : return new AnimationEffect("/couple_rain.pia", new CRGB(0x000000), -8, -16); - case 0xF1B117F7 /* single_dynamic */ : return new SingleDynamicEffect(); - case 0xF52F2804 /* multi_dynamic */ : return new MultiDynamicEffect(); - case 0xF83341CF /* matrix */ : return new MatrixEffect(); - case 0xD2B79DD0 /* rainbow_matrix */ : return new RainbowMatrixEffect(); - case 0xE8DD3433 /* random_matrix */ : return new RandomMatrixEffect(); - case 0xB086D193 /* cycle */ : return new CycleEffect(); - case 0x2293EF9F /* twirl */ : return new TwirlEffect(); - case 0x60ECC3E6 /* heart */ : return new AnimationEffect("/heart.pia", new CRGB(0x000000), 0, 0); - case 0x42090A49 /* confetti */ : return new ConfettiEffect(); - case 0x516D6B9E /* snake */ : return new SnakeEffect(); - case 0x58DE09CF /* fire */ : return new FireEffect(); - case 0x08BA9C08 /* firework */ : return new FireworkEffect(); - case 0x14B85EAC /* gol */ : return new GolEffect(); - case 0xFA13015D /* cake */ : return new AnimationEffect("/cake.pia", new CRGB(0x000000), 0, 0); - case 0xA2B0D68B /* pixel_clock */ : return new PixelClockEffect(); + case 0: case 0xD682E3C8 /* sinematrix3 */ : return new Sinematrix3Effect(); + case 1: case 0x90A887DA /* big_clock */ : return new BigClockEffect(); + case 2: case 0xBE7BBE92 /* clock */ : return new ClockEffect(); + case 3: case 0x733BE087 /* bell */ : return new BellEffect(); //(new AnimationEffect("/bell.pia", 0x000000, 0, 0))->setFgColor(0xFFFF00); + case 4: case 0x2BBC5D43 /* off */ : return new StaticEffect(0x000000); + case 5: case 0x1D84F231 /* koopa */ : return new AnimationEffect("/koopa.pia", CRGB(0x000000), 0, 0); + case 6: case 0xAC43BCF1 /* couple_rain */ : return new AnimationEffect("/couple_rain.pia", CRGB(0x000000), -8, -16); + case 7: case 0xF1B117F7 /* single_dynamic */ : return new SingleDynamicEffect(); + case 8: case 0xF52F2804 /* multi_dynamic */ : return new MultiDynamicEffect(); + case 9: case 0xF83341CF /* matrix */ : return new MatrixEffect(); + case 10: case 0xD2B79DD0 /* rainbow_matrix */ : return new RainbowMatrixEffect(); + case 11: case 0xE8DD3433 /* random_matrix */ : return new RandomMatrixEffect(); + case 12: case 0xB086D193 /* cycle */ : return new CycleEffect(); + case 13: case 0x2293EF9F /* twirl */ : return new TwirlEffect(); + case 14: case 0x60ECC3E6 /* heart */ : return new AnimationEffect("/heart.pia", CRGB(0x000000), 0, 0); + case 15: case 0x42090A49 /* confetti */ : return new ConfettiEffect(); + case 16: case 0x516D6B9E /* snake */ : return new SnakeEffect(); + case 17: case 0x58DE09CF /* fire */ : return new FireEffect(); + case 18: case 0x08BA9C08 /* firework */ : return new FireworkEffect(); + case 19: case 0x14B85EAC /* gol */ : return new GolEffect(); + case 20: case 0xFA13015D /* cake */ : return new AnimationEffect("/cake.pia", CRGB(0x000000), 0, 0); + case 21: case 0xA2B0D68B /* pixel_clock */ : return new PixelClockEffect(); + case 22: case 0x2C0E6962 /* big_dynamic */ : return new BigDynamicEffect(); + case 23: case 0xDA6F31A5 /* random_confetti */ : return new RandomConfettiEffect(); + case 24: case 0x8325C1DF /* dvd */ : return new DvdEffect(); default : return NULL; }; } diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 34dcff9..a7d77a3 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -10,6 +10,7 @@ #include "Effect.h" #include "effects.h" #include "functions.h" +#include "tests.h" WiFiClient wifi; PubSubClient mqtt_client(wifi); @@ -63,6 +64,9 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) { LOGln("MQTT * Rebooting"); ESP.restart(); return; // Will never be reached, but anyway... + } else if (topic.compareTo("run_tests")==0) { + tests::run(); + return; } long value = payload.toInt(); LOGln("MQTT * Payload as number: %d", value); diff --git a/src/tests.cpp b/src/tests.cpp new file mode 100644 index 0000000..73053ce --- /dev/null +++ b/src/tests.cpp @@ -0,0 +1,28 @@ +#include "tests.h" +#include "effects.h" + +namespace tests { + void run() { + LOGln("Tests * Running test for memory leaks..."); + test_effects_for_memory_leaks(); + } + + void test_effects_for_memory_leaks() { + int i=0; + Effect* effect; + int32_t diffs[3] = {0, 0, 0}; + int32_t usage = 0; + while (1) { + for (int j=0; j<3; j++) { + int free_at_start = ESP.getFreeHeap(); + effect = select_effect(i); + if (j==0) usage = free_at_start - ESP.getFreeHeap(); + if (effect == NULL) return; + delete effect; + diffs[j] = free_at_start - ESP.getFreeHeap(); + } + LOGln("Tests * Memory usage of effect #%d: %d, leakage %d, %d, %d", i, usage, diffs[0], diffs[1], diffs[2]); + i++; + } + } +}