From 59cd911a83897796599c5a5e09b67a5ee36906b5 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Mon, 1 Sep 2025 19:49:51 +0800 Subject: [PATCH] refactor(examples/classic_bt): Add example tests for A2DP and AVRCP examples --- examples/bluetooth/.build-test-rules.yml | 3 + .../classic_bt/pytest_classic_bt_test.py | 87 ++++++++++++------- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index 69caebef10..d0e2fdb7fe 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -63,6 +63,7 @@ examples/bluetooth/bluedroid/classic_bt: disable: - if: SOC_BT_CLASSIC_SUPPORTED != 1 depends_components+: + - esp_lcd - esp_console - esp_driver_gpio - esp_driver_i2s @@ -73,6 +74,8 @@ examples/bluetooth/bluedroid/classic_bt: - components/driver/dac/**/* - examples/bluetooth/bluedroid/esp_hid_host/**/* - examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py + - examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/pytest_classic_bt_cover_art_test.py + - examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/pytest_classic_bt_metadata_test.py - examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py examples/bluetooth/bluedroid/coex/a2dp_gatts_coex: diff --git a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py index 3190035c38..acd55d9f75 100644 --- a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py +++ b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py @@ -72,34 +72,7 @@ def test_bt_spp_vfs(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: acceptor.expect_exact('ESP_SPP_SRV_OPEN_EVT status:0', timeout=30) -# Case 3: A2DP -@pytest.mark.two_duts -@pytest.mark.parametrize( - 'count, app_path, target, config', - [ - ( - 2, - f'{os.path.join(os.path.dirname(__file__), "a2dp_sink")}|' - f'{os.path.join(os.path.dirname(__file__), "a2dp_source")}', - 'esp32|esp32', - 'test', - ), - ], - indirect=True, -) -def test_bt_a2dp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: - sink_dut = dut[0] - source_dut = dut[1] - source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') - sink_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30) - source_dut.expect_exact('a2dp connecting to peer', timeout=30) - source_dut.expect_exact('a2dp connected', timeout=30) - source_dut.expect_exact('a2dp media start successfully', timeout=30) - sink_dut.expect_exact(f'A2DP connection state: Connected, [{source_dut_mac}]', timeout=30) - sink_dut.expect_exact('start volume change simulation', timeout=30) - - -# Case 4: HFP +# Case 3: HFP @pytest.mark.two_duts @pytest.mark.parametrize( 'count, app_path, target, config', @@ -124,7 +97,7 @@ def test_bt_hfp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: hfp_ag.expect_exact('connection state SLC_CONNECTED', timeout=30) -# # Case 5: HID +# # Case 4: HID @pytest.mark.two_duts @pytest.mark.parametrize( 'count, app_path, target, config', @@ -153,7 +126,7 @@ def test_bt_hid(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: hid_host.expect_exact(f'ESP_HIDH_DEMO: {hid_device_mac} OPEN', timeout=30) -# Case 6: L2CAP +# Case 5: L2CAP @pytest.mark.two_duts @pytest.mark.parametrize( 'count, app_path, target, config', @@ -182,3 +155,57 @@ def test_bt_l2cap(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: client.expect_exact('ESP_SDP_SEARCH_COMP_EVT: status:0', timeout=30) client.expect_exact('ESP_BT_L2CAP_OPEN_EVT: status:0', timeout=30) server.expect_exact('ESP_BT_L2CAP_OPEN_EVT: status:0', timeout=30) + + +# case 6: A2DP Stream +@pytest.mark.two_duts +@pytest.mark.parametrize( + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "a2dp_sink_stream")}|' + f'{os.path.join(os.path.dirname(__file__), "a2dp_source")}', + 'esp32|esp32', + 'test', + ), + ], + indirect=True, +) +def test_bt_a2dp_stream(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + sink_dut = dut[0] + source_dut = dut[1] + source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + sink_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30) + source_dut.expect_exact('a2dp connecting to peer', timeout=30) + source_dut.expect_exact('a2dp connected', timeout=30) + source_dut.expect_exact('a2dp media start successfully', timeout=30) + sink_dut.expect_exact(f'A2DP connection state: Connected, [{source_dut_mac}]', timeout=30) + + +# case 7: AVRCP absolute volume +@pytest.mark.two_duts +@pytest.mark.parametrize( + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "avrcp_absolute_volume")}|' + f'{os.path.join(os.path.dirname(__file__), "a2dp_source")}', + 'esp32|esp32', + 'test', + ), + ], + indirect=True, +) +def test_bt_avrcp_absolute_volume(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + sink_dut = dut[0] + source_dut = dut[1] + source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + sink_dut.expect_exact('AVRCP CT STATE: Init Complete', timeout=30) + sink_dut.expect_exact('AVRCP TG STATE: Init Complete', timeout=30) + source_dut.expect_exact('a2dp connecting to peer', timeout=30) + source_dut.expect_exact('a2dp connected', timeout=30) + sink_dut.expect_exact(f'AVRC conn_state event: state 1, [{source_dut_mac}]', timeout=30) + sink_dut.expect_exact(f'AVRC conn_state evt: state 1, [{source_dut_mac}]', timeout=30) + sink_dut.expect_exact('start volume change simulation', timeout=30)