1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include <stdio.h>
20 
21 #include <hardware/hardware.h>
22 #include <hardware/power.h>
23 #include <log/log.h>
24 
25 #include <iostream>
26 
27 using namespace std;
28 
29 namespace {
30 
31 // VTS structural testcase for HAL Power basic functionalities.
32 class VtsStructuralTestHalPowerTest : public ::testing::Test {
33  protected:
VtsStructuralTestHalPowerTest()34   VtsStructuralTestHalPowerTest() {
35     int rc =
36         hw_get_module(POWER_HARDWARE_MODULE_ID, (hw_module_t const **)&module_);
37     if (rc || !module_) {
38       cerr << "could not find any power HAL module." << endl;
39       module_ = NULL;
40       return;
41     }
42     if (module_->init) module_->init(module_);
43   }
44 
~VtsStructuralTestHalPowerTest()45   virtual ~VtsStructuralTestHalPowerTest() {}
46 
SetUp()47   virtual void SetUp() {
48     // define operations to execute before running each testcase.
49     ASSERT_TRUE(module_->get_number_of_platform_modes)
50         << "get_number_of_platform_modes is NULL";
51     ASSERT_TRUE(module_->get_voter_list) << "get_voter_list is NULL";
52     ASSERT_TRUE(module_->get_number_of_platform_modes)
53         << "get_number_of_platform_modes is NULL";
54     num_modes_ = module_->get_number_of_platform_modes(module_);
55     ASSERT_GT(num_modes_, 0) << "num_modes_ should be at least 1";
56   }
57 
TearDown()58   virtual void TearDown() {
59     // define operations to execute after running each testcase.
60   }
61 
62   struct power_module *module_;
63 
64   int num_modes_;
65 };
66 
67 // get_number_of_platform_modes should always return the same value
68 // irrespective of how many times invoked.
TEST_F(VtsStructuralTestHalPowerTest,get_number_of_platform_modes_returns_same_value)69 TEST_F(VtsStructuralTestHalPowerTest,
70        get_number_of_platform_modes_returns_same_value) {
71   // NOTE: We can repeat this for few more times in a loop if the test can
72   // run longer.
73   sleep(1);
74   int rc2 = module_->get_number_of_platform_modes(module_);
75   EXPECT_EQ(num_modes_, rc2)
76       << "get_number_of_platform_modes returned unequal values";
77 }
78 
79 // Check if residency duration and count decreases between successive
80 // invocations.
TEST_F(VtsStructuralTestHalPowerTest,check_if_the_values_decrease)81 TEST_F(VtsStructuralTestHalPowerTest, check_if_the_values_decrease) {
82   power_state_platform_sleep_state_t *list1 =
83       (power_state_platform_sleep_state_t *)calloc(
84           num_modes_, sizeof(power_state_platform_sleep_state_t));
85   ASSERT_TRUE(list1) << "power_state_platform_sleep_state_t* alloc failed";
86 
87   power_state_platform_sleep_state_t *list2 =
88       (power_state_platform_sleep_state_t *)calloc(
89           num_modes_, sizeof(power_state_platform_sleep_state_t));
90   ASSERT_TRUE(list2) << "power_state_platform_sleep_state_t* alloc failed";
91 
92   size_t *voter_list = (size_t *)calloc(num_modes_, sizeof(*voter_list));
93   ASSERT_TRUE(voter_list) << "voter_list* alloc failed";
94 
95   module_->get_voter_list(module_, voter_list);
96 
97   for (int i = 0; i < num_modes_; i++) {
98     list1[i].voters = (power_state_voter_t *)calloc(
99         voter_list[i], sizeof(power_state_voter_t));
100     ASSERT_TRUE(list1[i].voters) << "voter_t allocation failed";
101 
102     list2[i].voters = (power_state_voter_t *)calloc(
103         voter_list[i], sizeof(power_state_voter_t));
104 
105     ASSERT_TRUE(list2[i].voters) << "voter_t allocation failed";
106   }
107 
108   ASSERT_EQ(0, module_->get_platform_low_power_stats(module_, list1))
109       << "get_platform_low_power_stats failed";
110   sleep(2);
111   ASSERT_EQ(0, module_->get_platform_low_power_stats(module_, list2))
112       << "get_platform_low_power_stats failed";
113 
114   for (int i = 0; i < num_modes_; i++) {
115     EXPECT_LE(list1[i].residency_in_msec_since_boot,
116               list2[i].residency_in_msec_since_boot)
117         << "residency_in_msec_since_boot decreased";
118     EXPECT_LE(list1[i].total_transitions, list2[i].total_transitions)
119         << "total_transitions decreased";
120 
121     for (unsigned int j = 0; j < list1[i].number_of_voters; j++) {
122       EXPECT_LE(list1[i].voters[j].total_time_in_msec_voted_for_since_boot,
123                 list2[i].voters[j].total_time_in_msec_voted_for_since_boot)
124           << "total_time_in_msec_voted_for_since_boot decreased";
125       EXPECT_LE(list1[i].voters[j].total_number_of_times_voted_since_boot,
126                 list2[i].voters[j].total_number_of_times_voted_since_boot)
127           << "total_number_of_times_voted_since_boot decreased";
128     }
129   }
130   for (int i = 0; i < num_modes_; i++) {
131     free(list1[i].voters);
132     free(list2[i].voters);
133   }
134   free(list1);
135   free(list2);
136   free(voter_list);
137 }
138 
139 // Check if get_platform_low_power_stats succeeds.
TEST_F(VtsStructuralTestHalPowerTest,check_if_get_platform_low_power_stats_returns_success)140 TEST_F(VtsStructuralTestHalPowerTest,
141        check_if_get_platform_low_power_stats_returns_success) {
142   power_state_platform_sleep_state_t *list1 =
143       (power_state_platform_sleep_state_t *)calloc(
144           num_modes_, sizeof(power_state_platform_sleep_state_t));
145   ASSERT_TRUE(list1) << "power_state_platform_sleep_state_t* alloc failed";
146 
147   size_t *voter_list = (size_t *)calloc(num_modes_, sizeof(*voter_list));
148   ASSERT_TRUE(voter_list) << "voter_t allocation failed";
149 
150   module_->get_voter_list(module_, voter_list);
151   for (int i = 0; i < num_modes_; i++) {
152     list1[i].voters = (power_state_voter_t *)calloc(
153         voter_list[i], sizeof(power_state_voter_t));
154     ASSERT_TRUE(list1[i].voters) << "voter_t allocation failed";
155   }
156   EXPECT_EQ(0, module_->get_platform_low_power_stats(module_, list1))
157       << "get_platform_low_power_stats failed";
158   for (int i = 0; i < num_modes_; i++) {
159     free(list1[i].voters);
160   }
161   free(list1);
162   free(voter_list);
163 }
164 }  // namespace
165