17861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#!/usr/bin/env python
27861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# -*- coding: utf-8 -*-
37861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#
47861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Copyright 2017 Google Inc.
57861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#
67861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Licensed under the Apache License, Version 2.0 (the "License");
77861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# you may not use this file except in compliance with the License.
87861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# You may obtain a copy of the License at
97861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#
107861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#   http://www.apache.org/licenses/LICENSE-2.0
117861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#
127861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Unless required by applicable law or agreed to in writing, software
137861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# distributed under the License is distributed on an "AS IS" BASIS,
147861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
157861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# See the License for the specific language governing permissions and
167861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# limitations under the License.
177861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#
187861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
197861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik"""
207861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    This module tests the Vehicle HAL using adb socket.
217861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
227861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    Protocol Buffer:
237861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        This module relies on VehicleHalProto_pb2.py being in sync with the protobuf in the VHAL.
2495fb30b5d0bf47808125bacf97d772608eda19cfScott Randolph        If the VehicleHalProto.proto file has changed, re-generate the python version using
2595fb30b5d0bf47808125bacf97d772608eda19cfScott Randolph        a command of the form:
267861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            protoc -I=<proto_dir> --python_out=<out_dir> <proto_dir>/VehicleHalProto.proto
2795fb30b5d0bf47808125bacf97d772608eda19cfScott Randolph        For example:
2895fb30b5d0bf47808125bacf97d772608eda19cfScott Randolph            protoDir=~/android/master/hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto
2995fb30b5d0bf47808125bacf97d772608eda19cfScott Randolph            outDir=~/android/master/packages/services/Car/tools/emulator
3095fb30b5d0bf47808125bacf97d772608eda19cfScott Randolph            protoc -I=$protoDir --python_out=$outDir $protoDir/VehicleHalProto.proto
317861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik"""
327861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
3366d5a97c5cef5a075960e3cca9986c578436df58Enrico Granatafrom __future__ import print_function
3466d5a97c5cef5a075960e3cca9986c578436df58Enrico Granata
357861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Suppress .pyc files
367861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport sys
377861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paiksys.dont_write_bytecode = True
387861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
397861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport VehicleHalProto_pb2
4023608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paikimport vhal_consts_2_1
417861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport vhal_emulator
427861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport logging
437861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
447861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikclass VhalTest:
457861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Global vars
467861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    _badProps = [0, 0x3FFFFFFF]     # List of bad properties to try for negative tests
477861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    _configs = 0                    # List of configs from DUT
487861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    _log = 0                        # Logger module
497861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    _vhal = 0                       # Handle to VHAL object that communicates over socket to DUT
5023608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik    # TODO: b/38203109 - Fix OBD2 values, implement handling for complex properties
5123608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik    _skipProps = [
5223608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    vhal_consts_2_1.VEHICLEPROPERTY_OBD2_LIVE_FRAME,
5323608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    vhal_consts_2_1.VEHICLEPROPERTY_OBD2_FREEZE_FRAME,
5423608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    vhal_consts_2_1.VEHICLEPROPERTY_OBD2_FREEZE_FRAME_INFO,
5523608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    vhal_consts_2_1.VEHICLEPROPERTY_OBD2_FREEZE_FRAME_CLEAR,
5623608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    vhal_consts_2_1.VEHICLEPROPERTY_VEHICLE_MAP_SERVICE,
5723608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    vhal_consts_2_1.VEHICLEPROPERTY_WHEEL_TICK,     # Need to support complex properties
5823608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    0x21E00666      # FakeDataControllingProperty - an internal test property
5923608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                 ]
607861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
617861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def _getMidpoint(self, minVal, maxVal):
627861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        retVal =  minVal + (maxVal - minVal)/2
637861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        return retVal
647861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
657861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Generates a test value based on the config
667861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def _generateTestValue(self, cfg, idx, origValue):
677861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        valType = cfg.value_type
687861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        if valType in self._types.TYPE_STRING:
697861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            testValue = "test string"
707861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        elif valType in self._types.TYPE_BYTES:
717861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            # Generate array of integers counting from 0
7266d5a97c5cef5a075960e3cca9986c578436df58Enrico Granata            testValue = list(range(len(origValue)))
7323608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik        elif valType == vhal_consts_2_1.VEHICLEPROPERTYTYPE_BOOLEAN:
747861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            testValue = origValue ^ 1
757861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        elif valType in self._types.TYPE_INT32:
767861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            try:
777861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = self._getMidpoint(cfg.area_configs[idx].min_int32_value,
787861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                              cfg.area_configs[idx].max_int32_value)
797861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            except:
807861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # min/max values aren't set.  Set a hard-coded value
817861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = 123
827861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        elif valType in self._types.TYPE_INT64:
837861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            try:
847861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = self._getMidpoint(cfg.area_configs[idx].min_int64_value,
857861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                              cfg.area_configs[idx].max_int64_value)
867861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            except:
877861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # min/max values aren't set.  Set a large hard-coded value
887861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = 1 << 50
897861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        elif valType in self._types.TYPE_FLOAT:
907861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            try:
917861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = self._getMidpoint(cfg.area_configs[idx].min_float_value,
927861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                              cfg.area_configs[idx].max_float_value)
937861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            except:
947861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # min/max values aren't set.  Set a hard-coded value
957861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = 123.456
967861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            # Truncate float to 5 decimal places
977861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            testValue = "%.5f" % testValue
987861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            testValue = float(testValue)
997861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        else:
10023608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.error("generateTestValue:  valType=0x%X is not handled", valType)
1017861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            testValue = None
1027861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        return testValue
1037861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1047861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Helper function to extract values array from rxMsg
1057861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def _getValueFromMsg(self, rxMsg):
1067861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        # Check to see only one property value is returned
1077861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        if len(rxMsg.value) != 1:
1087861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            self._log.error("getValueFromMsg:  Received invalid value")
1097861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            value = None
1107861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        else:
1117861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            valType = rxMsg.value[0].value_type
1127861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            if valType in self._types.TYPE_STRING:
1137861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = rxMsg.value[0].string_value
1147861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            elif valType in self._types.TYPE_BYTES:
1157861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = rxMsg.value[0].bytes_value
11623608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            elif valType == vhal_consts_2_1.VEHICLEPROPERTYTYPE_BOOLEAN:
1177861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = rxMsg.value[0].int32_values[0]
1187861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            elif valType in self._types.TYPE_INT32:
1197861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = rxMsg.value[0].int32_values[0]
1207861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            elif valType in self._types.TYPE_INT64:
1217861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = rxMsg.value[0].int64_values[0]
1227861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            elif valType in self._types.TYPE_FLOAT:
1237861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = rxMsg.value[0].float_values[0]
1247861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Truncate float to 5 decimal places
1257861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = "%.5f" % value
1267861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = float(value)
1277861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            else:
12823608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                self._log.error("getValueFromMsg:  valType=0x%X is not handled", valType)
1297861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                value = None
1307861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        return value
1317861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1327861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Helper function to receive a message and validate the type and status
1337861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   retVal = 1 if no errors
1347861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   retVal = 0 if errors detected
1357861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def _rxMsgAndValidate(self, expectedType, expectedStatus):
1367861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        retVal = 1
1377861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        rxMsg = self._vhal.rxMsg()
1387861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        if rxMsg.msg_type != expectedType:
13923608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.error("rxMsg Type expected: 0x%X, received: 0x%X", expectedType, rxMsg.msg_type)
1407861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            retVal = 0
1417861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        if rxMsg.status != expectedStatus:
14223608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.error("rxMsg Status expected: 0x%X, received: 0x%X", expectedStatus, rxMsg.status)
1437861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            retVal = 0
1447861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        return rxMsg, retVal
1457861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1467861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Calls getConfig() on each individual property ID and verifies it matches with the config
1477861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   received in getConfigAll()
1487861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def testGetConfig(self):
1497861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("Starting testGetConfig...")
1507861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        for cfg in self._configs:
15123608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.debug("  Getting config for propId=0x%X", cfg.prop)
1527861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            self._vhal.getConfig(cfg.prop)
1537861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.GET_CONFIG_RESP,
1547861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                                   VehicleHalProto_pb2.RESULT_OK)
1557861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            if retVal:
1567861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                if rxMsg.config[0] != cfg:
15723608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    self._log.error("testGetConfig failed.  prop=0x%X, expected:\n%s\nreceived:\n%s",
1587861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                               cfg.prop, str(cfg), str(rxMsg.config))
1597861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("  Finished testGetConfig!")
1607861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1617861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Calls getConfig() on invalid property ID and verifies it generates an error
1627861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def testGetBadConfig(self):
1637861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("Starting testGetBadConfig...")
1647861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        for prop in self._badProps:
16523608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.debug("  Testing bad propId=0x%X", prop)
1667861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            self._vhal.getConfig(prop)
1677861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.GET_CONFIG_RESP,
1687861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                                   VehicleHalProto_pb2.ERROR_INVALID_PROPERTY)
1697861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            if retVal:
1707861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                for cfg in rxMsg.config:
17123608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    self._log.error("testGetBadConfig  prop=0x%X, expected:None, received:\n%s",
1727861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                    cfg.prop, str(rxMsg.config))
1737861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("  Finished testGetBadConfig!")
1747861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1757861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def testGetPropertyAll(self):
1767861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("Starting testGetPropertyAll...")
1777861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._vhal.getPropertyAll()
1787861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.GET_PROPERTY_ALL_RESP,
1797861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                               VehicleHalProto_pb2.RESULT_OK)
1807861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        if retVal == 0:
1817861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            self._log.error("testGetPropertyAll:  Failed to receive proper rxMsg")
1827861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1837861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        # TODO: Finish writing this test.  What should we be testing, anyway?
1847861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1857861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("  Finished testGetPropertyAll!")
1867861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
1877861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def testGetSet(self):
1887861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("Starting testGetSet()...")
1897861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        for cfg in self._configs:
19023608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            if cfg.prop in self._skipProps:
19123608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                # Skip properties that cannot be handled properly by this test.
19223608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                self._log.warning("  Skipping propId=0x%X", cfg.prop)
19323608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                continue
19423608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik
1957861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            areas = cfg.supported_areas
1967861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            idx = -1
1977861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            while (idx == -1) | (areas != 0):
1987861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                idx += 1
1997861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Get the area to test
2007861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                area = areas & (areas -1)
2017861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                area ^= areas
2027861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2037861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Remove the area from areas
2047861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                areas ^= area
2057861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
20623608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                self._log.debug("  Testing propId=0x%X, area=0x%X", cfg.prop, area)
2077861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2087861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Get the current value
2097861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                self._vhal.getProperty(cfg.prop, area)
2107861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.GET_PROPERTY_RESP,
2117861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                                       VehicleHalProto_pb2.RESULT_OK)
2127861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2137861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Save the original value
2147861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                origValue = self._getValueFromMsg(rxMsg)
2157861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                if origValue == None:
21623608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    self._log.error("testGetSet:  Could not get value for prop=0x%X, area=0x%X",
2177861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                    cfg.prop, area)
2187861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                    continue
2197861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2207861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Generate the test value
2217861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                testValue = self._generateTestValue(cfg, idx, origValue)
2227861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                if testValue == None:
22323608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    self._log.error("testGetSet:  Cannot generate test value for prop=0x%X, area=0x%X",
2247861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                    cfg.prop, area)
2257861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                    continue
2267861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2277861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Send the new value
2287861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                self._vhal.setProperty(cfg.prop, area, testValue)
2297861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.SET_PROPERTY_RESP,
23023608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                                                        VehicleHalProto_pb2.RESULT_OK)
2317861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2327861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Get the new value and verify it
2337861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                self._vhal.getProperty(cfg.prop, area)
2347861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.GET_PROPERTY_RESP,
2357861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                                       VehicleHalProto_pb2.RESULT_OK)
2367861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                newValue = self._getValueFromMsg(rxMsg)
2377861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                if newValue != testValue:
23823608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    self._log.error("testGetSet: set failed for propId=0x%X, area=0x%X", cfg.prop, area)
23966d5a97c5cef5a075960e3cca9986c578436df58Enrico Granata                    print("testValue= ", testValue, "newValue= ", newValue)
2407861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                    continue
2417861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2427861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Reset the value to what it was before
2437861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                self._vhal.setProperty(cfg.prop, area, origValue)
2447861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.SET_PROPERTY_RESP,
2457861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                                       VehicleHalProto_pb2.RESULT_OK)
2467861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("  Finished testGetSet()!")
2477861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2487861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def testGetBadProperty(self):
2497861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("Starting testGetBadProperty()...")
2507861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        for prop in self._badProps:
25123608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.debug("  Testing bad propId=0x%X", prop)
2527861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            self._vhal.getProperty(prop, 0)
2537861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            rxMsg, retVal = self._rxMsgAndValidate(VehicleHalProto_pb2.GET_PROPERTY_RESP,
2547861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                                   VehicleHalProto_pb2.ERROR_INVALID_PROPERTY)
2557861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            if retVal:
2567861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                for value in rxMsg.value:
25723608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                    self._log.error("testGetBadProperty  prop=0x%X, expected:None, received:\n%s",
2587861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                    prop, str(rxMsg))
2597861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("  Finished testGetBadProperty()!")
2607861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2617861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def testSetBadProperty(self):
2627861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("Starting testSetBadProperty()...")
2637861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        area = 1
2647861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        value = 100
2657861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        for prop in self._badProps:
26623608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik            self._log.debug("  Testing bad propId=0x%X", prop)
2677861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            area = area + 1
2687861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            value = value + 1
2697861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            try:
2707861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                self._vhal.setProperty(prop, area, value)
27123608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik                self._log.error("testGetBadProperty failed.  prop=0x%X, area=0x%X, value=%d",
2727861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                                prop, area, value)
2737861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik            except ValueError as e:
2747861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                # Received expected error
2757861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik                pass
2767861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.info("  Finished testSetBadProperty()!")
2777861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2787861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def runTests(self):
2797861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self.testGetConfig()
2807861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self.testGetBadConfig()
2817861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self.testGetPropertyAll()
2827861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self.testGetSet()
2837861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self.testGetBadProperty()
2847861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self.testSetBadProperty()
2857861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        # Add new tests here to be run
2867861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2877861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
2887861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    # Valid logLevels:
2897861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   CRITICAL    50
2907861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   ERRROR      40
2917861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   WARNING     30
2927861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   INFO        20
2937861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   DEBUG       10
2947861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    #   NOTSET      0
2957861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    def __init__(self, types, logLevel=20):
2967861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._types = types
2977861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        # Configure the logger
2987861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        logging.basicConfig()
2997861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log = logging.getLogger('vhal_emulator_test')
3007861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._log.setLevel(logLevel)
3017861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        # Start the VHAL Emulator
3027861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._vhal = vhal_emulator.Vhal(types)
3037861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        # Get the list of configs
3047861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._vhal.getConfigAll()
3057861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik        self._configs = self._vhal.rxMsg().config
3067861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik
3077861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikif __name__ == '__main__':
30823608326bda34f5d5ad3feb92bfc53b2416a04b8Steve Paik    v = VhalTest(vhal_consts_2_1.vhal_types_2_0)
3097861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik    v.runTests()
310