コード例 #1
0
    def RunBenchmark(self, bits):
        """Runs the native binary and parses its result.

        Args:
            bits: integer (32 or 64), the number of bits in a word chosen
                  at the compile time (e.g., 32- vs. 64-bit library).
        """
        # Runs the benchmark.
        logging.info(
            "Start to run the benchmark with HIDL mode %s (%s bit mode)",
            self.hidl_hal_mode, bits)
        binary = "/data/local/tmp/%s/libhwbinder_benchmark%s" % (bits, bits)

        self.dut.adb.shell("chmod 755 %s" % binary)

        try:
            result = self.dut.adb.shell(
                "LD_LIBRARY_PATH=/system/lib%s:/data/local/tmp/%s/hw:"
                "/data/local/tmp/%s:"
                "$LD_LIBRARY_PATH %s -m %s" %
                (bits, bits, bits, binary, self.hidl_hal_mode.encode("utf-8")))
        except adb.AdbError as e:
            asserts.fail("HwBinderPerformanceTest failed.")

        # Parses the result.
        stdout_lines = result.split("\n")
        logging.info("stdout: %s", stdout_lines)
        label_result = []
        value_result = []
        prefix = (self.LABEL_PREFIX_BINDERIZE
                  if self.hidl_hal_mode == "BINDERIZE" else
                  self.LABEL_PREFIX_PASSTHROUGH)
        for line in stdout_lines:
            if line.startswith(prefix):
                tokens = line.split()
                benchmark_name = tokens[0]
                time_in_ns = tokens[1].split()[0]
                logging.info(benchmark_name)
                logging.info(time_in_ns)
                label_result.append(benchmark_name.replace(prefix, ""))
                value_result.append(int(time_in_ns))

        logging.info("result label for %sbits: %s", bits, label_result)
        logging.info("result value for %sbits: %s", bits, value_result)
        # To upload to the web DB.
        self.web.AddProfilingDataLabeledVector(
            "hwbinder_vector_roundtrip_latency_benchmark_%sbits" % bits,
            label_result,
            value_result,
            x_axis_label="Message Size (Bytes)",
            y_axis_label="Roundtrip HwBinder RPC Latency (naonseconds)")

        # Assertions to check the performance requirements
        for label, value in zip(label_result, value_result):
            if label in self.THRESHOLD[bits]:
                asserts.assertLess(
                    value, self.THRESHOLD[bits][label],
                    "%s ns for %s is longer than the threshold %s ns" % (
                        value, label, self.THRESHOLD[bits][label]))
    def testListProperties(self):
        """Checks whether some PropConfigs are returned.

        Verifies that call to getAllPropConfigs is not failing and
        it returns at least 1 vehicle property config.
        """
        logging.info("all supported properties: %s", self.configList)
        asserts.assertLess(0, len(self.configList))
 def testInfoVinMakeModel(self):
     """Verifies INFO_VIN, INFO_MAKE, INFO_MODEL properties"""
     stringProperties = set([
         self.vtypes.VehicleProperty.INFO_VIN,
         self.vtypes.VehicleProperty.INFO_MAKE,
         self.vtypes.VehicleProperty.INFO_MODEL
     ])
     for prop in stringProperties:
         supported, val = self.getValueIfPropSupported(prop)
         if supported:
             asserts.assertEqual(str, type(val), "prop: 0x%x" % prop)
             asserts.assertLess(0, (len(val)), "prop: 0x%x" % prop)
