Files
esphome/tests/integration/fixtures/host_logger_thread_safety.yaml

92 lines
3.4 KiB
YAML

esphome:
name: host-logger-thread-test
host:
api:
logger:
button:
- platform: template
name: "Start Thread Race Test"
id: start_test_button
on_press:
- lambda: |-
// Number of threads and messages per thread
static const int NUM_THREADS = 3;
static const int MESSAGES_PER_THREAD = 100;
// Counters
static std::atomic<int> total_messages_logged{0};
// Thread function - must be a regular function pointer for pthread
struct ThreadTest {
static void *thread_func(void *arg) {
int thread_id = *static_cast<int *>(arg);
// Set thread name (different signatures on macOS vs Linux)
char thread_name[16];
snprintf(thread_name, sizeof(thread_name), "LogThread%d", thread_id);
#ifdef __APPLE__
pthread_setname_np(thread_name);
#else
pthread_setname_np(pthread_self(), thread_name);
#endif
// Log messages with different log levels
for (int i = 0; i < MESSAGES_PER_THREAD; i++) {
switch (i % 4) {
case 0:
ESP_LOGI("thread_test", "THREAD%d_MSG%03d_INFO_MESSAGE_WITH_DATA_%08X",
thread_id, i, i * 12345);
break;
case 1:
ESP_LOGD("thread_test", "THREAD%d_MSG%03d_DEBUG_MESSAGE_WITH_DATA_%08X",
thread_id, i, i * 12345);
break;
case 2:
ESP_LOGW("thread_test", "THREAD%d_MSG%03d_WARN_MESSAGE_WITH_DATA_%08X",
thread_id, i, i * 12345);
break;
case 3:
ESP_LOGE("thread_test", "THREAD%d_MSG%03d_ERROR_MESSAGE_WITH_DATA_%08X",
thread_id, i, i * 12345);
break;
}
total_messages_logged.fetch_add(1, std::memory_order_relaxed);
// Small busy loop to vary timing between threads
int delay_count = (thread_id + 1) * 10;
while (delay_count-- > 0) {
asm volatile("" ::: "memory"); // Prevent optimization
}
}
return nullptr;
}
};
ESP_LOGI("thread_test", "RACE_TEST_START: Starting %d threads with %d messages each",
NUM_THREADS, MESSAGES_PER_THREAD);
// Reset counter for this test run
total_messages_logged.store(0, std::memory_order_relaxed);
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// Create all threads
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i;
int ret = pthread_create(&threads[i], nullptr, ThreadTest::thread_func, &thread_ids[i]);
if (ret != 0) {
ESP_LOGE("thread_test", "RACE_TEST_ERROR: Failed to create thread %d", i);
return;
}
}
// Wait for all threads to complete
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], nullptr);
}
ESP_LOGI("thread_test", "RACE_TEST_COMPLETE: All threads finished, total messages: %d",
total_messages_logged.load(std::memory_order_relaxed));