blob: 63ac7c5940ef892d66c3d95e014eb9c9a91b67ec [file] [log] [blame]
# 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.
""" Test if the memory size is correctly written in the firmware.
Test memory size by comparing the result of mosys and kernel meminfo.
Optionally, we can check memory size by the information on shopfloor if factory
supports it.
"""
import logging
import re
import threading
import unittest
import factory_common # pylint: disable=unused-import
from cros.factory.test.i18n import test_ui as i18n_test_ui
from cros.factory.test import shopfloor
from cros.factory.test import test_ui
from cros.factory.test import ui_templates
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import debug_utils
from cros.factory.utils import process_utils
_SHOPFLOOR_METHOD_NAME = 'GetMemSize'
class MemorySize(unittest.TestCase):
ARGS = [
Arg('compare_with_shopfloor', bool,
'compare the memory size info with factory shopfloor', default=True),
Arg('shopfloor_method_name', str,
'Shopfloor method name for getting memory info',
default=_SHOPFLOOR_METHOD_NAME),
Arg('max_diff_gb', float,
'maxmum difference between memory size detected by kernel and mosys',
default=0.5),
]
def setUp(self):
self._event = threading.Event()
def runTest(self):
def Done():
self._event.set()
ui = test_ui.UI()
template = ui_templates.OneSection(ui)
ui.Run(blocking=False, on_finish=Done)
ui.AppendCSS('.large { font-size: 200% }')
template.SetState(i18n_test_ui.MakeI18nLabel('Checking memory info...'))
# Get memory info using mosys.
ret = process_utils.CheckOutput(
['mosys', '-k', 'memory', 'spd', 'print', 'geometry'])
mosys_mem_mb = sum([int(x) for x in re.findall('size_mb="([^"]*)"', ret)])
mosys_mem_gb = round(mosys_mem_mb / 1024.0, 1)
# Get kernal meminfo.
with open('/proc/meminfo', 'r') as f:
kernel_mem_kb = int(re.search(r'^MemTotal:\s*([0-9]+)\s*kB',
f.read()).group(1))
kernel_mem_gb = round(kernel_mem_kb / 1024.0 / 1024.0, 1)
diff = abs(kernel_mem_gb - mosys_mem_gb)
if diff > self.args.max_diff_gb:
self.fail('Memory size detected by kernel is different from mosys by '
'%.1f GB' % diff)
return
if not self.args.compare_with_shopfloor:
return
ui.AddEventHandler('retry', lambda dummy_event: self._event.set())
method_name = self.args.shopfloor_method_name
method = getattr(shopfloor.get_instance(detect=True), method_name)
mlb_serial_number = shopfloor.GetDeviceData()['mlb_serial_number']
message = 'Invoking %s(%s)' % (method_name, mlb_serial_number)
while True:
logging.info(message)
template.SetState(test_ui.Escape(message))
def HandleError(trace):
template.SetState(
i18n_test_ui.MakeI18nLabelWithClass(
'Shop floor exception:',
'test-status-failed large') +
'<p>' +
test_ui.Escape(trace) +
'<p><br>' +
"""<button onclick="test.sendTestEvent('retry')">""" +
i18n_test_ui.MakeI18nLabel('Retry') +
'</button>')
process_utils.WaitEvent(self._event)
self._event.clear()
try:
result = method(mlb_serial_number)
logging.info('%s: %s', method_name, str(result))
except: # pylint: disable=bare-except
exception_str = debug_utils.FormatExceptionOnly()
logging.exception('Exception invoking shopfloor method\n' +
exception_str)
HandleError(exception_str)
continue
sf_mem_gb = round(float(result['mem_size']), 1)
# The memory size info in mosys should be the same as that in shopfloor.
if abs(mosys_mem_gb - sf_mem_gb) > 10e-6:
msg = ('Memory size detected in mosys (%.1f GB) is different from the '
'reocrd in shopfloor (%.1f GB)' % (mosys_mem_gb, sf_mem_gb))
self.fail(msg)
break