コード例 #4
0
    def RunBenchmark(self, bits):
        """Runs the native binary and parses its result.

        Args:
            bits: integer (32 or 64), the number of bits in a word chosen
                  at the compile time (e.g., 32- vs. 64-bit library).
        """
        # Runs the benchmark.
        logging.info(
            "Start to run the benchmark with HIDL mode %s (%s bit mode)",
            self.hidl_hal_mode, bits)
        binary = "/data/local/tmp/%s/libhwbinder_benchmark%s" % (bits, bits)

        results = self.dut.shell.Execute([
            "chmod 755 %s" % binary,
            "VTS_ROOT_PATH=/data/local/tmp " \
            "LD_LIBRARY_PATH=/system/lib%s:/data/local/tmp/%s/hw:"
            "/data/local/tmp/%s:$LD_LIBRARY_PATH "
            "%s -m %s --benchmark_format=json" %
            (bits, bits, bits, binary, self.hidl_hal_mode.encode("utf-8"))
        ])

        # Parses the result.
        asserts.assertEqual(len(results[const.STDOUT]), 2)
        logging.info("stderr: %s", results[const.STDERR][1])
        logging.info("stdout: %s", results[const.STDOUT][1])
        asserts.assertFalse(any(results[const.EXIT_CODE]),
                            "HwBinderPerformanceTest failed.")
        parser = benchmark_parser.GoogleBenchmarkJsonParser(
            results[const.STDOUT][1])
        label_result = parser.GetArguments()
        value_result = parser.GetRealTime()
        table_name = "hwbinder_vector_roundtrip_latency_benchmark_%sbits" % bits
        self.addTableToResult(table_name, parser.ToTable())

        # To upload to the web DB.
        self.web.AddProfilingDataLabeledVector(
            table_name,
            label_result,
            value_result,
            x_axis_label="Message Size (Bytes)",
            y_axis_label="Roundtrip HwBinder RPC Latency (naonseconds)")

        # Assertions to check the performance requirements
        for label, value in zip(label_result, value_result):
            if label in self.THRESHOLD[bits]:
                asserts.assertLess(
                    value, self.THRESHOLD[bits][label],
                    "%s ns for %s is longer than the threshold %s ns" %
                    (value, label, self.THRESHOLD[bits][label]))
