1#!/usr/bin/env python
2# Copyright 2014 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import mock
7import time
8import unittest
9
10import common
11
12from autotest_lib.client.common_lib import time_utils
13from autotest_lib.site_utils import dut_status
14
15
16class TimeOptionTests(unittest.TestCase):
17    """Test the --since, --until, and --destination options.
18
19    The options are allowed in these seven combinations:
20      * No options - use the default end time and duration.
21      * --since - use the given start time and the default end time.
22      * --until - use the given end time and the default duration.
23      * --duration - use the given duration and the default end time.
24      * --since --until - use the given start and end times.
25      * --since --duration - use the given start time and duration.
26      * --until --duration - use the given end time and duration.
27
28    It's an error to use all three options together.
29
30    """
31
32    def setUp(self):
33        self.test_time = time.time()
34
35    def _try_parse(self, options):
36        with mock.patch('time.time', return_value=self.test_time):
37            arguments = dut_status._parse_command(
38                    ['mumble.py'] + options + ['hostname'])
39            dut_status._validate_time_range(arguments)
40        return arguments
41
42    def _check_duration(self, arguments, duration):
43        start_time = (arguments.until - duration * 3600)
44        self.assertEqual(arguments.since, start_time)
45
46    def test_default_time_bounds(self):
47        """Test time bounds when no options are supplied."""
48        end_time = int(self.test_time)
49        arguments = self._try_parse([])
50        self.assertEqual(arguments.until, end_time)
51        self._check_duration(arguments, dut_status._DEFAULT_DURATION)
52
53    def test_start_only(self):
54        """Test time bounds with --since only.
55
56        Also tests that --since and -s are equivalent.
57        """
58        end_time = int(self.test_time)
59        start_time = end_time - 3600
60        start_time_string = time_utils.epoch_time_to_date_string(start_time)
61        for option in ['--since', '-s']:
62            arguments = self._try_parse([option, start_time_string])
63            self.assertEqual(arguments.until, end_time)
64            self.assertEqual(arguments.since, start_time)
65
66    def test_end_only(self):
67        """Test time bounds with --until only.
68
69        Also tests that --until and -u are equivalent.
70        """
71        end_time = int(self.test_time) - 3600
72        end_time_string = time_utils.epoch_time_to_date_string(end_time)
73        for option in ['--until', '-u']:
74            arguments = self._try_parse([option, end_time_string])
75            self.assertEqual(arguments.until, end_time)
76            self._check_duration(arguments, dut_status._DEFAULT_DURATION)
77
78    def test_duration_only(self):
79        """Test time bounds with --duration only.
80
81        Also tests that --duration and -d are equivalent.
82        """
83        for option in ['--duration', '-d']:
84            duration = 4
85            duration_string = '%d' % duration
86            end_time = int(self.test_time)
87            arguments = self._try_parse([option, duration_string])
88            self.assertEqual(arguments.until, end_time)
89            self._check_duration(arguments, duration)
90
91    def test_start_and_end(self):
92        """Test time bounds with --since and --until."""
93        start_time = int(self.test_time) - 5 * 3600
94        start_time_string = time_utils.epoch_time_to_date_string(start_time)
95        end_time = start_time + 4 * 3600
96        end_time_string = time_utils.epoch_time_to_date_string(end_time)
97        arguments = self._try_parse(['-s', start_time_string,
98                                     '-u', end_time_string])
99        self.assertEqual(arguments.since, start_time)
100        self.assertEqual(arguments.until, end_time)
101
102    def test_start_and_duration(self):
103        """Test time bounds with --since and --duration."""
104        start_time = int(self.test_time) - 5 * 3600
105        start_time_string = time_utils.epoch_time_to_date_string(start_time)
106        duration = 4
107        duration_string = '%d' % duration
108        arguments = self._try_parse(['-s', start_time_string,
109                                     '-d', duration_string])
110        self.assertEqual(arguments.since, start_time)
111        self._check_duration(arguments, duration)
112
113    def test_end_and_duration(self):
114        """Test time bounds with --until and --duration."""
115        end_time = int(self.test_time) - 5 * 3600
116        end_time_string = time_utils.epoch_time_to_date_string(end_time)
117        duration = 4
118        duration_string = '%d' % duration
119        arguments = self._try_parse(['-u', end_time_string,
120                                     '-d', duration_string])
121        self.assertEqual(arguments.until, end_time)
122        self._check_duration(arguments, duration)
123
124    def test_all_options(self):
125        """Test that all three options are a fatal error."""
126        start_time = int(self.test_time) - 5 * 3600
127        start_time_string = time_utils.epoch_time_to_date_string(start_time)
128        duration = 4
129        duration_string = '%d' % duration
130        end_time = start_time + duration * 3600
131        end_time_string = time_utils.epoch_time_to_date_string(end_time)
132        with self.assertRaises(SystemExit):
133            self._try_parse(['-s', start_time_string,
134                             '-u', end_time_string,
135                             '-d', duration_string])
136
137
138if __name__ == '__main__':
139    unittest.main()
140