1# Copyright (c) 2014 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
5from autotest_lib.client.common_lib import error
6from autotest_lib.server import test
7
8
9class platform_Vpd(test.test):
10    """Test that vpd's cache gets generated during the boot if missing.
11
12    Clean the vpd cache file and check that the files are correctly generated
13    at the next reboot.
14    """
15    version = 1
16
17    _VPD_FILES = [
18        ('/mnt/stateful_partition/unencrypted/cache/vpd/filtered.txt',
19            'root', 'root', '644'),
20        ('/mnt/stateful_partition/unencrypted/cache/vpd/echo/vpd_echo.txt',
21            'root', 'chronos', '640'),
22        ('/mnt/stateful_partition/unencrypted/cache/vpd/full-v2.txt',
23            'root', 'root', '600')
24    ]
25
26    _VPD_LINKS = [
27        '/var/log/vpd_2.0.txt',
28        '/var/cache/vpd/full-v2.txt',
29        '/var/cache/echo/vpd_echo.txt'
30    ]
31
32    # files used by older versions on vpd and that should not be here anymore
33    _VPD_OLD_FILES = [
34        '/var/cache/vpd/full.cache',
35        '/var/cache/offers/vpd_echo.txt',
36        '/var/cache/vpd/full-v2.cache'
37    ]
38
39    def get_stat(self, host, path):
40        """Return user, group and permissions of file on host.
41
42        @param host: the host machine to test
43        @param path: path to the file that we are testing
44
45        @return None if the file does not exist
46                (user, group, permissions) if it does.
47        """
48        if not self.file_exists(host, path):
49            return None
50
51        user = host.run('stat -c %U ' + path).stdout.strip()
52        group = host.run('stat -c %G ' + path).stdout.strip()
53        mode = host.run('stat -c %a ' + path).stdout.strip()
54
55        return (user, group, mode)
56
57    def file_exists(self, host, path):
58        """Check if the path exists.
59
60        @param host: the host machine
61        @param path: path of the file to check
62
63        @return True if the file exists
64        """
65        return host.run('[ -f %s ]' % path,
66                        ignore_status=True).exit_status == 0
67
68    def is_symlink(self, host, path):
69        """Check if a file is a symlink.
70
71        @param host: the host machine
72        @param path: path to the file
73
74        @return True is the file is a symlink
75        """
76        return host.run('[ -h %s ]' % path,
77                        ignore_status=True).exit_status == 0
78
79    def run_once(self, host):
80        host.run('dump_vpd_log --clean')
81
82        removed_files = [item[0] for item in self._VPD_FILES]
83        removed_files += self._VPD_LINKS
84        removed_files += self._VPD_OLD_FILES
85
86        for vpdfile in removed_files:
87            if self.file_exists(host, vpdfile):
88                raise error.TestFail('Vpd file %s was not removed by '
89                    'dump_vpd_log --clean' % vpdfile)
90
91        host.reboot()
92
93        # check that the files exist and have the right permissions
94        for (path, user, group, perm) in self._VPD_FILES:
95            if self.is_symlink(host, path):
96                raise error.TestFail('File %s should not be a symlink' % path)
97
98            stats = self.get_stat(host, path)
99            if stats is None:
100                raise error.TestFail('File %s should be present' % path)
101
102            if user != stats[0]:
103                raise error.TestFail('Wrong user (%s instead of %s) for %s' %
104                      (stats[0], user, path))
105
106            if group != stats[1]:
107                raise error.TestFail('Wrong group (%s instead of %s) for %s' %
108                      (stats[1], group, path))
109
110            if perm != stats[2]:
111                raise error.TestFail('Wrong permissions (%s instead of %s)'
112                    ' for %s' % (stats[2], perm, path))
113
114        # for symlinks, check that they exist and are symlinks
115        for path in self._VPD_LINKS:
116            if not self.is_symlink(host, path):
117                raise error.TestFail('%s should be a symlink' % path)
118
119            if not self.file_exists(host, path):
120                raise error.TestFail('Symlink %s does not exist' % path)
121
122        for path in self._VPD_OLD_FILES:
123            if self.file_exists(host, path):
124                raise error.TestFail('Old vpd file %s installed' % path)
125