コード例 #5
0
    def _GetMinAndMaxCpuNo(self):
        """Returns the min and max CPU numbers.

        Returns:
            integer: min CPU number (inclusive)
            integer: max CPU number (exclusive)
        """
        results = self._shell.Execute("cat /sys/devices/system/cpu/present")
        asserts.assertEqual(len(results[const.STDOUT]), 1)
        stdout_lines = results[const.STDOUT][0].split("\n")
        stdout_split = stdout_lines[0].split('-')
        asserts.assertLess(len(stdout_split), 3)
        low = stdout_split[0]
        high = stdout_split[1] if len(stdout_split) == 2 else low
        logging.info("present cpus: %s : %s" % (low, high))
        return int(low), int(high) + 1
        def CheckStatsInState(state):
            """Sets VTS (root uid) into a given state and checks the stats.

            Args:
                state, boolean. Use False for foreground,
                and True for background.
            """
            state = 1 if state else 0
            filepath = "/proc/uid_procstat/set"
            root_uid = 0

            # fg write chars are at index 2, and bg write chars are at 6.
            wchar_index = 6 if state else 2
            old_wchar = UidIOStats(root_uid)[wchar_index]
            self.dut.adb.shell("\"echo %d %s > %s\"" %
                               (root_uid, state, filepath))
            # This should increase the number of write syscalls.
            self.dut.adb.shell("\"echo foo\"")
            asserts.assertLess(old_wchar,
                               UidIOStats(root_uid)[wchar_index],
                               "Number of write syscalls has not increased.")
    def ProcessTestResults(self, latencies, confidences):
        """Process test results and upload to web dashboard.

        Calculate the average and standard deviation of latencies from all test run.
        Only test results with confidence = 1.0 are counted.

        Args:
           latencies: List of latency (in ns) get from each run. e.g.[8040000]
           confidences: List of confidence get from each run. e.g. [0.98, 1.0]
        """
        total_latency = 0
        total_run = 0
        for latency, confidence in zip(latencies, confidences):
            # filter test runs with confidence < 1.0
            if confidence < 1.0:
                latencies.remove(latency)
            else:
                total_latency += latency
                total_run += 1
        asserts.assertLess(0, total_run, "No valid runs.")
        self.web.AddProfilingDataUnlabeledVector(
            "AVG_LATENCY",
            latencies,
            x_axis_label="AVG Roundtrip latency (ns)",
            y_axis_label="Frequency")
        # calculate the average latency.
        avg_latency = total_latency / total_run
        logging.info("avg_latency: %s", avg_latency)
        asserts.assertLess(avg_latency, self.THRESHOLD["MAX_LATENCY"],
                           "avg latency exceeds threshold")
        # calculate the standard deviation of latencies.
        sd = 0.0
        for latency in latencies:
            sd += (latency - avg_latency) * (latency - avg_latency)
        sd = int(math.sqrt(sd / total_run))
        logging.info("standard_deviation: %s", sd)
        self.web.AddProfilingDataUnlabeledVector(
            "STANDARD_DEVIATION", [sd],
            x_axis_label="Standard deviation",
            y_axis_label="Frequency")
    def extractValue(self, propValue):
        """Extracts value depending on data type of the property"""
        if propValue == None:
            return None

        # Extract data type
        dataType = propValue['prop'] & self.vtypes.VehiclePropertyType.MASK
        val = propValue['value']
        if self.vtypes.VehiclePropertyType.STRING == dataType:
            asserts.assertNotEqual(None, val['stringValue'])
            return val['stringValue']
        elif self.vtypes.VehiclePropertyType.INT32 == dataType or \
                self.vtypes.VehiclePropertyType.BOOLEAN == dataType:
            asserts.assertEqual(1, len(val["int32Values"]))
            return val["int32Values"][0]
        elif self.vtypes.VehiclePropertyType.INT64 == dataType:
            asserts.assertEqual(1, len(val["int64Values"]))
            return val["int64Values"][0]
        elif self.vtypes.VehiclePropertyType.FLOAT == dataType:
            asserts.assertEqual(1, len(val["floatValues"]))
            return val["floatValues"][0]
        elif self.vtypes.VehiclePropertyType.INT32_VEC == dataType:
            asserts.assertLess(0, len(val["int32Values"]))
            return val["int32Values"]
        elif self.vtypes.VehiclePropertyType.FLOAT_VEC == dataType:
            asserts.assertLess(0, len(val["floatValues"]))
            return val["floatValues"]
        elif self.vtypes.VehiclePropertyType.BYTES == dataType:
            asserts.assertLess(0, len(val["bytes"]))
            return val["bytes"]
        else:
            return val
