Merge lp:~canonical-platform-qa/ubuntu-system-tests/mtp_refactoring_merge_and_bugfix into lp:ubuntu-system-tests

Proposed by Sergio Cazzolato
Status: Merged
Approved by: Brendan Donegan
Approved revision: 155
Merged at revision: 153
Proposed branch: lp:~canonical-platform-qa/ubuntu-system-tests/mtp_refactoring_merge_and_bugfix
Merge into: lp:ubuntu-system-tests
Diff against target: 816 lines (+397/-244)
4 files modified
ubuntu_system_tests/helpers/file_system.py (+10/-3)
ubuntu_system_tests/helpers/mtp.py (+302/-0)
ubuntu_system_tests/helpers/ssh.py (+14/-5)
ubuntu_system_tests/tests/test_mtp.py (+71/-236)
To merge this branch: bzr merge lp:~canonical-platform-qa/ubuntu-system-tests/mtp_refactoring_merge_and_bugfix
Reviewer Review Type Date Requested Status
Richard Huddie (community) Approve
Brendan Donegan (community) Approve
PS Jenkins bot continuous-integration Approve
Sergio Cazzolato Pending
Review via email: mp+265084@code.launchpad.net

Commit message

.MTP helper created including different objects to manage mtp tests and allowing any other test to use mtp feature.
.Merge with scope test. New filesystem paths are being used in the mtp tests.
.Fix clean_dir method of the filesystem helper. The old implementation was making the media scanner fail after the media dir is cleaned.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
155. By Sergio Cazzolato

Fix test cases test_copy_large_number_of_files

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Brendan Donegan (brendan-donegan) wrote :

Code looks fine and everything seems to still work

review: Approve
Revision history for this message
Richard Huddie (rhuddie) wrote :

