1#!/usr/bin/env python3
2#
3# Copyright 2019, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Unittests for bug_detector."""
18
19# pylint: disable=line-too-long
20
21import datetime
22import json
23import os
24import unittest
25
26from unittest import mock
27
28import bug_detector
29import constants
30import unittest_constants as uc
31
32TEST_DICT = {
33    'test1': {
34        'latest_exit_code': 5,
35        'updated_at': ''
36    },
37    'test2': {
38        'latest_exit_code': 0,
39        'updated_at': ''
40    }
41}
42
43class BugDetectorUnittest(unittest.TestCase):
44    """Unit test for bug_detector.py"""
45
46    def setUp(self):
47        """Set up stuff for testing."""
48        self.history_file = os.path.join(uc.TEST_DATA_DIR, 'bug_detector.json')
49        self.detector = bug_detector.BugDetector(['test1'], 5, self.history_file)
50        self._reset_history_file()
51        self.history_file2 = os.path.join(uc.TEST_DATA_DIR, 'bug_detector2.json')
52
53    def tearDown(self):
54        """Run after execution of every test"""
55        if os.path.isfile(self.history_file):
56            os.remove(self.history_file)
57        if os.path.isfile(self.history_file2):
58            os.remove(self.history_file2)
59
60    def _reset_history_file(self):
61        """Reset test history file."""
62        with open(self.history_file, 'w') as outfile:
63            json.dump(TEST_DICT, outfile)
64
65    def _make_test_file(self, file_size):
66        temp_history = {}
67        for i in range(file_size):
68            latest_bug = {
69                i: {
70                    'latest_exit_code': i,
71                    'updated_at': datetime.datetime.now().isoformat()
72                }
73            }
74            temp_history.update(latest_bug)
75        with open(self.history_file2, 'w') as outfile:
76            json.dump(temp_history, outfile, indent=0)
77
78    @mock.patch.object(bug_detector.BugDetector, 'update_history')
79    def test_get_detect_key(self, _):
80        """Test get_detect_key."""
81        # argv without -v
82        argv = ['test2', 'test1']
83        want_key = 'test1 test2'
84        dtr = bug_detector.BugDetector(argv, 0)
85        self.assertEqual(dtr.get_detect_key(argv), want_key)
86
87        # argv with -v
88        argv = ['-v', 'test2', 'test1']
89        want_key = 'test1 test2'
90        dtr = bug_detector.BugDetector(argv, 0)
91        self.assertEqual(dtr.get_detect_key(argv), want_key)
92
93        # argv with --verbose
94        argv = ['--verbose', 'test2', 'test3', 'test1']
95        want_key = 'test1 test2 test3'
96        dtr = bug_detector.BugDetector(argv, 0)
97        self.assertEqual(dtr.get_detect_key(argv), want_key)
98
99    def test_get_history(self):
100        """Test get_history."""
101        self.assertEqual(self.detector.get_history(), TEST_DICT)
102
103    @mock.patch.object(bug_detector.BugDetector, 'update_history')
104    def test_detect_bug_caught(self, _):
105        """Test detect_bug_caught."""
106        self._reset_history_file()
107        dtr = bug_detector.BugDetector(['test1'], 0, self.history_file)
108        success = 1
109        self.assertEqual(dtr.detect_bug_caught(), success)
110
111    def test_update_history(self):
112        """Test update_history."""
113        constants.UPPER_LIMIT = 10
114        constants.TRIM_TO_SIZE = 3
115
116        mock_file_size = 0
117        self._make_test_file(mock_file_size)
118        dtr = bug_detector.BugDetector(['test1'], 0, self.history_file2)
119        self.assertTrue('test1' in dtr.history)
120
121        # History is larger than constants.UPPER_LIMIT. Trim to size.
122        mock_file_size = 10
123        self._make_test_file(mock_file_size)
124        dtr = bug_detector.BugDetector(['test1'], 0, self.history_file2)
125        self.assertEqual(len(dtr.history), constants.TRIM_TO_SIZE)
126        keys = ['test1', '9', '8']
127        for key in keys:
128            self.assertTrue(key in dtr.history)
129
130        # History is not larger than constants.UPPER_LIMIT.
131        mock_file_size = 5
132        self._make_test_file(mock_file_size)
133        dtr = bug_detector.BugDetector(['test1'], 0, self.history_file2)
134        self.assertEqual(len(dtr.history), mock_file_size+1)
135        keys = ['test1', '4', '3', '2', '1', '0']
136        for key in keys:
137            self.assertTrue(key in dtr.history)
138
139if __name__ == '__main__':
140    unittest.main()
141