1# Copyright 2019 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6 7from autotest_lib.client.bin import test 8from autotest_lib.client.bin import utils 9from autotest_lib.client.common_lib import error 10 11 12class vpd_ReadWrite(test.test): 13 """Tests reading from and writing to vpd.""" 14 version = 1 15 16 17 def _write_to_vpd(self, vpd_field, value): 18 """ 19 Writes a value to a vpd field. 20 21 @param vpd_field: The vpd field name 22 @param value: The value to write to the field. 23 24 @returns True if the write was successful, else False 25 26 """ 27 try: 28 result = utils.run('vpd -i RW_VPD -s %s=%d' % (vpd_field, value)) 29 logging.debug(result) 30 return True 31 except error.CmdError as err: 32 logging.info('Failed to write %d to %s vpd field: %s', value, 33 vpd_field, err) 34 return False 35 36 37 def _read_from_vpd(self, vpd_field): 38 """ 39 Reads a value from a vpd field. 40 41 @param vpd_field: The vpd field name to read from. 42 43 @returns The value of the vpd field specified or None if it failed. 44 45 """ 46 try: 47 result = utils.run('vpd -i RW_VPD -g %s' % vpd_field) 48 logging.debug(result) 49 return int(result.stdout) 50 except error.CmdError as err: 51 logging.info('Failed to read %s vpd field: %s', vpd_field, err) 52 return None 53 54 55 def _execute_read_write_cycle(self, repetitions, vpd_field): 56 write_failures = 0 57 read_failures = 0 58 59 for value in range(repetitions): 60 if not self._write_to_vpd(vpd_field, value): 61 write_failures += 1 62 continue 63 64 value_from_vpd = self._read_from_vpd(vpd_field) 65 66 if value_from_vpd is None: 67 read_failures += 1 68 elif value_from_vpd != value: 69 write_failures += 1 70 logging.info('No error when writing to vpd but reading showed ' 71 'a different value than we expected. Expected: ' 72 '%d, Actual: %d', value, value_from_vpd) 73 74 if write_failures > 0 and read_failures > 0: 75 raise error.TestFail('There were %d/%d write failures and %d/%d ' 76 'read failures.' % (write_failures, 77 repetitions, 78 read_failures, 79 repetitions)) 80 elif write_failures > 0: 81 raise error.TestFail('There were %d/%d write failures' % ( 82 write_failures, repetitions)) 83 elif read_failures > 0: 84 raise error.TestFail('There were %d/%d write failures' % ( 85 read_failures, repetitions)) 86 87 88 def run_once(self, repetitions): 89 """ 90 Entry point to the test. 91 92 @param repetitions: The number of times to cycle through the test. 93 94 """ 95 self._execute_read_write_cycle(repetitions, 'should_send_rlz_ping') 96 self._execute_read_write_cycle(repetitions, 97 'first_active_omaha_ping_sent') 98 logging.info('There were no read or write failures. Test successful') 99