1# Copyright 2016 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
6import time
7import os
8
9from autotest_lib.client.common_lib import error
10from autotest_lib.client.cros.crash.crash_test import CrashTest
11from autotest_lib.server import test
12
13
14class logging_GenerateCrashFiles(test.test):
15    """Tests if crash files are generated when crash is invoked."""
16    version = 1
17    SHORT_WAIT = 10
18    REBOOT_TIMEOUT = 60
19    CRASH_DIR = CrashTest._SYSTEM_CRASH_DIR
20
21    def check_missing_crash_files(self, expected_extensions, existing_files,
22                                  prefix):
23        """Find if the crash dumps with appropriate extensions are created.
24        @param expected_extensions: matching crash file extensions.
25        @param existing files: state of crash dir before induced crash.
26        @param prefix: matching crash file prefix.
27        @raises TestFail error if crash files are not generated.
28        """
29        crash_extensions = list()
30
31        out = self.host.run('ls %s' % self.CRASH_DIR, ignore_status=True)
32        current_files = out.stdout.strip().split('\n')
33
34        file_diff = set(current_files) - set(existing_files)
35        logging.info("Crash files diff: %s" % file_diff)
36
37        # Check empty files, prefix, and extension of crash files.
38        for crash_file in file_diff:
39            if crash_file.split('.')[0] != prefix:
40                continue
41            file_path = self.CRASH_DIR + '/' + crash_file
42            if '0' == self.host.run("du -h %s" % file_path).stdout[:1]:
43                raise error.TestFail('Crash file is empty: %s' % crash_file)
44            crash_extensions.append(crash_file.split('.')[-1])
45
46        # Check for presence of all crash file extensions.
47        extension_diff = set(expected_extensions) - set(crash_extensions)
48        if len(extension_diff) > 0:
49            raise error.TestFail('%s files not generated.' % extension_diff)
50
51        # Remove existing file crash files, if any.
52        for crash_file in file_diff:
53            self.host.run('rm %s' % self.CRASH_DIR + '/' + crash_file)
54
55    def run_once(self, host, crash_cmd, crash_files, prefix):
56        self.host = host
57
58        # Sync the file system.
59        self.host.run('sync', ignore_status=True)
60        time.sleep(self.SHORT_WAIT)
61        file_list = self.host.run('ls %s' % self.CRASH_DIR, ignore_status=True)
62        existing_files = file_list.stdout.strip().split('\n')
63
64        # Execute crash command.
65        self.host.run(crash_cmd, ignore_status=True,
66                      timeout=30, ignore_timeout=True)
67        logging.debug('Crash invoked!')
68
69        # In case of kernel crash the reboot will take some time.
70        host.ping_wait_up(self.REBOOT_TIMEOUT)
71
72        # Sync the file system.
73        self.host.run('sync', ignore_status=True)
74        time.sleep(self.SHORT_WAIT)
75
76        self.check_missing_crash_files(crash_files, existing_files, prefix)
77