コード例 #9
0
    def RunBenchmark(self, bits):
        """Runs the native binary and parses its result.

        Args:
            bits: integer (32 or 64), the number of bits in a word chosen
                  at the compile time (e.g., 32- vs. 64-bit library).
        """
        # Start the benchmark service.
        logging.info("Start the benchmark service(%s bit mode)", bits)
        binary = "/data/local/tmp/%s/mq_benchmark_service%s" % (bits, bits)
        results = self.dut.shell.one.Execute([
            "chmod 755 %s" % binary,
            "VTS_ROOT_PATH=/data/local/tmp TREBLE_TESTING_OVERRIDE=true " \
            "LD_LIBRARY_PATH=/data/local/tmp/%s:"
            "$LD_LIBRARY_PATH %s&" % (bits, binary)
        ])
        asserts.assertEqual(len(results[const.STDOUT]), 2)
        asserts.assertFalse(any(results[const.EXIT_CODE]),
                            "Failed to start the benchmark service.")

        # Runs the benchmark.
        logging.info("Start to run the benchmark (%s bit mode)", bits)
        binary = "/data/local/tmp/%s/mq_benchmark_client%s" % (bits, bits)

        results = self.dut.shell.one.Execute([
            "chmod 755 %s" % binary,
            "TREBLE_TESTING_OVERRIDE=true LD_LIBRARY_PATH=/data/local/tmp/%s:"
            "$LD_LIBRARY_PATH %s" % (bits, binary)
        ])

        # Stop the benchmark service.
        self.dut.shell.one.Execute("kill -9 `pidof mq_benchmark_service%s`" %
                                   bits)

        # Parses the result.
        asserts.assertEqual(len(results[const.STDOUT]), 2)
        asserts.assertFalse(any(results[const.EXIT_CODE]),
                            "FmqPerformanceTest failed.")
        read_label = []
        read_latency = []
        write_label = []
        write_latency = []
        stdout_lines = results[const.STDOUT][1].split("\n")
        for line in stdout_lines:
            if line.startswith("Average time to read"):
                read_result = line.replace("Average time to read",
                                           "").replace("bytes",
                                                       "").replace("ns", "")
                (label, value) = read_result.split(": ")
                read_label.append(label)
                read_latency.append(int(value))
            if line.startswith("Average time to write"):
                write_result = line.replace("Average time to write ",
                                            "").replace("bytes",
                                                        "").replace("ns", "")
                (label, value) = write_result.split(": ")
                write_label.append(label)
                write_latency.append(int(value))

        # To upload to the web DB.
        self.web.AddProfilingDataLabeledVector(
            "fmq_read_latency_benchmark_%sbits" % bits,
            read_label,
            read_latency,
            x_axis_label="Message Size (Bytes)",
            y_axis_label="Average Latency (nanoseconds)")

        self.web.AddProfilingDataLabeledVector(
            "fmq_write_latency_benchmark_%sbits" % bits,
            write_label,
            write_latency,
            x_axis_label="Message Size (Bytes)",
            y_axis_label="Average Latency (nanoseconds)")

        # Assertions to check the performance requirements
        for label, value in zip(read_label, read_latency):
            if label in self.THRESHOLD[bits]:
                asserts.assertLess(
                    value, self.THRESHOLD[bits][label],
                    "%s ns for %s is longer than the threshold %s ns" %
                    (value, label, self.THRESHOLD[bits][label]))

        for label, value in zip(write_label, write_latency):
            if label in self.THRESHOLD[bits]:
                asserts.assertLess(
                    value, self.THRESHOLD[bits][label],
                    "%s ns for %s is longer than the threshold %s ns" %
                    (value, label, self.THRESHOLD[bits][label]))