Looks good, I ran a test and it worked fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntu_system_tests/helpers/file_system.py'
--- ubuntu_system_tests/helpers/file_system.py 2015-07-15 11:06:17 +0000
+++ ubuntu_system_tests/helpers/file_system.py 2015-07-17 19:25:19 +0000
@@ -51,6 +51,8 @@
51DIR_TEST_DATA_TEXT = os.path.join(DIR_TEST_DATA, 'text')51DIR_TEST_DATA_TEXT = os.path.join(DIR_TEST_DATA, 'text')
52DIR_TEST_DATA_VIDEO = os.path.join(DIR_TEST_DATA, 'video')52DIR_TEST_DATA_VIDEO = os.path.join(DIR_TEST_DATA, 'video')
5353
54DIR_TEMP = '/tmp'
55
5456
55def delete_file(file_name):57def delete_file(file_name):
56 """Delete the file passed as parameter. In case the file does not58 """Delete the file passed as parameter. In case the file does not
@@ -78,13 +80,18 @@
7880
79def remove_dir(dir_path):81def remove_dir(dir_path):
80 """Remove the directory"""82 """Remove the directory"""
81 shutil.rmtree(dir_path, True)83 if os.path.isdir(dir_path):
84 shutil.rmtree(dir_path, True)
8285
8386
84def clean_dir(dir_path):87def clean_dir(dir_path):
85 """Delete all the content of the directory"""88 """Delete all the content of the directory"""
86 remove_dir(dir_path)89 for obj in os.listdir(dir_path):
87 os.makedirs(dir_path)90 obj_path = os.path.join(dir_path, obj)
91 if os.path.isfile(obj_path):
92 os.remove(obj_path)
93 else:
94 remove_dir(obj_path)
8895
8996
90def calculate_file_sha1(file_path):97def calculate_file_sha1(file_path):
9198
=== added file 'ubuntu_system_tests/helpers/mtp.py'
--- ubuntu_system_tests/helpers/mtp.py 1970-01-01 00:00:00 +0000
+++ ubuntu_system_tests/helpers/mtp.py 2015-07-17 19:25:19 +0000
@@ -0,0 +1,302 @@
1
2# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3
4# Ubuntu System Tests
5# Copyright (C) 2015 Canonical
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20import logging
21import os
22import shutil
23
24from ubuntu_system_tests.helpers import file_system as fs
25
26logger = logging.getLogger(__name__)
27
28DEFAULT_XDG_RUNTIME_DIR = '/run/user/1000'
29
30
31class MTPObjBase:
32 """ Base class used to represent objects that are copied through mtp"""
33
34 def __init__(self, remote_helper):
35 self.remote_helper = remote_helper
36 self.local_src_path = ""
37 self.local_dst_path = ""
38 self.remote_src_path = ""
39 self.remote_dst_path = ""
40
41 def validate_remote_copy(self):
42 """ Validate the src and dst paths are defined """
43 if not self.remote_src_path or not self.remote_dst_path:
44 raise RuntimeError("Remote copy cannot be done, remote_src_path "
45 "and remote_mtp_path have to be defined")
46
47 def validate_send_to_host(self):
48 """ Validate the src and dst paths are defined """
49 if not self.local_src_path or not self.remote_src_path:
50 raise RuntimeError("Send to host cannot be done, local_src_path "
51 "and remote_src_path have to be defined")
52
53
54class MTPFile(MTPObjBase):
55 """ This class represents a file which is copied through mtp"""
56
57 def __init__(self, remote_helper):
58 super(MTPFile, self).__init__(remote_helper)
59 self.sha1 = ""
60
61 @property
62 def name(self):
63 """ Retrieve the name based of the paths defined """
64 return os.path.basename(self.local_src_path) or \
65 os.path.basename(self.remote_src_path) or \
66 os.path.basename(self.remote_dst_path) or \
67 os.path.basename(self.local_dst_path)
68
69 def clean(self):
70 """ Clean the file in the different places where the file has been
71 copied. This method is used mainly for the clean up of the file """
72 fs.delete_file(self.local_src_path)
73 if self.remote_src_path:
74 self.remote_helper.remove_file(self.remote_src_path)
75 if self.remote_dst_path:
76 self.remote_helper.remove_file(self.remote_dst_path)
77 fs.delete_file(self.local_dst_path)
78
79 def remote_copy(self, remote_dst_path=None):
80 """ Copy the file in the remote host from src to dst
81 :param remote_dst_path: the remote destination in case it has not been
82 defined previously
83 """
84 if remote_dst_path:
85 self.remote_dst_path = remote_dst_path
86 self.validate_remote_copy()
87 logger.info("Copying remote file from {src_path} to {mtp_path}".
88 format(src_path=self.remote_src_path,
89 mtp_path=self.remote_dst_path))
90 self.remote_helper.copy_file(self.remote_src_path,
91 self.remote_dst_path)
92
93 def get_remote_dst_sha1(self):
94 """ Get the sha1 digest calculated in the remote host for the file
95 located in the remote_dst_path
96 """
97 if not self.remote_dst_path:
98 raise RuntimeError("Attribute remote_dst_path has to de defined")
99 return self.remote_helper.get_sha1(self.remote_dst_path)
100
101 def send_to_host(self, path=None):
102 """ Send the file from the device to the ubuntu host. The
103 remote_src_path will be updated in case the path is defined
104 :param path: The path in the remote host where the file is copied
105 """
106 if path:
107 self.remote_src_path = os.path.join(path, self.name)
108 self.validate_send_to_host()
109 logger.info("Sending file to remote host from {local_path} to "
110 "{remote_path}".format(local_path=self.local_src_path,
111 remote_path=self.remote_src_path))
112 self.remote_helper.put(self.local_src_path, self.remote_src_path)
113
114 def compare(self, file_path):
115 """ Compare the local file to the file located in the path
116 :return:True if the files are equal, false otherwise
117 """
118 return fs.compare_files(self.local_src_path, file_path)
119
120
121class MTPDir(MTPObjBase):
122 """ This class represents a directory which is copied through mtp"""
123
124 def __init__(self, remote_helper):
125 super(MTPDir, self).__init__(remote_helper)
126
127 @property
128 def name(self):
129 """ Retrieve the name based of the paths defined """
130 return os.path.basename(self.local_src_path) or \
131 os.path.basename(self.remote_src_path) or \
132 os.path.basename(self.remote_dst_path) or \
133 os.path.basename(self.local_dst_path)
134
135 def clean(self):
136 """ Clean the dir in the different places where the dir has been
137 copied. This method is used mainly for the clean up of the dir """
138 fs.remove_dir(self.local_src_path)
139 if self.remote_src_path:
140 self.remote_helper.remove_dir(self.remote_src_path)
141 if self.remote_dst_path:
142 self.remote_helper.remove_dir(self.remote_dst_path)
143 fs.remove_dir(self.local_dst_path)
144
145 def remote_copy(self, remote_dst_path=None):
146 """ Copy the dir in the remote host from src to dst
147 :param remote_dst_path: the remote destination in case it has not been
148 defined previously
149 """
150 if remote_dst_path:
151 self.remote_dst_path = remote_dst_path
152 self.validate_remote_copy()
153 logger.info("Copying remote directory from {src_path} to {mtp_path}".
154 format(src_path=self.remote_src_path,
155 mtp_path=self.remote_dst_path))
156 self.remote_helper.copy_dir(self.remote_src_path,
157 self.remote_dst_path)
158
159
160class MTPObjFactory:
161 """ A factory class used to create the mtp entities in the local and
162 remote host """
163
164 def __init__(self, remote_helper, clean_up):
165 """
166 :param remote_helper: The helper to interact with the remote host
167 :param clean_up: The method used to clean up the objects created
168 """
169 self.remote_helper = remote_helper
170 self.clean_up = clean_up
171
172 def new_file(self):
173 """ Create an MTPFile object and add a clean up for it """
174 file = MTPFile(self.remote_helper)
175 self.clean_up(file.clean)
176 return file
177
178 def create_random_file(self, dir, ext='', sha1=True):
179 """ Create a MTPFile object with random name
180 :param dir: The dir where the file is created
181 :param ext: The extension of the file to be created
182 :param sha1: if True, the sha1 is calculated and stores in the file
183 :return: The created file with the local src path already set
184 """
185 file = self.new_file()
186 file.local_src_path = fs.create_random_file(dir, ext)
187 if sha1:
188 file.sha1 = fs.calculate_file_sha1(file.local_src_path)
189 return file
190
191 def create_file(self, src_file, temp=True):
192 """ Create a MTPFile object based on a real file
193 :param src_file: The real file used to create the MTPFile obj
194 :param temp: if True, the file is copied to a temp dir. The temp is
195 used to avoid the original file is deleted in the clean-up
196 :return: The created file object with the local src path already set
197 """
198 file = self.new_file()
199 file.local_src_path = src_file
200 if temp:
201 file.local_src_path = os.path.join(fs.DIR_TEMP, file.name)
202 shutil.copy(src_file, file.local_src_path)
203 return file
204
205 def create_remote_file(self, path=None, name=None, ext='', sha1=True,
206 kb=0, mb=0, gb=0):
207 """ Create a file in the remote host
208 :param path: The path where the file is created, if None, the file will
209 be created in a temp dir
210 :param name: The name of the file to be created, if None, will be used
211 a random name
212 :param ext: the extension of the file
213 :param sha1: if True, the sha1 is calculated and stores in the file
214 :param kb: The kilobytes of the file to be created
215 :param mb: The megabytes of the file to be created
216 :param gb: The gigabytes of the file to be created
217 :return: The created file with random content and size equals to
218 kb kilobytes + mb megabytes + gb gigabytes
219 """
220 file = self.new_file()
221 file_path = path or fs.DIR_TEMP
222 file_name = name or fs.get_random_string()
223 file.remote_src_path = os.path.join(file_path, file_name + ext)
224 self.remote_helper.create_random_file(file.remote_src_path, kb=kb,
225 mb=mb, gb=gb)
226 if sha1:
227 file.sha1 = self.remote_helper.get_sha1(file.remote_src_path)
228 return file
229
230 def new_dir(self):
231 """ Create an MTPDir object and add a clean up for it """
232 dir = MTPDir(self.remote_helper)
233 self.clean_up(dir.clean)
234 return dir
235
236 def create_remote_dir(self, path=None, name=None):
237 """
238 Create a dir in the remote host
239 :param path: the name path where the new dir has to be created
240 :param name: the name of the dir, in case the name is not defined,
241 a random name is used
242 """
243 dir = self.new_dir()
244 dir_path = path or fs.DIR_TEMP
245 dir_name = name or fs.get_random_string()
246 dir.remote_src_path = os.path.join(dir_path, dir_name)
247 self.remote_helper.create_dir(dir.remote_src_path)
248 return dir
249
250
251class MTPHelper:
252
253 def __init__(self, remote_helper):
254 self.remote_helper = remote_helper
255 self.mtp_dir = self._calculate_mtp_dir()
256
257 def get_mtp_path(self, *paths):
258 """ Retrieve the mtp path following the desired paths
259 :param paths: A list of subdir to the destination path
260 :return: The mtp path already escaped to the destination path
261 """
262 return '"' + os.path.join(self.mtp_dir, *paths) + '"'
263
264 def _calculate_mtp_dir(self):
265 """ Get the path in the ubuntu host machine which maps to the mtp dir.
266 Use a random file to identify the device internal storage destination.
267 """
268 file = fs.create_random_file(fs.DIR_HOME_DOCUMENTS, ext='.tmp')
269 docs_mtp_dir = self._get_mtp_dir(fs.DIR_DOCUMENTS,
270 os.path.basename(file))
271 os.remove(file)
272 return os.path.dirname(docs_mtp_dir)
273
274 def _get_mtp_dir(self, dir_to_map, filename):
275 """ Determine the full_path in the ubuntu host machine which maps the
276 file and directory in the device
277 :param dir_to_map: The directory to map
278 :param filename: The name of the file to be mapped
279 :return: the full path that maps the dir_to_map and filename in the
280 device
281 """
282 cmd_line = "python3 -c \"import glob; import os; " \
283 "print(glob.glob(os.getenv('XDG_RUNTIME_DIR', " \
284 "'{default}') + '/gvfs/*/*/{dir}/{filename}')[0])\"".\
285 format(default=DEFAULT_XDG_RUNTIME_DIR,
286 dir=dir_to_map,
287 filename=filename)
288
289 file_path = self.remote_helper.run(cmd_line).strip()
290 if file_path:
291 return os.path.dirname(file_path)
292 return None
293
294 def replicate_file(self, src_file, dst_dir, dst_files):
295 """ Copy the src file to the dst directory with the different names
296 stored in the dst_files variable
297 :param src_file: the source file to replicate
298 :param dst_dir: the destination directory to copy the files
299 :param dst_files: the target names to use
300 """
301 for file in dst_files:
302 src_file.remote_copy(os.path.join(dst_dir.remote_src_path, file))
0303
=== modified file 'ubuntu_system_tests/helpers/ssh.py'
--- ubuntu_system_tests/helpers/ssh.py 2015-07-10 19:41:55 +0000
+++ ubuntu_system_tests/helpers/ssh.py 2015-07-17 19:25:19 +0000
@@ -21,6 +21,8 @@
21import os21import os
22import paramiko22import paramiko
2323
24from ubuntu_system_tests import config
25
24logger = logging.getLogger(__name__)26logger = logging.getLogger(__name__)
2527
2628
@@ -45,19 +47,26 @@
4547
46 return "".join(stdout.readlines())48 return "".join(stdout.readlines())
4749
48 def copy(self, localpath, remotepath):50 def put(self, local_path, remote_path):
49 """Copy a file through sftp from the localpath to the remotepath"""51 """Copy a file through sftp from the local_path to the remote_path"""
50 if not os.path.isfile(localpath):52 if not os.path.isfile(local_path):
51 raise RuntimeError("File to copy does not exist")53 raise RuntimeError("File to copy does not exist")
5254
53 sftp = self.client.open_sftp()55 sftp = self.client.open_sftp()
54 sftp.put(localpath, remotepath)56 sftp.put(local_path, remote_path)
55 sftp.close()57 sftp.close()
5658
5759
58class LinuxRemoteHelper(SSH):60class LinuxRemoteHelper(SSH):
59 """This class executes remote linux commands through the ssh connection"""61 """This class executes remote linux commands through the ssh connection"""
6062
63 def __init__(self):
64 config_stack = config.get_device_config_stack()
65 host = config_stack.get('ssh_ip')
66 user = config_stack.get('ssh_user')
67 password = config_stack.get('ssh_password')
68 super(LinuxRemoteHelper, self).__init__(host, user, password)
69
61 def remove_dir(self, dir_name):70 def remove_dir(self, dir_name):
62 self.run('rm -rf {}'.format(dir_name))71 self.run('rm -rf {}'.format(dir_name))
6372
@@ -85,7 +94,7 @@
85 :param mb: The megabytes of the file94 :param mb: The megabytes of the file
86 :param gb: The gigabytes fo the file95 :param gb: The gigabytes fo the file
87 :return: The file path to the created file with random content and size96 :return: The file path to the created file with random content and size
88 equals to kb KiloBytes + mb MegaBytes + gb GigaBytes97 equals to kb kilobytes + mb megabytes + gb gigabytes
89 """98 """
90 count = kb + mb * 1024 + gb * 1024 * 102499 count = kb + mb * 1024 + gb * 1024 * 1024
91 self.run('dd if=/dev/urandom of={file} bs=1024 count={count}'.100 self.run('dd if=/dev/urandom of={file} bs=1024 count={count}'.
92101
=== modified file 'ubuntu_system_tests/tests/test_mtp.py'
--- ubuntu_system_tests/tests/test_mtp.py 2015-07-15 11:06:17 +0000
+++ ubuntu_system_tests/tests/test_mtp.py 2015-07-17 19:25:19 +0000
@@ -22,26 +22,14 @@
22import logging22import logging
23import os23import os
2424
25from ubuntu_system_tests import config
26from ubuntu_system_tests.helpers import file_system as fs25from ubuntu_system_tests.helpers import file_system as fs
26from ubuntu_system_tests.helpers.mtp import MTPObjFactory, MTPHelper
27from ubuntu_system_tests.helpers import ssh27from ubuntu_system_tests.helpers import ssh
28from ubuntu_system_tests.helpers.scopes import music28from ubuntu_system_tests.helpers.scopes import music
29from ubuntu_system_tests.helpers.unity8.dash import get_dash29from ubuntu_system_tests.helpers.unity8.dash import get_dash
3030
31from ubuntu_system_tests.tests import base31from ubuntu_system_tests.tests import base
3232
33TEMP_DIR = '/tmp'
34DEFAULT_XDG_RUNTIME_DIR = '/run/user/1000'
35
36MUSIC = "Music"
37MUSIC_DIR = os.path.join(os.path.expanduser("~"), MUSIC)
38DOCS = "Documents"
39DOCS_DIR = os.path.join(os.path.expanduser("~"), DOCS)
40PICTURES = "Pictures"
41PICTURES_DIR = os.path.join(os.path.expanduser("~"), PICTURES)
42VIDEOS = "Videos"
43VIDEOS_DIR = os.path.join(os.path.expanduser("~"), VIDEOS)
44
45FileMusicDesc = namedtuple('FileMusicDesc', ['file', 'album'])33FileMusicDesc = namedtuple('FileMusicDesc', ['file', 'album'])
46logger = logging.getLogger(__name__)34logger = logging.getLogger(__name__)
47songs_album_mp3 = ['song_1.mp3', 'song_2.mp3', 'song_3.mp3']35songs_album_mp3 = ['song_1.mp3', 'song_2.mp3', 'song_3.mp3']
@@ -57,108 +45,17 @@
57}45}
5846
5947
60class MTPFile:
61 """ This class is a data model which represents a file to be copied
62 through mtp
63 """
64 def __init__(self, remote_helper):
65 self.remote_helper = remote_helper
66 self.local_path = ""
67 self.remote_src_path = ""
68 self.remote_dst_path = ""
69 self.sha1 = ""
70
71 @property
72 def name(self):
73 return os.path.basename(self.local_path) or ""
74
75 def clean_file(self):
76 if self.local_path:
77 fs.delete_file(self.local_path)
78 if self.remote_src_path:
79 self.remote_helper.remove_file(self.remote_src_path)
80 if self.remote_dst_path:
81 self.remote_helper.remove_file(self.remote_dst_path)
82
83 def remote_copy(self):
84 if not self.remote_src_path or not self.remote_dst_path:
85 raise RuntimeError("Remote copy cannot be done, it is required to "
86 "define src and dst paths,")
87 logger.info("Copying remote file from {src_path} to {dst_path}".
88 format(src_path=self.remote_src_path,
89 dst_path=self.remote_dst_path))
90 self.remote_helper.copy_file(self.remote_src_path,
91 self.remote_dst_path)
92
93 def get_remote_dst_sha1(self):
94 if not self.remote_dst_path:
95 raise RuntimeError("Attribute remote_dst_path has to de defined")
96 return self.remote_helper.get_sha1(self.remote_dst_path)
97
98
99class MTPTest(base.BaseUbuntuSystemTestCase):48class MTPTest(base.BaseUbuntuSystemTestCase):
100 """This Class tests the mtp protocol"""49 """This Class tests the mtp protocol"""
10150
102 def setUp(self):51 def setUp(self):
103 super().setUp()52 super().setUp()
10453
105 self.config_stack = config.get_device_config_stack()
106 self.unity_proxy = self.restart_unity()54 self.unity_proxy = self.restart_unity()
107 self.remote_helper = ssh.LinuxRemoteHelper(55 self.remote_helper = ssh.LinuxRemoteHelper()
108 self.config_stack.get('ssh_ip'),
109 self.config_stack.get('ssh_user'),
110 self.config_stack.get('ssh_password'))
111 self.addCleanup(self.remote_helper.close)56 self.addCleanup(self.remote_helper.close)
112 self.mtp_dir = self.calculate_device_mtp_dir()57 self.factory = MTPObjFactory(self.remote_helper, self.addCleanup)
11358 self.mtp_helper = MTPHelper(self.remote_helper)
114 def create_random_file(self, dir, ext='', sha1=True):
115 file = MTPFile(self.remote_helper)
116 file.local_path = fs.create_random_file(dir, ext)
117 if sha1:
118 file.sha1 = fs.calculate_file_sha1(file.local_path)
119 self.addCleanup(file.clean_file)
120 return file
121
122 def get_first_elem_in_dir_command(self, path):
123 """Command to retrieve the first element in a dir"""
124 return 'ls {} | sort -n | head -1'.format(path)
125
126 def get_device_mtp_dir(self, dir_to_map, filename):
127 """ Determine the full_path in the ubuntu host machine which maps the
128 file and directory in the device
129 :param dir_to_map: The directory to map
130 :param filename: The name of the file to be mapped
131 :return: the full path that maps the dir_to_map and filename in the
132 device
133 """
134 cmd_line = "python3 -c \"import glob; import os; " \
135 "print(glob.glob(os.getenv('XDG_RUNTIME_DIR', " \
136 "'{default}') + '/gvfs/*/*/{dir}/{filename}')[0])\"".\
137 format(default=DEFAULT_XDG_RUNTIME_DIR,
138 dir=dir_to_map,
139 filename=filename)
140
141 file_path = self.remote_helper.run(cmd_line).strip()
142 if file_path:
143 return os.path.dirname(file_path)
144 return None
145
146 def calculate_device_mtp_dir(self):
147 """ Get the path in the ubuntu host machine which maps to the mtp dir.
148 Use a random file to identify the device internal storage destination.
149 """
150 file = fs.create_random_file(DOCS_DIR, ext='.tmp')
151 self.addCleanup(os.remove, file)
152 docs_mtp_dir = self.get_device_mtp_dir(DOCS, os.path.basename(file))
153 return os.path.dirname(docs_mtp_dir)
154
155 def get_device_mtp_path(self, *paths):
156 """ Retrieve the mtp path following the desired paths
157 :param paths: A list of subdir to the destination path
158 :return: The mtp path already escaped to the destination path
159 """
160 dir = os.path.join(self.mtp_dir, *paths)
161 return '"' + dir + '"'
16259
163 def verify_music_album_is_shown(self, album):60 def verify_music_album_is_shown(self, album):
164 """ Determines if there is an album with the desired name in the music61 """ Determines if there is an album with the desired name in the music
@@ -169,33 +66,6 @@
169 music_scope = music.MusicScope(get_dash().open_music_scope())66 music_scope = music.MusicScope(get_dash().open_music_scope())
170 self.assertTrue(music_scope.is_album(album))67 self.assertTrue(music_scope.is_album(album))
17168
172 def create_remote_dir(self, parent_dir):
173 """
174 Create a dir with random name in the remote host
175 :param parent_dir: the name of the parent dir where the new dir has to
176 be created
177 :return: the dir name and its full path
178 """
179 dir_name = fs.get_random_string()
180 dir_path = os.path.join(parent_dir, dir_name)
181 self.remote_helper.create_dir(dir_path)
182
183 return dir_name, dir_path
184
185 def copy_file_to_remote_host(self, file_path, remote_dir):
186 """ Copy a local file to a remote host
187 :param file_path: the local dire where the file is located
188 :param remote_dir: the remote dir where the file is going to be copied
189 :return: the full path of the file in the remote host
190 """
191 dst_file = os.path.join(remote_dir, os.path.basename(file_path))
192 logger.info("Copying local file {file_path} to remote host on "
193 "{dst_file}".format(file_path=file_path,
194 dst_file=dst_file))
195 self.remote_helper.copy(file_path, dst_file)
196 self.addCleanup(self.remote_helper.remove_file, dst_file)
197 return dst_file
198
199 def verify_same_files(self, src_files, dst_files):69 def verify_same_files(self, src_files, dst_files):
200 """ Verify both file lists contains the same files70 """ Verify both file lists contains the same files
201 :param src_files: list of src file names71 :param src_files: list of src file names
@@ -210,67 +80,33 @@
210 :param dst_files: list of files copied to the copied in the device80 :param dst_files: list of files copied to the copied in the device
211 """81 """
212 for file in dst_files:82 for file in dst_files:
213 self.assertTrue(fs.compare_files(src_file,83 self.assertTrue(src_file.compare(os.path.join(dst_dir, file)))
214 os.path.join(dst_dir, file)))84
21585 def prepare_music_albums(self, mp3_file, ogg_file):
216 def replicate_file(self, src_file, dst_dir, dst_files):
217 """ Copy the src file to the dst directory with the different names
218 stored in the dst_files variable
219 :param src_file: the source file to replicate
220 :param dst_dir: the destination directory to copy the files
221 :param dst_files: the target names to use
222 """
223 for file in dst_files:
224 self.remote_helper.copy_file(src_file,
225 os.path.join(dst_dir, file))
226
227 def verify_file_copied(self, base_dir, file_name):
228 """ Verify the file was copied to the base directory
229 :param base_dir: the directory where the file has to be copied
230 :param file_name: the name of the copied file
231 :return: the destination path where the file was copied
232 """
233 copied_file = os.path.join(base_dir, file_name)
234 self.assertTrue(os.path.isfile(copied_file))
235 self.addCleanup(os.remove, copied_file)
236 return copied_file
237
238 def verify_dir_copied(self, base_dir, dir_name):
239 """ Verify the dir was copied to the base directory
240 :param base_dir: the directory where the dir name has to be copied
241 :param dir_name: the name of the copied dir
242 :return: the destination path where the dir was copied
243 """
244 copied_dir = os.path.join(base_dir, dir_name)
245 self.assertTrue(os.path.isdir(copied_dir))
246 self.addCleanup(fs.remove_dir, copied_dir)
247 return copied_dir
248
249 def prepare_music_albums(self, src_mp3_file, src_ogg_file):
250 """ Prepare the albums in the remote host with the song to be copied86 """ Prepare the albums in the remote host with the song to be copied
251 It creates one dir with two albums inside, each album has 3 songs with87 It creates one dir with two albums inside, each album has 3 songs with
252 mp3 and ogg formats respectively88 mp3 and ogg formats respectively
253 :return: the
254 """89 """
25590
256 # Create music albums structure in the host machine91 # Create music albums structure in the host machine
257 (albums_name, albums_dir) = self.create_remote_dir(TEMP_DIR)92 albums_dir = self.factory.create_remote_dir()
258 (album_mp3_name, album_mp3_dir) = self.create_remote_dir(albums_dir)93 album_mp3_dir = self.factory.create_remote_dir(
259 (album_ogg_name, album_ogg_dir) = self.create_remote_dir(albums_dir)94 path=albums_dir.remote_src_path)
260 self.addCleanup(self.remote_helper.remove_dir, albums_dir)95 album_ogg_dir = self.factory.create_remote_dir(
96 path=albums_dir.remote_src_path)
26197
262 # Copy the music files to the ubuntu host machine98 # Copy the music files to the ubuntu host machine
263 dst_tmp_mp3_file = \99 mp3_file.send_to_host(fs.DIR_TEMP)
264 self.copy_file_to_remote_host(src_mp3_file, TEMP_DIR)100 ogg_file.send_to_host(fs.DIR_TEMP)
265 dst_tmp_ogg_file = \
266 self.copy_file_to_remote_host(src_ogg_file, TEMP_DIR)
267101
268 # Copy the music files in the ubuntu host machine to the albums102 # Copy the music files in the ubuntu host machine to the albums
269 # several times with different names and formats103 # several times with different names and formats
270 self.replicate_file(dst_tmp_mp3_file, album_mp3_dir, songs_album_mp3)104 self.mtp_helper.replicate_file(mp3_file, album_mp3_dir,
271 self.replicate_file(dst_tmp_ogg_file, album_ogg_dir, songs_album_ogg)105 songs_album_mp3)
106 self.mtp_helper.replicate_file(ogg_file, album_ogg_dir,
107 songs_album_ogg)
272108
273 return albums_name, albums_dir, album_mp3_name, album_ogg_name109 return albums_dir, album_mp3_dir, album_ogg_dir
274110
275 def verify_copied_files(self, seed_file, original_files, copied_dir):111 def verify_copied_files(self, seed_file, original_files, copied_dir):
276 """ Verify all the files have been copied correctly to the dst112 """ Verify all the files have been copied correctly to the dst
@@ -307,27 +143,33 @@
307143
308 # Prepare the albums structure in the remote machine previous to be144 # Prepare the albums structure in the remote machine previous to be
309 # copied to the device145 # copied to the device
310 src_mp3_file = os.path.join(fs.DIR_TEST_DATA_AUDIO,146 mp3_file = self.factory.create_file(
311 test_data.get('mp3_file').file)147 os.path.join(fs.DIR_TEST_DATA_AUDIO,
312 src_ogg_file = os.path.join(fs.DIR_TEST_DATA_AUDIO,148 test_data.get('mp3_file').file))
313 test_data.get('ogg_file').file)149 ogg_file = self.factory.create_file(
314 albums_name, albums_dir, album_mp3_name, album_ogg_name = \150 os.path.join(fs.DIR_TEST_DATA_AUDIO,
315 self.prepare_music_albums(src_mp3_file, src_ogg_file)151 test_data.get('ogg_file').file))
152
153 albums_dir, album_mp3_dir, album_ogg_dir = \
154 self.prepare_music_albums(mp3_file, ogg_file)
316155
317 # Copy the albums directory from the temporal dir in the ubuntu host156 # Copy the albums directory from the temporal dir in the ubuntu host
318 # machine to the dir which maps the music dir in the device157 # machine to the dir which maps the music dir in the device
319 device_mtp_albums_path = self.get_device_mtp_path(MUSIC, albums_name)158 mtp_albums_path = self.mtp_helper.get_mtp_path(fs.DIR_MUSIC,
320 self.remote_helper.copy_dir(albums_dir, device_mtp_albums_path)159 albums_dir.name)
160 albums_dir.remote_copy(mtp_albums_path)
321161
322 # Verify the albums have ben copied to the music folder162 # Verify the albums have ben copied to the music folder
323 copied_albums = self.verify_dir_copied(MUSIC_DIR, albums_name)163 albums_dir.local_dst_path = os.path.join(fs.DIR_HOME_MUSIC,
164 albums_dir.name)
165 self.assertTrue(os.path.isdir(albums_dir.local_dst_path))
324166
325 copied_album_mp3 = os.path.join(copied_albums, album_mp3_name)167 dst_path = os.path.join(albums_dir.local_dst_path, album_mp3_dir.name)
326 self.verify_songs(src_mp3_file, songs_album_mp3, copied_album_mp3,168 self.verify_songs(mp3_file, songs_album_mp3, dst_path,
327 test_data.get('mp3_file').album)169 test_data.get('mp3_file').album)
328170
329 copied_album_ogg = os.path.join(copied_albums, album_ogg_name)171 dst_path = os.path.join(albums_dir.local_dst_path, album_ogg_dir.name)
330 self.verify_songs(src_ogg_file, songs_album_ogg, copied_album_ogg,172 self.verify_songs(ogg_file, songs_album_ogg, dst_path,
331 test_data.get('ogg_file').album)173 test_data.get('ogg_file').album)
332174
333 def test_copy_large_number_of_files(self):175 def test_copy_large_number_of_files(self):
@@ -336,53 +178,43 @@
336 original.178 original.
337 """179 """
338 amount = 100180 amount = 100
339 src_file_name = test_data.get('text_file')181 myfile = self.factory.create_file(
340 src_file = os.path.join(fs.DIR_TEST_DATA_TEXT, src_file_name)182 os.path.join(fs.DIR_TEST_DATA_TEXT, test_data.get('text_file')))
341183
342 # Create the dir to store the files in the host machine184 # Create the dir to store the files in the host machine
343 (dir_name, dir_path) = self.create_remote_dir(TEMP_DIR)185 mydir = self.factory.create_remote_dir()
344 self.addCleanup(self.remote_helper.remove_dir, dir_path)
345186
346 # Copy the src file to the ubuntu host machine187 # Copy the src file to the ubuntu host machine
347 dst_tmp_file = self.copy_file_to_remote_host(src_file, TEMP_DIR)188 myfile.send_to_host(fs.DIR_TEMP)
348189
349 # Replicate the src file 100 times190 # Replicate the src file 100 times
350 original_files = [src_file_name + "_" + str(i) for i in range(amount)]191 original_files = [myfile.name + "_" + str(i) for i in range(amount)]
351 self.replicate_file(dst_tmp_file, dir_path, original_files)192 self.mtp_helper.replicate_file(myfile, mydir, original_files)
352193
353 # Copy the directory from the temporal dir in the ubuntu host194 # Copy the directory from the temporal dir in the ubuntu host
354 # machine to the dir which maps the documents dir in the device195 # machine to the dir which maps the documents dir in the device
355 device_mtp_dir_path = self.get_device_mtp_path(DOCS, dir_name)196 mydir.remote_copy(self.mtp_helper.get_mtp_path(fs.DIR_DOCUMENTS,
356 logger.info("Copying remote files to mtp directory from {src_path} to "197 mydir.name))
357 "{mtp_path}".format(src_path=dir_path,
358 mtp_path=device_mtp_dir_path))
359 self.remote_helper.copy_dir(dir_path, device_mtp_dir_path)
360198
361 # Verify the files have ben copied correctly to the destiation199 # Verify the files have ben copied correctly to the destiation
362 copied_dir = self.verify_dir_copied(DOCS_DIR, dir_name)200 mydir.local_dst_path = os.path.join(fs.DIR_HOME_DOCUMENTS, mydir.name)
363 self.verify_copied_files(src_file, original_files, copied_dir)201 self.assertTrue(os.path.isdir(mydir.local_dst_path))
202 self.verify_copied_files(myfile, original_files, mydir.local_dst_path)
364203
365 def _test_copy_big_file(self, kb=0, mb=0, gb=0):204 def _test_copy_big_file(self, kb=0, mb=0, gb=0):
366 # Create the remote file with random content and get the sha1 digest205 # Create the remote file with random content and get the sha1 digest
367 file_name = fs.get_random_string() + ".tmp"206 file = self.factory.create_remote_file(ext='.tmp', kb=kb, mb=mb, gb=gb)
368 file_path = os.path.join(TEMP_DIR, file_name)
369
370 self.remote_helper.create_random_file(file_path, kb=kb, mb=mb, gb=gb)
371 self.addCleanup(self.remote_helper.remove_file, file_path)
372 file_sha1 = self.remote_helper.get_sha1(file_path).strip()
373
374 # Copy the directory from the temporal dir in the ubuntu host207 # Copy the directory from the temporal dir in the ubuntu host
375 # machine to the dir which maps the documents dir in the device208 # machine to the dir which maps the documents dir in the device
376 device_mtp_dst_path = self.get_device_mtp_path(DOCS, file_name)209 file.remote_copy(self.mtp_helper.get_mtp_path(fs.DIR_DOCUMENTS,
377 logger.info("Copying remote files to mtp directory from {src_path} to "210 file.name))
378 "{mtp_path}".format(src_path=file_path,
379 mtp_path=device_mtp_dst_path))
380 self.remote_helper.copy_file(file_path, device_mtp_dst_path)
381211
382 # Verify the files have ben copied correctly to the destiation212 # Verify the files have ben copied correctly to the destiation
383 copied_file = self.verify_file_copied(DOCS_DIR, file_name)213 file.local_dst_path = os.path.join(fs.DIR_HOME_DOCUMENTS, file.name)
384 copied_sha1 = fs.calculate_file_sha1(copied_file)214 self.assertTrue(os.path.isfile(file.local_dst_path))
385 self.assertEqual(file_sha1, copied_sha1)215
216 copied_sha1 = fs.calculate_file_sha1(file.local_dst_path)
217 self.assertEqual(file.sha1, copied_sha1)
386218
387 def test_copy_big_1gb_file(self):219 def test_copy_big_1gb_file(self):
388 """ Copy a big file (almost 2GB) through mtp and check the file has220 """ Copy a big file (almost 2GB) through mtp and check the file has
@@ -415,21 +247,24 @@
415 """247 """
416248
417 # Create random source data and calculate the sha1 digest249 # Create random source data and calculate the sha1 digest
418 song = self.create_random_file(MUSIC_DIR, ext='.mp3')250 song = self.factory.create_random_file(fs.DIR_HOME_MUSIC, ext='.mp3')
419 song.remote_src_path = self.get_device_mtp_path(MUSIC, song.name)251 song.remote_src_path = \
420252 self.mtp_helper.get_mtp_path(fs.DIR_MUSIC, song.name)
421 video = self.create_random_file(VIDEOS_DIR, ext='.avi')253
422 video.remote_src_path = self.get_device_mtp_path(VIDEOS, video.name)254 video = self.factory.create_random_file(fs.DIR_HOME_VIDEOS, ext='.avi')
423255 video.remote_src_path = \
424 picture = self.create_random_file(PICTURES_DIR, ext='.jpg')256 self.mtp_helper.get_mtp_path(fs.DIR_VIDEOS, video.name)
425 picture.remote_src_path = self.get_device_mtp_path(PICTURES,257
426 picture.name)258 picture = self.factory.create_random_file(fs.DIR_HOME_PICTURES,
259 ext='.jpg')
260 picture.remote_src_path = \
261 self.mtp_helper.get_mtp_path(fs.DIR_PICTURES, picture.name)
427262
428 files = [song, video, picture]263 files = [song, video, picture]
429264
430 # Set destination path to files265 # Set destination path to files
431 for file in files:266 for file in files:
432 file.remote_dst_path = os.path.join(TEMP_DIR, file.name)267 file.remote_dst_path = os.path.join(fs.DIR_TEMP, file.name)
433268
434 # Copy the files from mtp to tmp directory and verify the sha1269 # Copy the files from mtp to tmp directory and verify the sha1
435 for file in files:270 for file in files:
@@ -440,4 +275,4 @@
440 # Remove remote files and verify the files were deleted in the device275 # Remove remote files and verify the files were deleted in the device
441 for file in files:276 for file in files:
442 self.remote_helper.remove_file(file.remote_src_path)277 self.remote_helper.remove_file(file.remote_src_path)
443 self.assertFalse(os.path.isfile(file.local_path))278 self.assertFalse(os.path.isfile(file.local_src_path))

Subscribers

People subscribed via source and target branches

to all changes: