Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53c559af authored by Jack He's avatar Jack He
Browse files

RFCOMM: Add unit tests for connection scenarios

Unit tests:
* Add net_test_stack_rfcomm
* Use a compiler trick to compile production RFCOMM code against L2CAP
  and BTM header, but fake L2CAP and BTM source code so that we can stub
  statically defined L2CAP and BTM code using mocks
* Rename net_test_rfcomm to net_test_rfcomm_suite
* Add mocked L2CAP and BTM layer to allow packet replay from L2CAP layer
  to RFCOMM layer in order to reproduce time dependent issues such as
  connection collision
* Add a number of utility methods that generates RFCOMM packet bytes
  using supported parameters
* Add unit test for above utility methods
* Add suite of unit tests named StackRfcommTest, including:
 - SingleServerConnectionHelloWorld
 - MultiServerPortSameDeviceHelloWorld
 - SameServerPortMultiDeviceHelloWorld
 - SingleClientConnectionHelloWorld
 - SameClientPortMultiDeviceHelloWorld
* These tests supply L2CAP packets and API calls to trigger RFCOMM
  connection setup in various scenarios
* Added logging method to output debug log via VLOG(1) logging level and
  allow compile time configuration of these logs through a constant flag

Bug: 77224743
Test: ./test/run_unit_tests.sh net_test_stack_rfcomm
      testplans/details/158641/3975
Change-Id: I9d59843603cd36394c3736670bcf3c39dea26674
Merged-In: I9d59843603cd36394c3736670bcf3c39dea26674
(cherry picked from commit 9b423ecfc85f22d355d9f10b347083f9d9bfe02d)
parent 75517219
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -197,7 +197,9 @@ cc_test {
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/internal_include",
    ],
    srcs: ["test/stack_a2dp_test.cc"],
    srcs: [
        "test/stack_a2dp_test.cc",
    ],
    shared_libs: [
        "libhidlbase",
        "liblog",
@@ -221,6 +223,56 @@ cc_test {
    ],
}

cc_test {
  name: "net_test_stack_rfcomm",
  defaults: ["fluoride_defaults"],
  host_supported: true,
  local_include_dirs: [
      "include",
      "btm",
      "l2cap",
      "smp",
      "rfcomm",
      "test/common",
  ],
  include_dirs: [
      "packages/modules/Bluetooth/system",
      "packages/modules/Bluetooth/system/internal_include",
      "packages/modules/Bluetooth/system/btcore/include",
      "packages/modules/Bluetooth/system/hci/include",
      "packages/modules/Bluetooth/system/utils/include",
  ],
  srcs: [
      "rfcomm/port_api.cc",
      "rfcomm/port_rfc.cc",
      "rfcomm/port_utils.cc",
      "rfcomm/rfc_l2cap_if.cc",
      "rfcomm/rfc_mx_fsm.cc",
      "rfcomm/rfc_port_fsm.cc",
      "rfcomm/rfc_port_if.cc",
      "rfcomm/rfc_ts_frames.cc",
      "rfcomm/rfc_utils.cc",
      "test/common/mock_btm_layer.cc",
      "test/common/mock_btu_layer.cc",
      "test/common/mock_l2cap_layer.cc",
      "test/common/stack_test_packet_utils.cc",
      "test/rfcomm/stack_rfcomm_test.cc",
      "test/rfcomm/stack_rfcomm_test_main.cc",
      "test/rfcomm/stack_rfcomm_test_utils.cc",
      "test/rfcomm/stack_rfcomm_test_utils_test.cc",
  ],
  shared_libs: [
      "libcutils",
      "libprotobuf-cpp-lite",
  ],
  static_libs: [
      "liblog",
      "libgmock",
      "libosi",
      "libbt-protos-lite",
  ],
}