コード例 #10
0
 def testVndkVersion(self):
     """Test that VNDK version is specified."""
     vndkVersion = self.getProp("ro.vendor.vndk.version")
     asserts.assertLess(0, len(vndkVersion), "VNDK version is not defined")
    def testEngineOilTemp(self):
        """tests engine oil temperature.

        This also tests an HIDL async callback.
        """
        self.onPropertyEventCalled = 0
        self.onPropertySetCalled = 0
        self.onPropertySetErrorCalled = 0

        def onPropertyEvent(vehiclePropValues):
            logging.info("onPropertyEvent received: %s", vehiclePropValues)
            self.onPropertyEventCalled += 1

        def onPropertySet(vehiclePropValue):
            logging.info("onPropertySet notification received: %s",
                         vehiclePropValue)
            self.onPropertySetCalled += 1

        def onPropertySetError(erroCode, propId, areaId):
            logging.info(
                "onPropertySetError, error: %d, prop: 0x%x, area: 0x%x",
                erroCode, prop, area)
            self.onPropertySetErrorCalled += 1

        config = self.getPropConfig(
            self.vtypes.VehicleProperty.ENGINE_OIL_TEMP)
        if (config is None):
            logging.info("ENGINE_OIL_TEMP property is not supported")
            return  # Property not supported, we are done here.

        propValue = self.readVhalProperty(
            self.vtypes.VehicleProperty.ENGINE_OIL_TEMP)
        asserts.assertEqual(1, len(propValue['value']['floatValues']))
        oilTemp = propValue['value']['floatValues'][0]
        logging.info("Current oil temperature: %f C", oilTemp)
        asserts.assertLess(oilTemp, 200)  # Check it is in reasinable range
        asserts.assertLess(-50, oilTemp)

        if (config["changeMode"] ==
                self.vtypes.VehiclePropertyChangeMode.CONTINUOUS):
            logging.info(
                "ENGINE_OIL_TEMP is continuous property, subscribing...")
            callback = self.vehicle.GetHidlCallbackInterface(
                "IVehicleCallback",
                onPropertyEvent=onPropertyEvent,
                onPropertySet=onPropertySet,
                onPropertySetError=onPropertySetError)

            subscribeOptions = {
                "propId": self.vtypes.VehicleProperty.ENGINE_OIL_TEMP,
                "sampleRate": 10.0,  # Hz
                "flags": self.vtypes.SubscribeFlags.EVENTS_FROM_CAR,
            }
            pbSubscribeOptions = self.vtypes.Py2Pb("SubscribeOptions",
                                                   subscribeOptions)

            self.vehicle.subscribe(callback, [pbSubscribeOptions])
            for _ in range(5):
                if (self.onPropertyEventCalled > 0
                        or self.onPropertySetCalled > 0
                        or self.onPropertySetErrorCalled > 0):
                    return
                time.sleep(1)
            asserts.fail("Callback not called in 5 seconds.")
    def testPropertyRanges(self):
        """Retrieve the property ranges for all areas.

        This checks that the areas noted in the config all give valid area
        configs.  Once these are validated, the values for all these areas
        retrieved from the HIDL must be within the ranges defined."""

        enumProperties = {
            self.vtypes.VehicleProperty.ENGINE_OIL_LEVEL,
            self.vtypes.VehicleProperty.GEAR_SELECTION,
            self.vtypes.VehicleProperty.CURRENT_GEAR,
            self.vtypes.VehicleProperty.TURN_SIGNAL_STATE,
            self.vtypes.VehicleProperty.IGNITION_STATE,
            self.vtypes.VehicleProperty.HVAC_FAN_DIRECTION,
        }

        for c in self.configList:
            # Continuous properties need to have a sampling frequency.
            if c["changeMode"] & self.vtypes.VehiclePropertyChangeMode.CONTINUOUS != 0:
                asserts.assertLess(
                    0.0, c["minSampleRate"],
                    "minSampleRate should be > 0. Config list: %s" % c)
                asserts.assertLess(
                    0.0, c["maxSampleRate"],
                    "maxSampleRate should be > 0. Config list: %s" % c)
                asserts.assertFalse(
                    c["minSampleRate"] > c["maxSampleRate"],
                    "Prop 0x%x minSampleRate > maxSampleRate" % c["prop"])

            if c["prop"] & self.vtypes.VehiclePropertyType.BOOLEAN != 0:
                # Boolean types don't have ranges
                continue

            if c["prop"] in enumProperties:
                # This property does not use traditional min/max ranges
                continue

            asserts.assertTrue(c["areaConfigs"] != None,
                               "Prop 0x%x must have areaConfigs" % c["prop"])
            areasFound = 0
            if c["prop"] == self.vtypes.VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS:
                # This property doesn't have sensible min/max
                continue

            for a in c["areaConfigs"]:
                # Make sure this doesn't override one of the other areas found.
                asserts.assertEqual(0, areasFound & a["areaId"])
                areasFound |= a["areaId"]

                # Do some basic checking the min and max aren't mixed up.
                checks = [("minInt32Value", "maxInt32Value"),
                          ("minInt64Value", "maxInt64Value"),
                          ("minFloatValue", "maxFloatValue")]
                for minName, maxName in checks:
                    asserts.assertFalse(
                        a[minName] > a[maxName],
                        "Prop 0x%x Area 0x%X %s > %s: %d > %d" %
                        (c["prop"], a["areaId"], minName, maxName, a[minName],
                         a[maxName]))

                # Get a value and make sure it's within the bounds.
                propVal = self.readVhalProperty(c["prop"], a["areaId"])
                # Some values may not be available, which is not an error.
                if propVal is None:
                    continue
                val = propVal["value"]
                valTypes = {
                    "int32Values": ("minInt32Value", "maxInt32Value"),
                    "int64Values": ("minInt64Value", "maxInt64Value"),
                    "floatValues": ("minFloatValue", "maxFloatValue"),
                }
                for valType, valBoundNames in valTypes.items():
                    for v in val[valType]:
                        # Make sure value isn't less than the minimum.
                        asserts.assertFalse(
                            v < a[valBoundNames[0]],
                            "Prop 0x%x Area 0x%X %s < min: %s < %s" %
                            (c["prop"], a["areaId"], valType, v,
                             a[valBoundNames[0]]))
                        # Make sure value isn't greater than the maximum.
                        asserts.assertFalse(
                            v > a[valBoundNames[1]],
                            "Prop 0x%x Area 0x%X %s > max: %s > %s" %
                            (c["prop"], a["areaId"], valType, v,
                             a[valBoundNames[1]]))
    def disableTestHvacPowerOn(self):
        # Disable this test for now.  HVAC Power On will no longer behave like this now that we've
        #   added the status field in VehiclePropValue.  Need to update the test for this.
        """Test power on/off and properties associated with it.

        Gets the list of properties that are affected by the HVAC power state
        and validates them.

        Turns power on to start in a defined state, verifies that power is on
        and properties are available.  State change from on->off and verifies
        that properties are no longer available, then state change again from
        off->on to verify properties are now available again.
        """

        # Checks that HVAC_POWER_ON property is supported and returns valid
        # result initially.
        hvacPowerOnConfig = self.propToConfig[
            self.vtypes.VehicleProperty.HVAC_POWER_ON]
        if hvacPowerOnConfig is None:
            logging.info("HVAC_POWER_ON not supported")
            return

        zones = self.extractZonesAsList(hvacPowerOnConfig['supportedAreas'])
        asserts.assertLess(
            0, len(zones),
            "supportedAreas for HVAC_POWER_ON property is invalid")

        # TODO(pavelm): consider to check for all zones
        zone = zones[0]

        propValue = self.readVhalProperty(
            self.vtypes.VehicleProperty.HVAC_POWER_ON, areaId=zone)

        asserts.assertEqual(1, len(propValue["value"]["int32Values"]))
        asserts.assertTrue(
            propValue["value"]["int32Values"][0] in [0, 1],
            "%d not a valid value for HVAC_POWER_ON" %
            propValue["value"]["int32Values"][0])

        # Checks that HVAC_POWER_ON config string returns valid result.
        requestConfig = [
            self.vtypes.Py2Pb("VehicleProperty",
                              self.vtypes.VehicleProperty.HVAC_POWER_ON)
        ]
        logging.info("HVAC power on config request: %s", requestConfig)
        responseConfig = self.vehicle.getPropConfigs(requestConfig)
        logging.info("HVAC power on config response: %s", responseConfig)
        hvacTypes = set([
            self.vtypes.VehicleProperty.HVAC_FAN_SPEED,
            self.vtypes.VehicleProperty.HVAC_FAN_DIRECTION,
            self.vtypes.VehicleProperty.HVAC_TEMPERATURE_CURRENT,
            self.vtypes.VehicleProperty.HVAC_TEMPERATURE_SET,
            self.vtypes.VehicleProperty.HVAC_DEFROSTER,
            self.vtypes.VehicleProperty.HVAC_AC_ON,
            self.vtypes.VehicleProperty.HVAC_MAX_AC_ON,
            self.vtypes.VehicleProperty.HVAC_MAX_DEFROST_ON,
            self.vtypes.VehicleProperty.HVAC_RECIRC_ON,
            self.vtypes.VehicleProperty.HVAC_DUAL_ON,
            self.vtypes.VehicleProperty.HVAC_AUTO_ON,
            self.vtypes.VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM,
        ])
        status = responseConfig[0]
        asserts.assertEqual(self.vtypes.StatusCode.OK, status)
        configString = responseConfig[1][0]["configString"]
        configProps = []
        if configString != "":
            for prop in configString.split(","):
                configProps.append(int(prop, 16))
        for prop in configProps:
            asserts.assertTrue(prop in hvacTypes,
                               "0x%X not an HVAC type" % prop)

        # Turn power on.
        self.setAndVerifyIntProperty(self.vtypes.VehicleProperty.HVAC_POWER_ON,
                                     1,
                                     areaId=zone)

        # Check that properties that require power to be on can be set.
        propVals = {}
        for prop in configProps:
            v = self.readVhalProperty(prop, areaId=zone)["value"]
            self.setVhalProperty(prop, v, areaId=zone)
            # Save the value for use later when trying to set the property when
            # HVAC is off.
            propVals[prop] = v

        # Turn power off.
        self.setAndVerifyIntProperty(self.vtypes.VehicleProperty.HVAC_POWER_ON,
                                     0,
                                     areaId=zone)

        # Check that properties that require power to be on can't be set.
        for prop in configProps:
            self.setVhalProperty(
                prop,
                propVals[prop],
                areaId=zone,
                expectedStatus=self.vtypes.StatusCode.NOT_AVAILABLE)

        # Turn power on.
        self.setAndVerifyIntProperty(self.vtypes.VehicleProperty.HVAC_POWER_ON,
                                     1,
                                     areaId=zone)

        # Check that properties that require power to be on can be set.
        for prop in configProps:
            self.setVhalProperty(prop, propVals[prop], areaId=zone)
    def testPropertyRanges(self):
        """Retrieve the property ranges for all areas.

        This checks that the areas noted in the config all give valid area
        configs.  Once these are validated, the values for all these areas
        retrieved from the HIDL must be within the ranges defined."""
        for c in self.configList:
            # Continuous properties need to have a sampling frequency.
            if c["changeMode"] & self.vtypes.VehiclePropertyChangeMode.CONTINUOUS != 0:
                asserts.assertLess(
                    0.0, c["minSampleRate"],
                    "minSampleRate should be > 0. Config list: %s" % c)
                asserts.assertLess(
                    0.0, c["maxSampleRate"],
                    "maxSampleRate should be > 0. Config list: %s" % c)
                asserts.assertFalse(
                    c["minSampleRate"] > c["maxSampleRate"],
                    "Prop 0x%x minSampleRate > maxSampleRate" % c["prop"])

            areasFound = 0
            for a in c["areaConfigs"]:
                # Make sure this doesn't override one of the other areas found.
                asserts.assertEqual(0, areasFound & a["areaId"])
                areasFound |= a["areaId"]

                # Do some basic checking the min and max aren't mixed up.
                checks = [("minInt32Value", "maxInt32Value"),
                          ("minInt64Value", "maxInt64Value"),
                          ("minFloatValue", "maxFloatValue")]
                for minName, maxName in checks:
                    asserts.assertFalse(
                        a[minName] > a[maxName],
                        "Prop 0x%x Area 0x%X %s > %s: %d > %d" %
                        (c["prop"], a["areaId"], minName, maxName, a[minName],
                         a[maxName]))

                # Get a value and make sure it's within the bounds.
                propVal = self.readVhalProperty(c["prop"], a["areaId"])
                # Some values may not be available, which is not an error.
                if propVal is None:
                    continue
                val = propVal["value"]
                valTypes = {
                    "int32Values": ("minInt32Value", "maxInt32Value"),
                    "int64Values": ("minInt64Value", "maxInt64Value"),
                    "floatValues": ("minFloatValue", "maxFloatValue"),
                }
                for valType, valBoundNames in valTypes.items():
                    for v in val[valType]:
                        # Make sure value isn't less than the minimum.
                        asserts.assertFalse(
                            v < a[valBoundNames[0]],
                            "Prop 0x%x Area 0x%X %s < min: %s < %s" %
                            (c["prop"], a["areaId"], valType, v,
                             a[valBoundNames[0]]))
                        # Make sure value isn't greater than the maximum.
                        asserts.assertFalse(
                            v > a[valBoundNames[1]],
                            "Prop 0x%x Area 0x%X %s > max: %s > %s" %
                            (c["prop"], a["areaId"], valType, v,
                             a[valBoundNames[1]]))