Home | History | Annotate | Download | only in test
      1 /******************************************************************************
      2  *
      3  *  Copyright 2017 The Android Open Source Project
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include "btif/include/btif_state_machine.h"
     22 
     23 namespace {
     24 static constexpr uint32_t kInvalidEvent = 0xffffffff;
     25 static constexpr uint32_t kEventZero = 0;
     26 static constexpr uint32_t kEventOne = 1;
     27 static constexpr uint32_t kEventTwo = 2;
     28 
     29 static char dataZero = 0;
     30 static char dataOne = 1;
     31 static char dataTwo = 2;
     32 }  // namespace
     33 
     34 class BtifStateMachineImpl : public BtifStateMachine {
     35  public:
     36   enum {
     37     kStateZero,
     38     kStateOne,
     39     kStateTwo,
     40   };
     41 
     42   class StateZero : public State {
     43    public:
     44     StateZero(BtifStateMachine& sm)
     45         : State(sm, kStateZero),
     46           on_enter_(false),
     47           on_exit_(false),
     48           event_(kInvalidEvent),
     49           data_(nullptr) {}
     50     void OnEnter() override {
     51       on_enter_ = true;
     52       on_exit_ = false;
     53     }
     54     void OnExit() override {
     55       on_exit_ = true;
     56       on_enter_ = false;
     57     }
     58     bool ProcessEvent(uint32_t event, void* p_data) override {
     59       event_ = event;
     60       data_ = p_data;
     61       TransitionTo(kStateOne);
     62       return true;
     63     }
     64 
     65     bool on_enter_;
     66     bool on_exit_;
     67     uint32_t event_;
     68     void* data_;
     69   };
     70 
     71   class StateOne : public State {
     72    public:
     73     StateOne(BtifStateMachine& sm)
     74         : State(sm, kStateOne),
     75           on_enter_(false),
     76           on_exit_(false),
     77           event_(kInvalidEvent),
     78           data_(nullptr) {}
     79     void OnEnter() override {
     80       on_enter_ = true;
     81       on_exit_ = false;
     82     }
     83     void OnExit() override {
     84       on_exit_ = true;
     85       on_enter_ = false;
     86     }
     87     bool ProcessEvent(uint32_t event, void* p_data) override {
     88       event_ = event;
     89       data_ = p_data;
     90       TransitionTo(kStateTwo);
     91       return true;
     92     }
     93 
     94     bool on_enter_;
     95     bool on_exit_;
     96     uint32_t event_;
     97     void* data_;
     98   };
     99 
    100   class StateTwo : public State {
    101    public:
    102     StateTwo(BtifStateMachine& sm)
    103         : State(sm, kStateTwo),
    104           on_enter_(false),
    105           on_exit_(false),
    106           event_(kInvalidEvent),
    107           data_(nullptr) {}
    108     void OnEnter() override {
    109       on_enter_ = true;
    110       on_exit_ = false;
    111     }
    112     void OnExit() override {
    113       on_exit_ = true;
    114       on_enter_ = false;
    115     }
    116     bool ProcessEvent(uint32_t event, void* p_data) override {
    117       event_ = event;
    118       data_ = p_data;
    119       TransitionTo(kStateZero);
    120       return true;
    121     }
    122 
    123     bool on_enter_;
    124     bool on_exit_;
    125     uint32_t event_;
    126     void* data_;
    127   };
    128 
    129   BtifStateMachineImpl() {
    130     state_zero_ = new StateZero(*this);
    131     state_one_ = new StateOne(*this);
    132     state_two_ = new StateTwo(*this);
    133 
    134     AddState(state_zero_);
    135     AddState(state_one_);
    136     AddState(state_two_);
    137     SetInitialState(state_zero_);
    138   }
    139 
    140   StateZero* state_zero_;
    141   StateOne* state_one_;
    142   StateTwo* state_two_;
    143 };
    144 
    145 class BtifStateMachineTest : public ::testing::Test {
    146  protected:
    147   BtifStateMachineTest() {}
    148 
    149   void SetUp() override { sm_.Start(); }
    150 
    151   void TearDown() override { sm_.Quit(); }
    152 
    153   BtifStateMachineImpl sm_;
    154 };
    155 
    156 TEST_F(BtifStateMachineTest, test_initial_state) {
    157   ASSERT_EQ(sm_.kStateZero, sm_.StateId());
    158   ASSERT_EQ(sm_.kStateInvalid, sm_.PreviousStateId());
    159 }
    160 
    161 TEST_F(BtifStateMachineTest, test_invalid_state) {
    162   sm_.Quit();
    163   ASSERT_EQ(sm_.kStateInvalid, sm_.StateId());
    164   ASSERT_EQ(sm_.kStateInvalid, sm_.PreviousStateId());
    165   sm_.Start();
    166   ASSERT_EQ(sm_.kStateZero, sm_.StateId());
    167   ASSERT_EQ(sm_.kStateInvalid, sm_.PreviousStateId());
    168 }
    169 
    170 TEST_F(BtifStateMachineTest, test_transition_to) {
    171   // Initial state: StateZero
    172   ASSERT_EQ(sm_.kStateZero, sm_.StateId());
    173   ASSERT_EQ(sm_.kStateInvalid, sm_.PreviousStateId());
    174   ASSERT_TRUE(sm_.state_zero_->on_enter_);
    175   ASSERT_FALSE(sm_.state_zero_->on_exit_);
    176 
    177   // Transition to StateOne
    178   ASSERT_FALSE(sm_.state_one_->on_enter_);
    179   ASSERT_FALSE(sm_.state_one_->on_exit_);
    180   sm_.TransitionTo(sm_.kStateOne);
    181   ASSERT_EQ(sm_.kStateOne, sm_.StateId());
    182   ASSERT_EQ(sm_.kStateZero, sm_.PreviousStateId());
    183   ASSERT_TRUE(sm_.state_zero_->on_exit_);
    184   ASSERT_TRUE(sm_.state_one_->on_enter_);
    185   ASSERT_FALSE(sm_.state_one_->on_exit_);
    186 
    187   // Transition to StateTwo
    188   ASSERT_FALSE(sm_.state_two_->on_enter_);
    189   ASSERT_FALSE(sm_.state_two_->on_exit_);
    190   sm_.TransitionTo(sm_.kStateTwo);
    191   ASSERT_EQ(sm_.kStateTwo, sm_.StateId());
    192   ASSERT_EQ(sm_.kStateOne, sm_.PreviousStateId());
    193   ASSERT_TRUE(sm_.state_one_->on_exit_);
    194   ASSERT_TRUE(sm_.state_two_->on_enter_);
    195   ASSERT_FALSE(sm_.state_two_->on_exit_);
    196 }
    197 
    198 TEST_F(BtifStateMachineTest, test_process_event) {
    199   // Initial state: StateZero
    200   ASSERT_EQ(sm_.kStateZero, sm_.StateId());
    201   ASSERT_EQ(sm_.kStateInvalid, sm_.PreviousStateId());
    202   ASSERT_TRUE(sm_.state_zero_->on_enter_);
    203   ASSERT_FALSE(sm_.state_zero_->on_exit_);
    204   ASSERT_EQ(sm_.state_zero_->event_, kInvalidEvent);
    205   ASSERT_EQ(sm_.state_zero_->data_, nullptr);
    206 
    207   // Process an event and transition to StateOne
    208   ASSERT_FALSE(sm_.state_one_->on_enter_);
    209   ASSERT_FALSE(sm_.state_one_->on_exit_);
    210   ASSERT_EQ(sm_.state_one_->event_, kInvalidEvent);
    211   ASSERT_EQ(sm_.state_one_->data_, nullptr);
    212   ASSERT_TRUE(sm_.ProcessEvent(kEventZero, &dataZero));
    213   ASSERT_EQ(sm_.kStateOne, sm_.StateId());
    214   ASSERT_EQ(sm_.kStateZero, sm_.PreviousStateId());
    215   // Check StateZero
    216   ASSERT_EQ(sm_.state_zero_->event_, kEventZero);
    217   ASSERT_EQ(sm_.state_zero_->data_, &dataZero);
    218   ASSERT_TRUE(sm_.state_zero_->on_exit_);
    219   // Check StateOne
    220   ASSERT_TRUE(sm_.state_one_->on_enter_);
    221   ASSERT_FALSE(sm_.state_one_->on_exit_);
    222   ASSERT_EQ(sm_.state_one_->event_, kInvalidEvent);
    223   ASSERT_EQ(sm_.state_one_->data_, nullptr);
    224 
    225   // Process an event and transition to StateTwo
    226   ASSERT_FALSE(sm_.state_two_->on_enter_);
    227   ASSERT_FALSE(sm_.state_two_->on_exit_);
    228   ASSERT_EQ(sm_.state_two_->event_, kInvalidEvent);
    229   ASSERT_EQ(sm_.state_two_->data_, nullptr);
    230   ASSERT_TRUE(sm_.ProcessEvent(kEventOne, &dataOne));
    231   ASSERT_EQ(sm_.kStateTwo, sm_.StateId());
    232   ASSERT_EQ(sm_.kStateOne, sm_.PreviousStateId());
    233   // Check StateOne
    234   ASSERT_EQ(sm_.state_one_->event_, kEventOne);
    235   ASSERT_EQ(sm_.state_one_->data_, &dataOne);
    236   ASSERT_TRUE(sm_.state_one_->on_exit_);
    237   // Check StateTwo
    238   ASSERT_TRUE(sm_.state_two_->on_enter_);
    239   ASSERT_FALSE(sm_.state_two_->on_exit_);
    240   ASSERT_EQ(sm_.state_two_->event_, kInvalidEvent);
    241   ASSERT_EQ(sm_.state_two_->data_, nullptr);
    242 
    243   // Process an event and transition to StateZero
    244   // NOTE: StateZero was exited before and has local state
    245   ASSERT_FALSE(sm_.state_zero_->on_enter_);
    246   ASSERT_TRUE(sm_.state_zero_->on_exit_);  // NOTE: already exited before
    247   ASSERT_EQ(sm_.state_zero_->event_, kEventZero);  // NOTE: state from before
    248   ASSERT_EQ(sm_.state_zero_->data_, &dataZero);    // NOTE: state from before
    249   ASSERT_TRUE(sm_.ProcessEvent(kEventTwo, &dataTwo));
    250   ASSERT_EQ(sm_.kStateZero, sm_.StateId());
    251   ASSERT_EQ(sm_.kStateTwo, sm_.PreviousStateId());
    252   // Check StateTwo
    253   ASSERT_EQ(sm_.state_two_->event_, kEventTwo);
    254   ASSERT_EQ(sm_.state_two_->data_, &dataTwo);
    255   ASSERT_TRUE(sm_.state_two_->on_exit_);
    256   // Check StateZero
    257   ASSERT_TRUE(sm_.state_zero_->on_enter_);
    258   ASSERT_FALSE(sm_.state_zero_->on_exit_);
    259   ASSERT_EQ(sm_.state_zero_->event_, kEventZero);  // NOTE: state from before
    260   ASSERT_EQ(sm_.state_zero_->data_, &dataZero);    // NOTE: state from before
    261 }
    262