// Bluetooth stack smp unit tests for target
// ========================================================
cc_test {
+45 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2018 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#include "mock_btm_layer.h"

static bluetooth::manager::MockBtmSecurityInternalInterface*
    btm_security_internal_interface = nullptr;

void bluetooth::manager::SetMockSecurityInternalInterface(
    MockBtmSecurityInternalInterface* mock_btm_security_internal_interface) {
  btm_security_internal_interface = mock_btm_security_internal_interface;
}

void btm_sec_abort_access_req(const RawAddress& bd_addr) {
  btm_security_internal_interface->AbortAccessRequest(bd_addr);
}

tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, uint16_t psm,
                                      bool is_originator, uint32_t mx_proto_id,
                                      uint32_t mx_chan_id,
                                      tBTM_SEC_CALLBACK* p_callback,
                                      void* p_ref_data) {
  return btm_security_internal_interface->MultiplexingProtocolAccessRequest(
      bd_addr, psm, is_originator, mx_proto_id, mx_chan_id, p_callback,
      p_ref_data);
}

uint16_t btm_get_max_packet_size(const RawAddress& addr) {
  return RFCOMM_DEFAULT_MTU;
}
 No newline at end of file
+57 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2018 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/
#pragma once

#include <gmock/gmock.h>

#include "btm_int.h"

namespace bluetooth {
namespace manager {

class BtmSecurityInternalInterface {
 public:
  virtual void AbortAccessRequest(const RawAddress& bd_addr) = 0;
  virtual tBTM_STATUS MultiplexingProtocolAccessRequest(
      const RawAddress& bd_addr, uint16_t psm, bool is_originator,
      uint32_t mx_proto_id, uint32_t mx_chan_id, tBTM_SEC_CALLBACK* p_callback,
      void* p_ref_data) = 0;
  virtual ~BtmSecurityInternalInterface() = default;
};

class MockBtmSecurityInternalInterface : public BtmSecurityInternalInterface {
 public:
  MOCK_METHOD1(AbortAccessRequest, void(const RawAddress& bd_addr));
  MOCK_METHOD7(MultiplexingProtocolAccessRequest,
               tBTM_STATUS(const RawAddress& bd_addr, uint16_t psm,
                           bool is_originator, uint32_t mx_proto_id,
                           uint32_t mx_chan_id, tBTM_SEC_CALLBACK* p_callback,
                           void* p_ref_data));
};

/**
 * Set the {@link MockBtmSecurityInternalInterface} for testing
 *
 * @param mock_btm_security_internal_interface pointer to mock btm security
 * internal interface, could be null
 */
void SetMockSecurityInternalInterface(
    MockBtmSecurityInternalInterface* mock_btm_security_internal_interface);

}  // namespace manager
}  // namespace bluetooth
 No newline at end of file
+21 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2018 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#include <base/message_loop/message_loop.h>

base::MessageLoop* get_message_loop() { return nullptr; }
 No newline at end of file
+59 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2018 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/
#include "mock_l2cap_layer.h"

static bluetooth::l2cap::MockL2capInterface* l2cap_interface = nullptr;

void bluetooth::l2cap::SetMockInterface(
    MockL2capInterface* mock_l2cap_interface) {
  l2cap_interface = mock_l2cap_interface;
}

uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) {
  VLOG(1) << __func__ << ": psm=" << psm << ", p_cb_info=" << p_cb_info;
  return l2cap_interface->Register(psm, p_cb_info);
}

uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& bd_addr) {
  return l2cap_interface->ConnectRequest(psm, bd_addr);
}

bool L2CA_ConnectRsp(const RawAddress& bd_addr, uint8_t id, uint16_t lcid,
                     uint16_t result, uint16_t status) {
  return l2cap_interface->ConnectResponse(bd_addr, id, lcid, result, status);
}

bool L2CA_DisconnectReq(uint16_t cid) {
  return l2cap_interface->DisconnectRequest(cid);
}

bool L2CA_DisconnectRsp(uint16_t cid) {
  return l2cap_interface->DisconnectResponse(cid);
}

bool L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
  return l2cap_interface->ConfigRequest(cid, p_cfg);
}

bool L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
  return l2cap_interface->ConfigResponse(cid, p_cfg);
}

uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
  return l2cap_interface->DataWrite(cid, p_data);
}
Loading