FastLED 3.9.15
Loading...
Searching...
No Matches
TestRunner.h
Go to the documentation of this file.
1// @filter: (platform is esp32)
14
15#pragma once
16
17#include <Arduino.h>
18#include <FastLED.h>
19#include "fl/channels/manager.h" // ChannelManager::setExclusiveDriverByName (by-name escape hatch)
20#include "fl/stl/sstream.h"
21#include "PlatformConfig.h"
22
23// ============================================================================
24// BOX DRAWING CHARACTERS (for nice console output)
25// ============================================================================
26
27#define BOX_TOP "\n+================================================================+\n"
28#define BOX_MID "+================================================================+\n"
29#define BOX_BOTTOM "+================================================================+\n"
30#define LINE_SEP "----------------------------------------------------------------\n"
31
32// ============================================================================
33// TEST RESULT CLASS
34// ============================================================================
35
37struct TestResult {
38 const char* mTestName;
39 bool mPassed;
40 const char* mMessage;
41
42 TestResult(const char* name, bool passed, const char* msg = "")
43 : mTestName(name), mPassed(passed), mMessage(msg) {}
44};
45
46// ============================================================================
47// DRIVER TEST RUNNER CLASS
48// ============================================================================
49
62public:
66 DriverTestRunner(CRGB* leds, int numLeds)
67 : mLeds(leds)
68 , mNumLeds(numLeds)
69 , mTotalTests(0)
70 , mPassedTests(0)
71 , mAllTestsPassed(true) {}
72
79
81 void printSummary() {
82 fl::sstream ss;
83 ss << BOX_TOP;
84 if (mAllTestsPassed) {
85 ss << "| ALL TESTS PASSED |\n";
86 } else {
87 ss << "| SOME TESTS FAILED |\n";
88 }
89 ss << BOX_MID;
90 ss << "| Platform: " << getPlatformName() << "\n";
91 ss << "| Tests: " << mPassedTests << "/" << mTotalTests << " passed\n";
92 ss << BOX_BOTTOM;
93 Serial.print(ss.str().c_str());
94
95 // Machine-readable output for automated testing
96 if (mAllTestsPassed) {
97 Serial.println("\nTEST_SUITE_COMPLETE: PASS");
98 } else {
99 Serial.println("\nTEST_SUITE_COMPLETE: FAIL");
100 }
101 }
102
105 bool allPassed() const { return mAllTestsPassed; }
106
108 int getTotalTests() const { return mTotalTests; }
109
111 int getPassedTests() const { return mPassedTests; }
112
113private:
119
121 void printHeader() {
122 fl::sstream ss;
123 ss << BOX_TOP;
124 ss << "| ESP32 Generic Driver Test |\n";
125 ss << "| Tests all available LED channel drivers via Channel API |\n";
126 ss << BOX_BOTTOM;
127 ss << "\nPlatform: " << getPlatformName() << "\n";
128 ss << "Data Pin: " << DATA_PIN << "\n";
129 ss << "LED Count: " << mNumLeds << "\n";
130 Serial.print(ss.str().c_str());
131 }
132
136 void recordResult(const char* name, bool passed) {
137 mTotalTests++;
138 if (passed) {
139 mPassedTests++;
140 Serial.print(" [PASS] ");
141 } else {
142 mAllTestsPassed = false;
143 Serial.print(" [FAIL] ");
144 }
145 Serial.println(name);
146 }
147
148 // ========================================================================
149 // DRIVER VALIDATION
150 // ========================================================================
151
155 getExpectedDrivers(expected);
156
157 if (expected.empty()) {
158 Serial.println("\n[WARNING] Unknown platform - skipping driver validation");
159 return;
160 }
161
162 fl::sstream ss;
163 ss << BOX_TOP;
164 ss << "| DRIVER VALIDATION FOR " << getPlatformName() << "\n";
165 ss << BOX_BOTTOM;
166 Serial.print(ss.str().c_str());
167
168 // Get available drivers from FastLED
169 auto drivers = FastLED.getDriverInfos();
170
171 // Print expected drivers
172 ss.clear();
173 ss << "\nExpected drivers (" << expected.size() << "):\n";
174 for (fl::size i = 0; i < expected.size(); i++) {
175 ss << " - " << expected[i] << "\n";
176 }
177 Serial.print(ss.str().c_str());
178
179 // Print available drivers with details
180 ss.clear();
181 ss << "\nAvailable drivers (" << drivers.size() << "):\n";
182 for (fl::size i = 0; i < drivers.size(); i++) {
183 ss << " - " << drivers[i].name.c_str()
184 << " (priority: " << drivers[i].priority
185 << ", enabled: " << (drivers[i].enabled ? "yes" : "no") << ")\n";
186 }
187 Serial.print(ss.str().c_str());
188
189 // Check each expected driver is present
190 Serial.println("\nValidation results:");
191 for (fl::size i = 0; i < expected.size(); i++) {
192 const char* expName = expected[i];
193 bool found = false;
194
195 for (fl::size j = 0; j < drivers.size(); j++) {
196 if (fl::strcmp(drivers[j].name.c_str(), expName) == 0) {
197 found = true;
198 break;
199 }
200 }
201
202 fl::sstream resultMsg;
203 resultMsg << expName << " driver " << (found ? "found" : "MISSING!");
204 recordResult(resultMsg.str().c_str(), found);
205 }
206 }
207
208 // ========================================================================
209 // DRIVER TESTING
210 // ========================================================================
211
214 auto drivers = FastLED.getDriverInfos();
215
216 fl::sstream ss;
217 ss << BOX_TOP;
218 ss << "| TESTING ALL AVAILABLE DRIVERS |\n";
219 ss << BOX_BOTTOM;
220 Serial.print(ss.str().c_str());
221
222 Serial.print("Found ");
223 Serial.print(drivers.size());
224 Serial.println(" driver(s) to test\n");
225
226 int tested = 0;
227 int skipped = 0;
228
229 for (fl::size i = 0; i < drivers.size(); i++) {
230 const char* name = drivers[i].name.c_str();
231 if (drivers[i].name.empty()) {
232 Serial.println(" [SKIP] Unnamed driver");
233 skipped++;
234 continue;
235 }
236
237 if (testSingleDriver(name)) {
238 tested++;
239 } else {
240 skipped++;
241 }
242
243 delay(500); // Brief pause between driver tests
244 }
245
246 Serial.print("\n");
247 Serial.print(LINE_SEP);
248 Serial.print("Driver tests complete: ");
249 Serial.print(tested);
250 Serial.print(" tested, ");
251 Serial.print(skipped);
252 Serial.println(" skipped");
253 }
254
258 bool testSingleDriver(const char* driverName) {
259 fl::sstream ss;
260 ss << "\n" << LINE_SEP;
261 ss << "Testing driver: " << driverName << "\n";
262 ss << LINE_SEP;
263 Serial.print(ss.str().c_str());
264
265 // Attempt to set this driver as exclusive. `driverName` is a runtime
266 // string (the test iterates over discovered drivers by name), so we use
267 // the by-name escape hatch on ChannelManager rather than the typed
268 // FastLED.setExclusiveDriver(fl::Bus) overload. Make sure every driver
269 // is enrolled first so the lookup can succeed.
270 FastLED.enableAllDrivers();
271 if (!fl::ChannelManager::instance().setExclusiveDriverByName(driverName)) {
272 Serial.print(" [SKIP] Could not set ");
273 Serial.print(driverName);
274 Serial.println(" as exclusive driver (not available)");
275 return false;
276 }
277
278 Serial.print(" [INFO] ");
279 Serial.print(driverName);
280 Serial.println(" set as exclusive driver");
281
282 // Run visual test patterns
284
285 // Record success
286 fl::sstream resultMsg;
287 resultMsg << driverName << " driver test completed";
288 recordResult(resultMsg.str().c_str(), true);
289
290 return true;
291 }
292
295 // Clear first
297 FastLED.show();
298 delay(50);
299
300 // Pattern 1: Rainbow gradient
301 Serial.println(" [INFO] Sending rainbow pattern...");
303 FastLED.show();
304 delay(100);
305
306 // Pattern 2: Solid red
307 Serial.println(" [INFO] Sending solid red...");
309 FastLED.show();
310 delay(100);
311
312 // Pattern 3: Solid green
313 Serial.println(" [INFO] Sending solid green...");
315 FastLED.show();
316 delay(100);
317
318 // Pattern 4: Solid blue
319 Serial.println(" [INFO] Sending solid blue...");
321 FastLED.show();
322 delay(100);
323
324 // Clear for next test
326 FastLED.show();
327 }
328};
fl::CRGB leds[NUM_LEDS]
#define DATA_PIN
Definition ClientReal.h:82
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
const char * getPlatformName()
Get a human-readable name for the current platform.
void getExpectedDrivers(fl::vector< const char * > &expected)
Populate a vector with the expected drivers for this platform.
ESP32 Platform Detection and Configuration.
#define BOX_TOP
Definition TestRunner.h:27
#define LINE_SEP
Definition TestRunner.h:30
#define BOX_MID
Definition TestRunner.h:28
#define BOX_BOTTOM
Definition TestRunner.h:29
int getTotalTests() const
Get total number of tests run.
Definition TestRunner.h:108
void recordResult(const char *name, bool passed)
Record a test result.
Definition TestRunner.h:136
bool allPassed() const
Check if all tests passed.
Definition TestRunner.h:105
int getPassedTests() const
Get number of passed tests.
Definition TestRunner.h:111
DriverTestRunner(CRGB *leds, int numLeds)
Construct a test runner.
Definition TestRunner.h:66
void printHeader()
Print test startup header.
Definition TestRunner.h:121
void testAllDrivers()
Test all available drivers.
Definition TestRunner.h:213
void runTestPatterns()
Run visual LED test patterns.
Definition TestRunner.h:294
bool testSingleDriver(const char *driverName)
Test a single driver with LED patterns.
Definition TestRunner.h:258
void runAllTests()
Run all tests: validation + driver tests.
Definition TestRunner.h:74
void printSummary()
Print final test summary with pass/fail status.
Definition TestRunner.h:81
void validateExpectedDrivers()
Validate that all expected drivers are present.
Definition TestRunner.h:153
static ChannelManager & instance() FL_NOEXCEPT
Get the global singleton instance.
const char * c_str() const FL_NOEXCEPT
string str() const FL_NOEXCEPT
Definition strstream.h:43
void clear() FL_NOEXCEPT
Definition strstream.h:358
const char * c_str() const FL_NOEXCEPT
Definition strstream.h:44
fl::size size() const FL_NOEXCEPT
bool empty() const FL_NOEXCEPT
void fill_rainbow(CRGB *targetArray, int numToFill, fl::u8 initialhue, fl::u8 deltahue=5) FL_NOEXCEPT
Fill a range of LEDs with a rainbow of colors.
Definition fill.cpp.hpp:29
void fill_solid(CRGB *targetArray, int numToFill, const CRGB &color) FL_NOEXCEPT
Fill a range of LEDs with a solid color.
Definition fill.cpp.hpp:9
fl::CRGB CRGB
Definition crgb.h:25
Unified manager for channel drivers with priority-based fallback.
int strcmp(const char *s1, const char *s2) FL_NOEXCEPT
const char * mTestName
Definition TestRunner.h:38
bool mPassed
Definition TestRunner.h:39
TestResult(const char *name, bool passed, const char *msg="")
Definition TestRunner.h:42
const char * mMessage
Definition TestRunner.h:40
@ Green
<div style='background:#008000;width:4em;height:4em;'></div>
Definition crgb.h:558
@ Red
<div style='background:#FF0000;width:4em;height:4em;'></div>
Definition crgb.h:622
@ Blue
<div style='background:#0000FF;width:4em;height:4em;'></div>
Definition crgb.h:512
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Definition crgb.h:510
#define Serial
Definition serial.h:304