• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 - The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Tests for pull."""
15import unittest
16
17import os
18import tempfile
19
20from unittest import mock
21
22from acloud import errors
23from acloud.internal import constants
24from acloud.internal.lib import driver_test_lib
25from acloud.internal.lib import ssh
26from acloud.internal.lib import utils
27from acloud.list import list as list_instances
28from acloud.public import config
29from acloud.pull import pull
30
31
32class PullTest(driver_test_lib.BaseDriverTest):
33    """Test pull."""
34
35    # pylint: disable=no-member
36    def testPullFileFromInstance(self):
37        """test PullFileFromInstance."""
38        cfg = mock.MagicMock()
39        cfg.ssh_private_key_path = "fake_ssh_path"
40        cfg.extra_args_ssh_tunnel = ""
41        instance = mock.MagicMock()
42        instance.ip = "1.1.1.1"
43        # Multiple selected files case.
44        selected_files = ["file1.log", "file2.log"]
45        self.Patch(pull, "SelectLogFileToPull", return_value=selected_files)
46        self.Patch(pull, "GetDownloadLogFolder", return_value="fake_folder")
47        self.Patch(pull, "PullLogs")
48        self.Patch(pull, "DisplayLog")
49        pull.PullFileFromInstance(cfg, instance)
50        self.assertEqual(pull.DisplayLog.call_count, 0)
51
52        # Only one file selected case.
53        selected_files = ["file1.log"]
54        self.Patch(pull, "SelectLogFileToPull", return_value=selected_files)
55        pull.PullFileFromInstance(cfg, instance)
56        self.assertEqual(pull.DisplayLog.call_count, 1)
57
58    # pylint: disable=no-member
59    def testPullLogs(self):
60        """test PullLogs."""
61        _ssh = mock.MagicMock()
62        self.Patch(utils, "PrintColorString")
63        log_files = ["file1.log", "file2.log"]
64        download_folder = "/fake_folder"
65        pull.PullLogs(_ssh, log_files, download_folder)
66        self.assertEqual(_ssh.ScpPullFile.call_count, 2)
67        utils.PrintColorString.assert_called_once()
68
69    @mock.patch.object(ssh.Ssh, "Run")
70    def testDisplayLog(self, mock_ssh_run):
71        """Test DisplayLog."""
72        fake_ip = ssh.IP(external="1.1.1.1", internal="10.1.1.1")
73        _ssh = ssh.Ssh(ip=fake_ip,
74                       user=constants.GCE_USER,
75                       ssh_private_key_path="/fake/acloud_rea")
76        self.Patch(utils, "GetUserAnswerYes", return_value="Y")
77        log_file = "file1.log"
78        pull.DisplayLog(_ssh, log_file)
79        expected_cmd = "tail -f -n +1 %s" % log_file
80        mock_ssh_run.assert_has_calls([
81            mock.call(expected_cmd, show_output=True)])
82
83    def testGetDownloadLogFolder(self):
84        """test GetDownloadLogFolder."""
85        self.Patch(tempfile, "gettempdir", return_value="/tmp")
86        self.Patch(os.path, "exists", return_value=True)
87        instance = "instance"
88        expected_path = "/tmp/instance"
89        self.assertEqual(pull.GetDownloadLogFolder(instance), expected_path)
90
91    def testSelectLogFileToPull(self):
92        """test choose log files from the remote instance."""
93        _ssh = mock.MagicMock()
94
95        # Test only one log file case
96        log_files = ["file1.log"]
97        self.Patch(pull, "GetAllLogFilePaths", return_value=log_files)
98        expected_result = ["file1.log"]
99        self.assertEqual(pull.SelectLogFileToPull(_ssh), expected_result)
100
101        # Test no log files case
102        self.Patch(pull, "GetAllLogFilePaths", return_value=[])
103        with self.assertRaises(errors.CheckPathError):
104            pull.SelectLogFileToPull(_ssh)
105
106        # Test two log files case.
107        log_files = ["file1.log", "file2.log"]
108        choose_log = ["file2.log"]
109        self.Patch(pull, "GetAllLogFilePaths", return_value=log_files)
110        self.Patch(utils, "GetAnswerFromList", return_value=choose_log)
111        expected_result = ["file2.log"]
112        self.assertEqual(pull.SelectLogFileToPull(_ssh), expected_result)
113
114        # Test user provided file name exist.
115        log_files = ["/home/vsoc-01/cuttlefish_runtime/file1.log",
116                     "/home/vsoc-01/cuttlefish_runtime/file2.log"]
117        input_file = "file1.log"
118        self.Patch(pull, "GetAllLogFilePaths", return_value=log_files)
119        expected_result = ["/home/vsoc-01/cuttlefish_runtime/file1.log"]
120        self.assertEqual(pull.SelectLogFileToPull(_ssh, input_file), expected_result)
121
122        # Test user provided file name not exist.
123        log_files = ["/home/vsoc-01/cuttlefish_runtime/file1.log",
124                     "/home/vsoc-01/cuttlefish_runtime/file2.log"]
125        input_file = "not_exist.log"
126        self.Patch(pull, "GetAllLogFilePaths", return_value=log_files)
127        with self.assertRaises(errors.CheckPathError):
128            pull.SelectLogFileToPull(_ssh, input_file)
129
130    def testFilterLogfiles(self):
131        """test filer log file from black list."""
132        # Filter out file name is "kernel".
133        files = ["kernel.log", "logcat", "kernel"]
134        expected_result = ["kernel.log", "logcat"]
135        self.assertEqual(pull.FilterLogfiles(files), expected_result)
136
137        # Filter out file extension is ".img".
138        files = ["kernel.log", "system.img", "userdata.img", "launcher.log"]
139        expected_result = ["kernel.log", "launcher.log"]
140        self.assertEqual(pull.FilterLogfiles(files), expected_result)
141
142    @mock.patch.object(pull, "PullFileFromInstance")
143    def testRun(self, mock_pull_file):
144        """test Run."""
145        cfg = mock.MagicMock()
146        args = mock.MagicMock()
147        instance_obj = mock.MagicMock()
148        # Test case with provided instance name.
149        args.instance_name = "instance_1"
150        args.file_name = "file1.log"
151        args.no_prompt = True
152        self.Patch(config, "GetAcloudConfig", return_value=cfg)
153        self.Patch(list_instances, "GetInstancesFromInstanceNames",
154                   return_value=[instance_obj])
155        pull.Run(args)
156        mock_pull_file.assert_has_calls([
157            mock.call(cfg, instance_obj, args.file_name, args.no_prompt)])
158
159        # Test case for user select one instance to pull log.
160        selected_instance = mock.MagicMock()
161        self.Patch(list_instances, "ChooseOneRemoteInstance",
162                   return_value=selected_instance)
163        args.instance_name = None
164        pull.Run(args)
165        mock_pull_file.assert_has_calls([
166            mock.call(cfg, selected_instance, args.file_name, args.no_prompt)])
167
168
169if __name__ == '__main__':
170    unittest.main()
171