mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	improve test
This commit is contained in:
		| @@ -44,9 +44,9 @@ void DeferStressComponent::run_multi_thread_test() { | ||||
|         auto *component = this; | ||||
|  | ||||
|         // Directly call defer() from this thread - no locking! | ||||
|         this->defer([component, defer_id]() { | ||||
|         this->defer([component, i, j, defer_id]() { | ||||
|           component->executed_defers_.fetch_add(1); | ||||
|           ESP_LOGV(TAG, "Executed defer %d", defer_id); | ||||
|           ESP_LOGV(TAG, "Executed defer %d (thread %d, index %d)", defer_id, i, j); | ||||
|         }); | ||||
|  | ||||
|         ESP_LOGV(TAG, "Thread %d called defer for request %d successfully", i, defer_id); | ||||
| @@ -68,19 +68,7 @@ void DeferStressComponent::run_multi_thread_test() { | ||||
|   auto end_time = std::chrono::steady_clock::now(); | ||||
|   auto thread_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(); | ||||
|   ESP_LOGI(TAG, "All threads finished in %lldms. Created %d defer requests", thread_time, this->total_defers_.load()); | ||||
|  | ||||
|   // Store the final values for checking | ||||
|   this->expected_total_ = NUM_THREADS * DEFERS_PER_THREAD; | ||||
|   this->test_complete_ = true; | ||||
| } | ||||
|  | ||||
| int DeferStressComponent::get_total_defers() { return this->total_defers_.load(); } | ||||
|  | ||||
| int DeferStressComponent::get_executed_defers() { return this->executed_defers_.load(); } | ||||
|  | ||||
| bool DeferStressComponent::is_test_complete() { return this->test_complete_; } | ||||
|  | ||||
| int DeferStressComponent::get_expected_total() { return this->expected_total_; } | ||||
|  | ||||
| }  // namespace defer_stress_component | ||||
| }  // namespace esphome | ||||
|   | ||||
| @@ -11,17 +11,9 @@ class DeferStressComponent : public Component { | ||||
|   void setup() override; | ||||
|   void run_multi_thread_test(); | ||||
|  | ||||
|   // Getters for test status | ||||
|   int get_total_defers(); | ||||
|   int get_executed_defers(); | ||||
|   bool is_test_complete(); | ||||
|   int get_expected_total(); | ||||
|  | ||||
|  private: | ||||
|   std::atomic<int> total_defers_{0}; | ||||
|   std::atomic<int> executed_defers_{0}; | ||||
|   bool test_complete_{false}; | ||||
|   int expected_total_{0}; | ||||
| }; | ||||
|  | ||||
| }  // namespace defer_stress_component | ||||
|   | ||||
| @@ -32,22 +32,38 @@ async def test_defer_stress( | ||||
|     loop = asyncio.get_event_loop() | ||||
|     test_complete_future: asyncio.Future[None] = loop.create_future() | ||||
|  | ||||
|     # Track executed defers | ||||
|     # Track executed defers and their order | ||||
|     executed_defers = set() | ||||
|     thread_executions = {}  # thread_id -> list of indices in execution order | ||||
|     fifo_violations = [] | ||||
|  | ||||
|     def on_log_line(line: str) -> None: | ||||
|         # Track all executed defers | ||||
|         match = re.search(r"Executed defer (\d+)", line) | ||||
|         # Track all executed defers with thread and index info | ||||
|         match = re.search(r"Executed defer (\d+) \(thread (\d+), index (\d+)\)", line) | ||||
|         if match: | ||||
|             defer_id = int(match.group(1)) | ||||
|             thread_id = int(match.group(2)) | ||||
|             index = int(match.group(3)) | ||||
|  | ||||
|             executed_defers.add(defer_id) | ||||
|  | ||||
|             # Check if we've executed all 1000 defers (0-999) | ||||
|             # Track execution order per thread | ||||
|             if thread_id not in thread_executions: | ||||
|                 thread_executions[thread_id] = [] | ||||
|  | ||||
|             # Check FIFO ordering within thread | ||||
|             if ( | ||||
|                 defer_id == 999 | ||||
|                 and len(executed_defers) == 1000 | ||||
|                 and not test_complete_future.done() | ||||
|                 thread_executions[thread_id] | ||||
|                 and thread_executions[thread_id][-1] >= index | ||||
|             ): | ||||
|                 fifo_violations.append( | ||||
|                     f"Thread {thread_id}: index {index} executed after {thread_executions[thread_id][-1]}" | ||||
|                 ) | ||||
|  | ||||
|             thread_executions[thread_id].append(index) | ||||
|  | ||||
|             # Check if we've executed all 1000 defers (0-999) | ||||
|             if len(executed_defers) == 1000 and not test_complete_future.done(): | ||||
|                 test_complete_future.set_result(None) | ||||
|  | ||||
|     async with ( | ||||
| @@ -96,5 +112,22 @@ async def test_defer_stress( | ||||
|         missing_ids = expected_ids - executed_defers | ||||
|         assert not missing_ids, f"Missing defer IDs: {sorted(missing_ids)}" | ||||
|  | ||||
|         # If we got here without crashing, the test passed | ||||
|         assert True, "Test completed successfully - all 1000 defers executed in order" | ||||
|         # Verify FIFO ordering was maintained within each thread | ||||
|         assert not fifo_violations, "FIFO ordering violations detected:\n" + "\n".join( | ||||
|             fifo_violations[:10] | ||||
|         ) | ||||
|  | ||||
|         # Verify each thread executed all its defers in order | ||||
|         for thread_id, indices in thread_executions.items(): | ||||
|             assert len(indices) == 100, ( | ||||
|                 f"Thread {thread_id} executed {len(indices)} defers, expected 100" | ||||
|             ) | ||||
|             # Indices should be 0-99 in ascending order | ||||
|             assert indices == list(range(100)), ( | ||||
|                 f"Thread {thread_id} executed indices out of order: {indices[:10]}..." | ||||
|             ) | ||||
|  | ||||
|         # If we got here without crashing and with proper ordering, the test passed | ||||
|         assert True, ( | ||||
|             "Test completed successfully - all 1000 defers executed with FIFO ordering preserved" | ||||
|         ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user