| // Copyright 2015 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <map> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "gtest/gtest.h" |
| |
| #include "thermald/thermal_state_engine.h" |
| #include "thermald/thermal_zone.h" |
| |
| using std::make_pair; |
| using std::string; |
| using std::vector; |
| |
| namespace thermald { |
| |
| static const char *kTemp0Name = "temperature 0"; |
| static const char *kTemp1Name = "temperature 1"; |
| |
| static const int kSt2S0ActThld = 60000; |
| static const int kSt2S0BotThld = 55000; |
| static const int kSt2S1ActThld = 70000; |
| static const int kSt2S1BotThld = 65000; |
| |
| static const int kSt3S0ActThld = 70000; |
| static const int kSt3S0BotThld = 65000; |
| static const int kSt3S1ActThld = 80000; |
| static const int kSt3S1BotThld = 75000; |
| |
| static const int kSt4S0ActThld = 80000; |
| static const int kSt4S0BotThld = 75000; |
| static const int kSt4S1ActThld = kTempInfinite; // No activation threshold |
| static const int kSt4S1BotThld = kTemp0K; // No bottom threshold |
| |
| static const int kSt5S0ActThld = 90000; |
| static const int kSt5S0BotThld = 85000; |
| static const int kSt5S1ActThld = 100000; |
| static const int kSt5S1BotThld = 95000; |
| |
| // Test case for ThermalStateEngine monitoring a single temperature. |
| class ThermalStateEngineSingleTemperatureTest : public testing::Test { |
| protected: |
| ThermalStateEngineSingleTemperatureTest() : state_engine_(&thermal_zone_) {} |
| |
| static void SetUpTestCase(); |
| static void AddThermalState(int state_id, int activation_threshold, |
| int bottom_threshold); |
| |
| static ThermalZone thermal_zone_; |
| ThermalStateEngine state_engine_; |
| }; |
| |
| class ThermalStateEngineSingleTemperatureInitialTransitionTest : |
| public ThermalStateEngineSingleTemperatureTest {}; |
| |
| ThermalZone ThermalStateEngineSingleTemperatureTest::thermal_zone_; |
| |
| void ThermalStateEngineSingleTemperatureTest::AddThermalState( |
| int state_id, int activation_threshold, int bottom_threshold) { |
| std::unique_ptr<ThermalState> state = std::make_unique<ThermalState>(); |
| ThermalPointThresholds thresholds; |
| |
| state->id = state_id; |
| thresholds.activation = activation_threshold; |
| thresholds.bottom = bottom_threshold; |
| state->thresholds.insert(make_pair(kTemp0Name, thresholds)); |
| thermal_zone_.states.push_back(std::move(state)); |
| } |
| |
| void ThermalStateEngineSingleTemperatureTest::SetUpTestCase() { |
| thermal_zone_.name = "single temp zone"; |
| |
| // Set up from higher to lower criticality/temperatures. |
| AddThermalState(3, kSt3S0ActThld, kSt3S0BotThld); |
| AddThermalState(2, kSt2S0ActThld, kSt2S0BotThld); |
| AddThermalState(1, kTemp0K, kTemp0K); |
| } |
| |
| // Verify for the initial transition that the lowest temperature state is |
| // entered if the temperature is below the activation threshold of the next |
| // state. |
| TEST_F(ThermalStateEngineSingleTemperatureInitialTransitionTest, |
| TemperatureBelowActivationThresholdOfSecondState) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify for the initial transition that an intermediate state is entered if |
| // the temperature is at the activation threshold of the state. |
| TEST_F(ThermalStateEngineSingleTemperatureInitialTransitionTest, |
| TemperatureAtActivationThreshold) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify for the initial transition that an intermediate state is entered if |
| // the temperature is above the activation threshold of the state and below the |
| // activation threshold of the next state. |
| TEST_F(ThermalStateEngineSingleTemperatureInitialTransitionTest, |
| TemperatureAboveActivationThreshold) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld - 1); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify for the initial transition that the highest temperature state is |
| // entered if the temperature is at the activation threshold of the state. |
| TEST_F(ThermalStateEngineSingleTemperatureInitialTransitionTest, |
| TemperatureAtActivationThresholdOfHighestState) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(3, state_engine_.current_state().id); |
| } |
| |
| // Verify for the initial transition that the highest temperature state is |
| // entered if the temperature is above the activation threshold of the state. |
| TEST_F(ThermalStateEngineSingleTemperatureInitialTransitionTest, |
| TemperatureAboveActivationThresholdOfHighestState) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, |
| kSt3S0ActThld + 5000); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(3, state_engine_.current_state().id); |
| } |
| |
| // Verify that no transition to a higher state occurs when the temperature is |
| // just below the activation threshold of the higher state state. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| TemperatureJustBelowActivationThreshold) { |
| bool rc; |
| int initial_state; |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld - 1); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that no transition to a lower state occurs when the temperature is |
| // just above the bottom threshold of the current state. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| TemperatureJustAboveBottomThreshold) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0BotThld + 1); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that a higher state is entered when the temperature is at the |
| // activation threshold of the state. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| TemperatureRisesToActivationThreshold) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that a higher state is entered when the temperature is above the |
| // activation threshold of the state. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| TemperatureRisesAboveActivationThreshold) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, |
| kSt2S0ActThld + 1000); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that a lower state is entered when the temperature is at the bottom |
| // threshold of the current state. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| TemperatureDropsToBottomThreshold) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0BotThld); |
| |
| ASSERT_EQ(3, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that a lower state is entered when the temperature is below |
| // the bottom threshold of the current state. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| TemperatureDropsBelowBottomThreshold) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0BotThld - 1); |
| |
| ASSERT_EQ(3, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify [cur_state + 2] is entered directly when the activation |
| // threshold of that state is reached. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| SuddenTemperatureRise) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(3, state_engine_.current_state().id); |
| } |
| |
| // Verify [cur_state - 2] is entered directly when the bottom threshold |
| // of [cur_state - 1] is reached. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| SuddenTemperatureDrop) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld); |
| |
| ASSERT_EQ(3, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify that the lowest state is active at a very low temperature. |
| TEST_F(ThermalStateEngineSingleTemperatureTest, |
| VeryLowTemperature) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, -260000); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Test case for ThermalStateEngine monitoring multiple temperatures. |
| class ThermalStateEngineMultipleTemperaturesTest : public testing::Test { |
| protected: |
| ThermalStateEngineMultipleTemperaturesTest() |
| : state_engine_(&thermal_zone_) {} |
| |
| static void SetUpTestCase(); |
| static void AddThermalState(int state_id, |
| int activation_threshold_0, |
| int bottom_threshold_0, |
| int activation_threshold_1, |
| int bottom_threshold_1); |
| |
| static ThermalZone thermal_zone_; |
| ThermalStateEngine state_engine_; |
| }; |
| |
| class ThermalStateEngineMultipleTemperaturesInitialTransitionTest : |
| public ThermalStateEngineMultipleTemperaturesTest {}; |
| |
| class ThermalStateEngineMultipleTemperaturesNoThresholdsTest : |
| public ThermalStateEngineMultipleTemperaturesTest {}; |
| |
| ThermalZone ThermalStateEngineMultipleTemperaturesTest::thermal_zone_; |
| |
| void ThermalStateEngineMultipleTemperaturesTest::AddThermalState( |
| int state_id, |
| int activation_threshold_0, int bottom_threshold_0, |
| int activation_threshold_1, int bottom_threshold_1) { |
| std::unique_ptr<ThermalState> state = std::make_unique<ThermalState>(); |
| ThermalPointThresholds thresholds; |
| |
| state->id = state_id; |
| |
| thresholds.activation = activation_threshold_0; |
| thresholds.bottom = bottom_threshold_0; |
| state->thresholds.insert(make_pair(kTemp0Name, thresholds)); |
| |
| thresholds.activation = activation_threshold_1; |
| thresholds.bottom = bottom_threshold_1; |
| state->thresholds.insert(make_pair(kTemp1Name, thresholds)); |
| |
| thermal_zone_.states.push_back(std::move(state)); |
| } |
| |
| void ThermalStateEngineMultipleTemperaturesTest::SetUpTestCase() { |
| thermal_zone_.name = "multi temp zone"; |
| |
| // Set up from higher to lower criticality/temperatures. |
| AddThermalState(5, kSt5S0ActThld, kSt5S0BotThld, kSt5S1ActThld, |
| kSt5S1BotThld); |
| AddThermalState(4, kSt4S0ActThld, kSt4S0BotThld, kSt4S1ActThld, |
| kSt4S1BotThld); |
| AddThermalState(3, kSt3S0ActThld, kSt3S0BotThld, kSt3S1ActThld, |
| kSt3S1BotThld); |
| AddThermalState(2, kSt2S0ActThld, kSt2S0BotThld, kSt2S1ActThld, |
| kSt2S1BotThld); |
| AddThermalState(1, kTemp0K, kTemp0K, kTemp0K, kTemp0K); |
| } |
| |
| // Verify for the initial transition that the lowest temperature state is |
| // entered when the first reported temperature is below the activation |
| // threshold of the next state. |
| TEST_F(ThermalStateEngineMultipleTemperaturesInitialTransitionTest, |
| TemperatureBelowActivationThresholdOfSecondState) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld - 1); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify for the initial transition that a the correct thermal state is entered |
| // when the first reported temperature is at the activation threshold of the |
| // state (not the lowest temperature state). |
| TEST_F(ThermalStateEngineMultipleTemperaturesInitialTransitionTest, |
| TemperatureAtActivationThreshold) { |
| bool rc; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify for the initial transitions that the lowest temperature state is |
| // active when all temperatures are below the activation threshold of the next |
| // state. |
| TEST_F(ThermalStateEngineMultipleTemperaturesInitialTransitionTest, |
| AllTemperaturesBelowActivationThresholdsOfSecondState) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld - 1); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify that a temperature without any readings is treated as a |
| // very low temperature. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| TreatsUnkownTemperatureAsVeryLow) { |
| bool rc[3]; |
| int state[2]; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc[0] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| state[0] = state_engine_.current_state().id; |
| rc[1] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| state[1] = state_engine_.current_state().id; |
| rc[2] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0BotThld); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc[0]); |
| ASSERT_EQ(2, state[0]); |
| ASSERT_TRUE(rc[1]); |
| ASSERT_EQ(3, state[1]); |
| ASSERT_TRUE(rc[2]); |
| ASSERT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that a thermal state is entered when one of the temperatures |
| // reaches the activation threshold of that state. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| SingleTemperatureAtActivationThreshold) { |
| bool rc; |
| int initial_state; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc); |
| EXPECT_EQ(2, state_engine_.current_state().id); |
| } |
| |
| // Verify that a lower thermal state is entered only when all temperatures |
| // which were at/above the activation threshold of the current state reach |
| // the bottom threshold of the current state. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| AllBottomThresholdsMustBeReached) { |
| int initial_state; |
| bool rc[7]; |
| int state[6]; |
| |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 0 just above bottom threshold. |
| rc[0] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld + 1); |
| state[0] = state_engine_.current_state().id; |
| // Temperature 1 just above bottom threshold. |
| rc[1] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld + 1); |
| state[1] = state_engine_.current_state().id; |
| // Temperature 0 reaches bottom threshold. |
| rc[2] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld); |
| state[2] = state_engine_.current_state().id; |
| // Temperature 1 reaches bottom threshold => state 1. |
| rc[3] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld); |
| state[3] = state_engine_.current_state().id; |
| |
| // Only one of the temperatures exceeds activation threshold. |
| |
| // Temperature 1 reaches state 2 activation threshold again. |
| rc[4] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| state[4] = state_engine_.current_state().id; |
| // Temperature 1 just above bottom threshold. |
| rc[5] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld + 1); |
| state[5] = state_engine_.current_state().id; |
| // Temperature 1 reaches bottom threshold => state 1. |
| rc[6] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc[0]); |
| ASSERT_EQ(2, state[0]); |
| ASSERT_TRUE(rc[1]); |
| ASSERT_EQ(2, state[1]); |
| ASSERT_TRUE(rc[2]); |
| ASSERT_EQ(2, state[2]); |
| ASSERT_TRUE(rc[3]); |
| ASSERT_EQ(1, state[3]); |
| ASSERT_TRUE(rc[4]); |
| ASSERT_EQ(2, state[4]); |
| ASSERT_TRUE(rc[5]); |
| ASSERT_EQ(2, state[5]); |
| ASSERT_TRUE(rc[6]); |
| ASSERT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify that for a transition to a lower state it is sufficient that a |
| // temperature reaches the bottom threshold of the active state once, it |
| // may rise afterwards above the threshold as long as it stays below the |
| // activation threshold of the current state. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| TemperatureRisesAgainAboveBottomThreshold) { |
| int initial_state; |
| bool rc[3]; |
| int state[2]; |
| |
| // Start in state 2, with both temperatures >= activation threshold. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 0 reaches bottom threshold. |
| rc[0] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld); |
| state[0] = state_engine_.current_state().id; |
| // Temperature 0 rises again, but stays below the activation threshold of |
| // state 2. |
| rc[1] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| state[1] = state_engine_.current_state().id; |
| // Temperature 1 reaches bottom threshold => state 1. |
| rc[2] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc[0]); |
| ASSERT_EQ(2, state[0]); |
| ASSERT_TRUE(rc[1]); |
| ASSERT_EQ(2, state[1]); |
| ASSERT_TRUE(rc[2]); |
| ASSERT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify that for a transition to a lower state a temperature need to reach |
| // the bottom threshold again if it rose to the activation threshold after |
| // the prior drop to the bottom threshold. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| TemperatureRisesToActivationThresholdAfterReachingBottomThreshold) { |
| int initial_state; |
| bool rc[4]; |
| int state[3]; |
| |
| // Start in state 2, with both temperatures at/above activation threshold. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 0 reaches bottom threshold. |
| rc[0] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld); |
| state[0] = state_engine_.current_state().id; |
| // Temperature 0 rises to the activation threshold. |
| rc[1] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| state[1] = state_engine_.current_state().id; |
| // Temperature 1 reaches bottom threshold. |
| rc[2] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld); |
| state[2] = state_engine_.current_state().id; |
| // Temperature 0 reaches the bottom threshold again => state 1. |
| rc[3] =state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc[0]); |
| ASSERT_EQ(2, state[0]); |
| ASSERT_TRUE(rc[1]); |
| ASSERT_EQ(2, state[1]); |
| ASSERT_TRUE(rc[2]); |
| ASSERT_EQ(2, state[2]); |
| ASSERT_TRUE(rc[3]); |
| ASSERT_EQ(1, state_engine_.current_state().id); |
| } |
| |
| // Verify [cur_state + 2] is entered directly when an activation |
| // threshold of that state is reached. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| SuddenTemperatureRise) { |
| bool rc; |
| int initial_state; |
| |
| // Start in state 1. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld - 1); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld - 1); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 0 at activation threshold of state 3 => state 3. |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| |
| ASSERT_EQ(1, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(3, state_engine_.current_state().id); |
| } |
| |
| // Verify [cur_state - 2] is entered directly when all temperatures |
| // have reached the bottom thresholds of [cur_state - 1]. |
| TEST_F(ThermalStateEngineMultipleTemperaturesTest, |
| SuddenTemperatureDrop) { |
| int initial_state; |
| bool rc[2]; |
| int state[2]; |
| |
| // Start in state 3 with both temperatures >= activation threshold. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt3S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // First temperature reaches bottom threshold. |
| rc[0] = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0BotThld); |
| state[0] = state_engine_.current_state().id; |
| // Second temperature reaches bottom threshold => state 1. |
| rc[1] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1BotThld); |
| state[1] = state_engine_.current_state().id; |
| |
| ASSERT_EQ(3, initial_state); |
| ASSERT_TRUE(rc[0]); |
| ASSERT_EQ(3, state[0]); |
| ASSERT_TRUE(rc[1]); |
| ASSERT_EQ(1, state[1]); |
| } |
| |
| // Verify that a thermal state without thresholds for a temperature is |
| // skipped upon changes of only this temperature. |
| TEST_F(ThermalStateEngineMultipleTemperaturesNoThresholdsTest, |
| SkipsStateWithoutThresholds) { |
| int initial_state; |
| bool rc[3]; |
| int state[2]; |
| |
| // Start in state 2, with both temperatures >= activation threshold. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt2S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt2S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 1 just below the activation threshold of state 5 => state 3. |
| rc[0] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt5S1ActThld - 1); |
| state[0] = state_engine_.current_state().id; |
| // Temperature 1 reaches activation threshold of state 5 => state 5. |
| rc[1] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt5S1ActThld); |
| state[1] = state_engine_.current_state().id; |
| // Temperature 1 reaches bottom threshold of state 5 => state 3. |
| rc[2] = state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt5S1BotThld); |
| |
| ASSERT_EQ(2, initial_state); |
| ASSERT_TRUE(rc[0]); |
| ASSERT_EQ(3, state[0]); |
| ASSERT_TRUE(rc[1]); |
| ASSERT_EQ(5, state[1]); |
| ASSERT_TRUE(rc[2]); |
| ASSERT_EQ(3, state_engine_.current_state().id); |
| } |
| |
| // Verify that a thermal state without thresholds for a temperature is |
| // entered when the activation thresholds of other temperatures are |
| // reached. |
| TEST_F(ThermalStateEngineMultipleTemperaturesNoThresholdsTest, |
| OtherTemperatureReachesActivationThreshold) { |
| bool rc; |
| int initial_state; |
| |
| // Start in state 3 with both temperatures >= activation threshold. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt3S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt3S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 0 reaches activation threshold of state 4 => state 4. |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt4S0ActThld); |
| |
| ASSERT_EQ(3, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(4, state_engine_.current_state().id); |
| } |
| |
| // Verify that a thermal state without thresholds for a temperature is |
| // left when the bottom thresholds of other temperatures are reached. |
| TEST_F(ThermalStateEngineMultipleTemperaturesNoThresholdsTest, |
| OtherTemperatureReachesBottomThreshold) { |
| bool rc; |
| int initial_state; |
| |
| // Start in state 4, with temperature 0 at activation threshold and |
| // temperature 1 at the activation thresold of state 3. |
| state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt4S0ActThld); |
| state_engine_.ProcessTemperatureUpdate(kTemp1Name, kSt3S1ActThld); |
| initial_state = state_engine_.current_state().id; |
| |
| // Temperature 0 reaches bottom threshold of state 4 => state 3. |
| rc = state_engine_.ProcessTemperatureUpdate(kTemp0Name, kSt4S0BotThld); |
| |
| ASSERT_EQ(4, initial_state); |
| ASSERT_TRUE(rc); |
| ASSERT_EQ(3, state_engine_.current_state().id); |
| } |
| |
| } // thermald |