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

Proposed by Sergio Cazzolato on 2015-07-17
Status: Merged
Approved by: Brendan Donegan on 2015-07-22
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 on 2015-07-22
Brendan Donegan (community) Approve on 2015-07-22
PS Jenkins bot continuous-integration Approve on 2015-07-17
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.
155. By Sergio Cazzolato on 2015-07-17

Fix test cases test_copy_large_number_of_files

Brendan Donegan (brendan-donegan) wrote :

Code looks fine and everything seems to still work

review: Approve
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
1=== modified file 'ubuntu_system_tests/helpers/file_system.py'
2--- ubuntu_system_tests/helpers/file_system.py 2015-07-15 11:06:17 +0000
3+++ ubuntu_system_tests/helpers/file_system.py 2015-07-17 19:25:19 +0000
4@@ -51,6 +51,8 @@
5 DIR_TEST_DATA_TEXT = os.path.join(DIR_TEST_DATA, 'text')
6 DIR_TEST_DATA_VIDEO = os.path.join(DIR_TEST_DATA, 'video')
7
8+DIR_TEMP = '/tmp'
9+
10
11 def delete_file(file_name):
12 """Delete the file passed as parameter. In case the file does not
13@@ -78,13 +80,18 @@
14
15 def remove_dir(dir_path):
16 """Remove the directory"""
17- shutil.rmtree(dir_path, True)
18+ if os.path.isdir(dir_path):
19+ shutil.rmtree(dir_path, True)
20
21
22 def clean_dir(dir_path):
23 """Delete all the content of the directory"""
24- remove_dir(dir_path)
25- os.makedirs(dir_path)
26+ for obj in os.listdir(dir_path):
27+ obj_path = os.path.join(dir_path, obj)
28+ if os.path.isfile(obj_path):
29+ os.remove(obj_path)
30+ else:
31+ remove_dir(obj_path)
32
33
34 def calculate_file_sha1(file_path):
35
36=== added file 'ubuntu_system_tests/helpers/mtp.py'
37--- ubuntu_system_tests/helpers/mtp.py 1970-01-01 00:00:00 +0000
38+++ ubuntu_system_tests/helpers/mtp.py 2015-07-17 19:25:19 +0000
39@@ -0,0 +1,302 @@
40+
41+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
42+
43+# Ubuntu System Tests
44+# Copyright (C) 2015 Canonical
45+#
46+# This program is free software: you can redistribute it and/or modify
47+# it under the terms of the GNU General Public License as published by
48+# the Free Software Foundation, either version 3 of the License, or
49+# (at your option) any later version.
50+#
51+# This program is distributed in the hope that it will be useful,
52+# but WITHOUT ANY WARRANTY; without even the implied warranty of
53+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54+# GNU General Public License for more details.
55+#
56+# You should have received a copy of the GNU General Public License
57+# along with this program. If not, see <http://www.gnu.org/licenses/>.
58+
59+import logging
60+import os
61+import shutil
62+
63+from ubuntu_system_tests.helpers import file_system as fs
64+
65+logger = logging.getLogger(__name__)
66+
67+DEFAULT_XDG_RUNTIME_DIR = '/run/user/1000'
68+
69+
70+class MTPObjBase:
71+ """ Base class used to represent objects that are copied through mtp"""
72+
73+ def __init__(self, remote_helper):
74+ self.remote_helper = remote_helper
75+ self.local_src_path = ""
76+ self.local_dst_path = ""
77+ self.remote_src_path = ""
78+ self.remote_dst_path = ""
79+
80+ def validate_remote_copy(self):
81+ """ Validate the src and dst paths are defined """
82+ if not self.remote_src_path or not self.remote_dst_path:
83+ raise RuntimeError("Remote copy cannot be done, remote_src_path "
84+ "and remote_mtp_path have to be defined")
85+
86+ def validate_send_to_host(self):
87+ """ Validate the src and dst paths are defined """
88+ if not self.local_src_path or not self.remote_src_path:
89+ raise RuntimeError("Send to host cannot be done, local_src_path "
90+ "and remote_src_path have to be defined")
91+
92+
93+class MTPFile(MTPObjBase):
94+ """ This class represents a file which is copied through mtp"""
95+
96+ def __init__(self, remote_helper):
97+ super(MTPFile, self).__init__(remote_helper)
98+ self.sha1 = ""
99+
100+ @property
101+ def name(self):
102+ """ Retrieve the name based of the paths defined """
103+ return os.path.basename(self.local_src_path) or \
104+ os.path.basename(self.remote_src_path) or \
105+ os.path.basename(self.remote_dst_path) or \
106+ os.path.basename(self.local_dst_path)
107+
108+ def clean(self):
109+ """ Clean the file in the different places where the file has been
110+ copied. This method is used mainly for the clean up of the file """
111+ fs.delete_file(self.local_src_path)
112+ if self.remote_src_path:
113+ self.remote_helper.remove_file(self.remote_src_path)
114+ if self.remote_dst_path:
115+ self.remote_helper.remove_file(self.remote_dst_path)
116+ fs.delete_file(self.local_dst_path)
117+
118+ def remote_copy(self, remote_dst_path=None):
119+ """ Copy the file in the remote host from src to dst
120+ :param remote_dst_path: the remote destination in case it has not been
121+ defined previously
122+ """
123+ if remote_dst_path:
124+ self.remote_dst_path = remote_dst_path
125+ self.validate_remote_copy()
126+ logger.info("Copying remote file from {src_path} to {mtp_path}".
127+ format(src_path=self.remote_src_path,
128+ mtp_path=self.remote_dst_path))
129+ self.remote_helper.copy_file(self.remote_src_path,
130+ self.remote_dst_path)
131+
132+ def get_remote_dst_sha1(self):
133+ """ Get the sha1 digest calculated in the remote host for the file
134+ located in the remote_dst_path
135+ """
136+ if not self.remote_dst_path:
137+ raise RuntimeError("Attribute remote_dst_path has to de defined")
138+ return self.remote_helper.get_sha1(self.remote_dst_path)
139+
140+ def send_to_host(self, path=None):
141+ """ Send the file from the device to the ubuntu host. The
142+ remote_src_path will be updated in case the path is defined
143+ :param path: The path in the remote host where the file is copied
144+ """
145+ if path:
146+ self.remote_src_path = os.path.join(path, self.name)
147+ self.validate_send_to_host()
148+ logger.info("Sending file to remote host from {local_path} to "
149+ "{remote_path}".format(local_path=self.local_src_path,
150+ remote_path=self.remote_src_path))
151+ self.remote_helper.put(self.local_src_path, self.remote_src_path)
152+
153+ def compare(self, file_path):
154+ """ Compare the local file to the file located in the path
155+ :return:True if the files are equal, false otherwise
156+ """
157+ return fs.compare_files(self.local_src_path, file_path)
158+
159+
160+class MTPDir(MTPObjBase):
161+ """ This class represents a directory which is copied through mtp"""
162+
163+ def __init__(self, remote_helper):
164+ super(MTPDir, self).__init__(remote_helper)
165+
166+ @property
167+ def name(self):
168+ """ Retrieve the name based of the paths defined """
169+ return os.path.basename(self.local_src_path) or \
170+ os.path.basename(self.remote_src_path) or \
171+ os.path.basename(self.remote_dst_path) or \
172+ os.path.basename(self.local_dst_path)
173+
174+ def clean(self):
175+ """ Clean the dir in the different places where the dir has been
176+ copied. This method is used mainly for the clean up of the dir """
177+ fs.remove_dir(self.local_src_path)
178+ if self.remote_src_path:
179+ self.remote_helper.remove_dir(self.remote_src_path)
180+ if self.remote_dst_path:
181+ self.remote_helper.remove_dir(self.remote_dst_path)
182+ fs.remove_dir(self.local_dst_path)
183+
184+ def remote_copy(self, remote_dst_path=None):
185+ """ Copy the dir in the remote host from src to dst
186+ :param remote_dst_path: the remote destination in case it has not been
187+ defined previously
188+ """
189+ if remote_dst_path:
190+ self.remote_dst_path = remote_dst_path
191+ self.validate_remote_copy()
192+ logger.info("Copying remote directory from {src_path} to {mtp_path}".
193+ format(src_path=self.remote_src_path,
194+ mtp_path=self.remote_dst_path))
195+ self.remote_helper.copy_dir(self.remote_src_path,
196+ self.remote_dst_path)
197+
198+
199+class MTPObjFactory:
200+ """ A factory class used to create the mtp entities in the local and
201+ remote host """
202+
203+ def __init__(self, remote_helper, clean_up):
204+ """
205+ :param remote_helper: The helper to interact with the remote host
206+ :param clean_up: The method used to clean up the objects created
207+ """
208+ self.remote_helper = remote_helper
209+ self.clean_up = clean_up
210+
211+ def new_file(self):
212+ """ Create an MTPFile object and add a clean up for it """
213+ file = MTPFile(self.remote_helper)
214+ self.clean_up(file.clean)
215+ return file
216+
217+ def create_random_file(self, dir, ext='', sha1=True):
218+ """ Create a MTPFile object with random name
219+ :param dir: The dir where the file is created
220+ :param ext: The extension of the file to be created
221+ :param sha1: if True, the sha1 is calculated and stores in the file
222+ :return: The created file with the local src path already set
223+ """
224+ file = self.new_file()
225+ file.local_src_path = fs.create_random_file(dir, ext)
226+ if sha1:
227+ file.sha1 = fs.calculate_file_sha1(file.local_src_path)
228+ return file
229+
230+ def create_file(self, src_file, temp=True):
231+ """ Create a MTPFile object based on a real file
232+ :param src_file: The real file used to create the MTPFile obj
233+ :param temp: if True, the file is copied to a temp dir. The temp is
234+ used to avoid the original file is deleted in the clean-up
235+ :return: The created file object with the local src path already set
236+ """
237+ file = self.new_file()
238+ file.local_src_path = src_file
239+ if temp:
240+ file.local_src_path = os.path.join(fs.DIR_TEMP, file.name)
241+ shutil.copy(src_file, file.local_src_path)
242+ return file
243+
244+ def create_remote_file(self, path=None, name=None, ext='', sha1=True,
245+ kb=0, mb=0, gb=0):
246+ """ Create a file in the remote host
247+ :param path: The path where the file is created, if None, the file will
248+ be created in a temp dir
249+ :param name: The name of the file to be created, if None, will be used
250+ a random name
251+ :param ext: the extension of the file
252+ :param sha1: if True, the sha1 is calculated and stores in the file
253+ :param kb: The kilobytes of the file to be created
254+ :param mb: The megabytes of the file to be created
255+ :param gb: The gigabytes of the file to be created
256+ :return: The created file with random content and size equals to
257+ kb kilobytes + mb megabytes + gb gigabytes
258+ """
259+ file = self.new_file()
260+ file_path = path or fs.DIR_TEMP
261+ file_name = name or fs.get_random_string()
262+ file.remote_src_path = os.path.join(file_path, file_name + ext)
263+ self.remote_helper.create_random_file(file.remote_src_path, kb=kb,
264+ mb=mb, gb=gb)
265+ if sha1:
266+ file.sha1 = self.remote_helper.get_sha1(file.remote_src_path)
267+ return file
268+
269+ def new_dir(self):
270+ """ Create an MTPDir object and add a clean up for it """
271+ dir = MTPDir(self.remote_helper)
272+ self.clean_up(dir.clean)
273+ return dir
274+
275+ def create_remote_dir(self, path=None, name=None):
276+ """
277+ Create a dir in the remote host
278+ :param path: the name path where the new dir has to be created
279+ :param name: the name of the dir, in case the name is not defined,
280+ a random name is used
281+ """
282+ dir = self.new_dir()
283+ dir_path = path or fs.DIR_TEMP
284+ dir_name = name or fs.get_random_string()
285+ dir.remote_src_path = os.path.join(dir_path, dir_name)
286+ self.remote_helper.create_dir(dir.remote_src_path)
287+ return dir
288+
289+
290+class MTPHelper:
291+
292+ def __init__(self, remote_helper):
293+ self.remote_helper = remote_helper
294+ self.mtp_dir = self._calculate_mtp_dir()
295+
296+ def get_mtp_path(self, *paths):
297+ """ Retrieve the mtp path following the desired paths
298+ :param paths: A list of subdir to the destination path
299+ :return: The mtp path already escaped to the destination path
300+ """
301+ return '"' + os.path.join(self.mtp_dir, *paths) + '"'
302+
303+ def _calculate_mtp_dir(self):
304+ """ Get the path in the ubuntu host machine which maps to the mtp dir.
305+ Use a random file to identify the device internal storage destination.
306+ """
307+ file = fs.create_random_file(fs.DIR_HOME_DOCUMENTS, ext='.tmp')
308+ docs_mtp_dir = self._get_mtp_dir(fs.DIR_DOCUMENTS,
309+ os.path.basename(file))
310+ os.remove(file)
311+ return os.path.dirname(docs_mtp_dir)
312+
313+ def _get_mtp_dir(self, dir_to_map, filename):
314+ """ Determine the full_path in the ubuntu host machine which maps the
315+ file and directory in the device
316+ :param dir_to_map: The directory to map
317+ :param filename: The name of the file to be mapped
318+ :return: the full path that maps the dir_to_map and filename in the
319+ device
320+ """
321+ cmd_line = "python3 -c \"import glob; import os; " \
322+ "print(glob.glob(os.getenv('XDG_RUNTIME_DIR', " \
323+ "'{default}') + '/gvfs/*/*/{dir}/{filename}')[0])\"".\
324+ format(default=DEFAULT_XDG_RUNTIME_DIR,
325+ dir=dir_to_map,
326+ filename=filename)
327+
328+ file_path = self.remote_helper.run(cmd_line).strip()
329+ if file_path:
330+ return os.path.dirname(file_path)
331+ return None
332+
333+ def replicate_file(self, src_file, dst_dir, dst_files):
334+ """ Copy the src file to the dst directory with the different names
335+ stored in the dst_files variable
336+ :param src_file: the source file to replicate
337+ :param dst_dir: the destination directory to copy the files
338+ :param dst_files: the target names to use
339+ """
340+ for file in dst_files:
341+ src_file.remote_copy(os.path.join(dst_dir.remote_src_path, file))
342
343=== modified file 'ubuntu_system_tests/helpers/ssh.py'
344--- ubuntu_system_tests/helpers/ssh.py 2015-07-10 19:41:55 +0000
345+++ ubuntu_system_tests/helpers/ssh.py 2015-07-17 19:25:19 +0000
346@@ -21,6 +21,8 @@
347 import os
348 import paramiko
349
350+from ubuntu_system_tests import config
351+
352 logger = logging.getLogger(__name__)
353
354
355@@ -45,19 +47,26 @@
356
357 return "".join(stdout.readlines())
358
359- def copy(self, localpath, remotepath):
360- """Copy a file through sftp from the localpath to the remotepath"""
361- if not os.path.isfile(localpath):
362+ def put(self, local_path, remote_path):
363+ """Copy a file through sftp from the local_path to the remote_path"""
364+ if not os.path.isfile(local_path):
365 raise RuntimeError("File to copy does not exist")
366
367 sftp = self.client.open_sftp()
368- sftp.put(localpath, remotepath)
369+ sftp.put(local_path, remote_path)
370 sftp.close()
371
372
373 class LinuxRemoteHelper(SSH):
374 """This class executes remote linux commands through the ssh connection"""
375
376+ def __init__(self):
377+ config_stack = config.get_device_config_stack()
378+ host = config_stack.get('ssh_ip')
379+ user = config_stack.get('ssh_user')
380+ password = config_stack.get('ssh_password')
381+ super(LinuxRemoteHelper, self).__init__(host, user, password)
382+
383 def remove_dir(self, dir_name):
384 self.run('rm -rf {}'.format(dir_name))
385
386@@ -85,7 +94,7 @@
387 :param mb: The megabytes of the file
388 :param gb: The gigabytes fo the file
389 :return: The file path to the created file with random content and size
390- equals to kb KiloBytes + mb MegaBytes + gb GigaBytes
391+ equals to kb kilobytes + mb megabytes + gb gigabytes
392 """
393 count = kb + mb * 1024 + gb * 1024 * 1024
394 self.run('dd if=/dev/urandom of={file} bs=1024 count={count}'.
395
396=== modified file 'ubuntu_system_tests/tests/test_mtp.py'
397--- ubuntu_system_tests/tests/test_mtp.py 2015-07-15 11:06:17 +0000
398+++ ubuntu_system_tests/tests/test_mtp.py 2015-07-17 19:25:19 +0000
399@@ -22,26 +22,14 @@
400 import logging
401 import os
402
403-from ubuntu_system_tests import config
404 from ubuntu_system_tests.helpers import file_system as fs
405+from ubuntu_system_tests.helpers.mtp import MTPObjFactory, MTPHelper
406 from ubuntu_system_tests.helpers import ssh
407 from ubuntu_system_tests.helpers.scopes import music
408 from ubuntu_system_tests.helpers.unity8.dash import get_dash
409
410 from ubuntu_system_tests.tests import base
411
412-TEMP_DIR = '/tmp'
413-DEFAULT_XDG_RUNTIME_DIR = '/run/user/1000'
414-
415-MUSIC = "Music"
416-MUSIC_DIR = os.path.join(os.path.expanduser("~"), MUSIC)
417-DOCS = "Documents"
418-DOCS_DIR = os.path.join(os.path.expanduser("~"), DOCS)
419-PICTURES = "Pictures"
420-PICTURES_DIR = os.path.join(os.path.expanduser("~"), PICTURES)
421-VIDEOS = "Videos"
422-VIDEOS_DIR = os.path.join(os.path.expanduser("~"), VIDEOS)
423-
424 FileMusicDesc = namedtuple('FileMusicDesc', ['file', 'album'])
425 logger = logging.getLogger(__name__)
426 songs_album_mp3 = ['song_1.mp3', 'song_2.mp3', 'song_3.mp3']
427@@ -57,108 +45,17 @@
428 }
429
430
431-class MTPFile:
432- """ This class is a data model which represents a file to be copied
433- through mtp
434- """
435- def __init__(self, remote_helper):
436- self.remote_helper = remote_helper
437- self.local_path = ""
438- self.remote_src_path = ""
439- self.remote_dst_path = ""
440- self.sha1 = ""
441-
442- @property
443- def name(self):
444- return os.path.basename(self.local_path) or ""
445-
446- def clean_file(self):
447- if self.local_path:
448- fs.delete_file(self.local_path)
449- if self.remote_src_path:
450- self.remote_helper.remove_file(self.remote_src_path)
451- if self.remote_dst_path:
452- self.remote_helper.remove_file(self.remote_dst_path)
453-
454- def remote_copy(self):
455- if not self.remote_src_path or not self.remote_dst_path:
456- raise RuntimeError("Remote copy cannot be done, it is required to "
457- "define src and dst paths,")
458- logger.info("Copying remote file from {src_path} to {dst_path}".
459- format(src_path=self.remote_src_path,
460- dst_path=self.remote_dst_path))
461- self.remote_helper.copy_file(self.remote_src_path,
462- self.remote_dst_path)
463-
464- def get_remote_dst_sha1(self):
465- if not self.remote_dst_path:
466- raise RuntimeError("Attribute remote_dst_path has to de defined")
467- return self.remote_helper.get_sha1(self.remote_dst_path)
468-
469-
470 class MTPTest(base.BaseUbuntuSystemTestCase):
471 """This Class tests the mtp protocol"""
472
473 def setUp(self):
474 super().setUp()
475
476- self.config_stack = config.get_device_config_stack()
477 self.unity_proxy = self.restart_unity()
478- self.remote_helper = ssh.LinuxRemoteHelper(
479- self.config_stack.get('ssh_ip'),
480- self.config_stack.get('ssh_user'),
481- self.config_stack.get('ssh_password'))
482+ self.remote_helper = ssh.LinuxRemoteHelper()
483 self.addCleanup(self.remote_helper.close)
484- self.mtp_dir = self.calculate_device_mtp_dir()
485-
486- def create_random_file(self, dir, ext='', sha1=True):
487- file = MTPFile(self.remote_helper)
488- file.local_path = fs.create_random_file(dir, ext)
489- if sha1:
490- file.sha1 = fs.calculate_file_sha1(file.local_path)
491- self.addCleanup(file.clean_file)
492- return file
493-
494- def get_first_elem_in_dir_command(self, path):
495- """Command to retrieve the first element in a dir"""
496- return 'ls {} | sort -n | head -1'.format(path)
497-
498- def get_device_mtp_dir(self, dir_to_map, filename):
499- """ Determine the full_path in the ubuntu host machine which maps the
500- file and directory in the device
501- :param dir_to_map: The directory to map
502- :param filename: The name of the file to be mapped
503- :return: the full path that maps the dir_to_map and filename in the
504- device
505- """
506- cmd_line = "python3 -c \"import glob; import os; " \
507- "print(glob.glob(os.getenv('XDG_RUNTIME_DIR', " \
508- "'{default}') + '/gvfs/*/*/{dir}/{filename}')[0])\"".\
509- format(default=DEFAULT_XDG_RUNTIME_DIR,
510- dir=dir_to_map,
511- filename=filename)
512-
513- file_path = self.remote_helper.run(cmd_line).strip()
514- if file_path:
515- return os.path.dirname(file_path)
516- return None
517-
518- def calculate_device_mtp_dir(self):
519- """ Get the path in the ubuntu host machine which maps to the mtp dir.
520- Use a random file to identify the device internal storage destination.
521- """
522- file = fs.create_random_file(DOCS_DIR, ext='.tmp')
523- self.addCleanup(os.remove, file)
524- docs_mtp_dir = self.get_device_mtp_dir(DOCS, os.path.basename(file))
525- return os.path.dirname(docs_mtp_dir)
526-
527- def get_device_mtp_path(self, *paths):
528- """ Retrieve the mtp path following the desired paths
529- :param paths: A list of subdir to the destination path
530- :return: The mtp path already escaped to the destination path
531- """
532- dir = os.path.join(self.mtp_dir, *paths)
533- return '"' + dir + '"'
534+ self.factory = MTPObjFactory(self.remote_helper, self.addCleanup)
535+ self.mtp_helper = MTPHelper(self.remote_helper)
536
537 def verify_music_album_is_shown(self, album):
538 """ Determines if there is an album with the desired name in the music
539@@ -169,33 +66,6 @@
540 music_scope = music.MusicScope(get_dash().open_music_scope())
541 self.assertTrue(music_scope.is_album(album))
542
543- def create_remote_dir(self, parent_dir):
544- """
545- Create a dir with random name in the remote host
546- :param parent_dir: the name of the parent dir where the new dir has to
547- be created
548- :return: the dir name and its full path
549- """
550- dir_name = fs.get_random_string()
551- dir_path = os.path.join(parent_dir, dir_name)
552- self.remote_helper.create_dir(dir_path)
553-
554- return dir_name, dir_path
555-
556- def copy_file_to_remote_host(self, file_path, remote_dir):
557- """ Copy a local file to a remote host
558- :param file_path: the local dire where the file is located
559- :param remote_dir: the remote dir where the file is going to be copied
560- :return: the full path of the file in the remote host
561- """
562- dst_file = os.path.join(remote_dir, os.path.basename(file_path))
563- logger.info("Copying local file {file_path} to remote host on "
564- "{dst_file}".format(file_path=file_path,
565- dst_file=dst_file))
566- self.remote_helper.copy(file_path, dst_file)
567- self.addCleanup(self.remote_helper.remove_file, dst_file)
568- return dst_file
569-
570 def verify_same_files(self, src_files, dst_files):
571 """ Verify both file lists contains the same files
572 :param src_files: list of src file names
573@@ -210,67 +80,33 @@
574 :param dst_files: list of files copied to the copied in the device
575 """
576 for file in dst_files:
577- self.assertTrue(fs.compare_files(src_file,
578- os.path.join(dst_dir, file)))
579-
580- def replicate_file(self, src_file, dst_dir, dst_files):
581- """ Copy the src file to the dst directory with the different names
582- stored in the dst_files variable
583- :param src_file: the source file to replicate
584- :param dst_dir: the destination directory to copy the files
585- :param dst_files: the target names to use
586- """
587- for file in dst_files:
588- self.remote_helper.copy_file(src_file,
589- os.path.join(dst_dir, file))
590-
591- def verify_file_copied(self, base_dir, file_name):
592- """ Verify the file was copied to the base directory
593- :param base_dir: the directory where the file has to be copied
594- :param file_name: the name of the copied file
595- :return: the destination path where the file was copied
596- """
597- copied_file = os.path.join(base_dir, file_name)
598- self.assertTrue(os.path.isfile(copied_file))
599- self.addCleanup(os.remove, copied_file)
600- return copied_file
601-
602- def verify_dir_copied(self, base_dir, dir_name):
603- """ Verify the dir was copied to the base directory
604- :param base_dir: the directory where the dir name has to be copied
605- :param dir_name: the name of the copied dir
606- :return: the destination path where the dir was copied
607- """
608- copied_dir = os.path.join(base_dir, dir_name)
609- self.assertTrue(os.path.isdir(copied_dir))
610- self.addCleanup(fs.remove_dir, copied_dir)
611- return copied_dir
612-
613- def prepare_music_albums(self, src_mp3_file, src_ogg_file):
614+ self.assertTrue(src_file.compare(os.path.join(dst_dir, file)))
615+
616+ def prepare_music_albums(self, mp3_file, ogg_file):
617 """ Prepare the albums in the remote host with the song to be copied
618 It creates one dir with two albums inside, each album has 3 songs with
619 mp3 and ogg formats respectively
620- :return: the
621 """
622
623 # Create music albums structure in the host machine
624- (albums_name, albums_dir) = self.create_remote_dir(TEMP_DIR)
625- (album_mp3_name, album_mp3_dir) = self.create_remote_dir(albums_dir)
626- (album_ogg_name, album_ogg_dir) = self.create_remote_dir(albums_dir)
627- self.addCleanup(self.remote_helper.remove_dir, albums_dir)
628+ albums_dir = self.factory.create_remote_dir()
629+ album_mp3_dir = self.factory.create_remote_dir(
630+ path=albums_dir.remote_src_path)
631+ album_ogg_dir = self.factory.create_remote_dir(
632+ path=albums_dir.remote_src_path)
633
634 # Copy the music files to the ubuntu host machine
635- dst_tmp_mp3_file = \
636- self.copy_file_to_remote_host(src_mp3_file, TEMP_DIR)
637- dst_tmp_ogg_file = \
638- self.copy_file_to_remote_host(src_ogg_file, TEMP_DIR)
639+ mp3_file.send_to_host(fs.DIR_TEMP)
640+ ogg_file.send_to_host(fs.DIR_TEMP)
641
642 # Copy the music files in the ubuntu host machine to the albums
643 # several times with different names and formats
644- self.replicate_file(dst_tmp_mp3_file, album_mp3_dir, songs_album_mp3)
645- self.replicate_file(dst_tmp_ogg_file, album_ogg_dir, songs_album_ogg)
646+ self.mtp_helper.replicate_file(mp3_file, album_mp3_dir,
647+ songs_album_mp3)
648+ self.mtp_helper.replicate_file(ogg_file, album_ogg_dir,
649+ songs_album_ogg)
650
651- return albums_name, albums_dir, album_mp3_name, album_ogg_name
652+ return albums_dir, album_mp3_dir, album_ogg_dir
653
654 def verify_copied_files(self, seed_file, original_files, copied_dir):
655 """ Verify all the files have been copied correctly to the dst
656@@ -307,27 +143,33 @@
657
658 # Prepare the albums structure in the remote machine previous to be
659 # copied to the device
660- src_mp3_file = os.path.join(fs.DIR_TEST_DATA_AUDIO,
661- test_data.get('mp3_file').file)
662- src_ogg_file = os.path.join(fs.DIR_TEST_DATA_AUDIO,
663- test_data.get('ogg_file').file)
664- albums_name, albums_dir, album_mp3_name, album_ogg_name = \
665- self.prepare_music_albums(src_mp3_file, src_ogg_file)
666+ mp3_file = self.factory.create_file(
667+ os.path.join(fs.DIR_TEST_DATA_AUDIO,
668+ test_data.get('mp3_file').file))
669+ ogg_file = self.factory.create_file(
670+ os.path.join(fs.DIR_TEST_DATA_AUDIO,
671+ test_data.get('ogg_file').file))
672+
673+ albums_dir, album_mp3_dir, album_ogg_dir = \
674+ self.prepare_music_albums(mp3_file, ogg_file)
675
676 # Copy the albums directory from the temporal dir in the ubuntu host
677 # machine to the dir which maps the music dir in the device
678- device_mtp_albums_path = self.get_device_mtp_path(MUSIC, albums_name)
679- self.remote_helper.copy_dir(albums_dir, device_mtp_albums_path)
680+ mtp_albums_path = self.mtp_helper.get_mtp_path(fs.DIR_MUSIC,
681+ albums_dir.name)
682+ albums_dir.remote_copy(mtp_albums_path)
683
684 # Verify the albums have ben copied to the music folder
685- copied_albums = self.verify_dir_copied(MUSIC_DIR, albums_name)
686+ albums_dir.local_dst_path = os.path.join(fs.DIR_HOME_MUSIC,
687+ albums_dir.name)
688+ self.assertTrue(os.path.isdir(albums_dir.local_dst_path))
689
690- copied_album_mp3 = os.path.join(copied_albums, album_mp3_name)
691- self.verify_songs(src_mp3_file, songs_album_mp3, copied_album_mp3,
692+ dst_path = os.path.join(albums_dir.local_dst_path, album_mp3_dir.name)
693+ self.verify_songs(mp3_file, songs_album_mp3, dst_path,
694 test_data.get('mp3_file').album)
695
696- copied_album_ogg = os.path.join(copied_albums, album_ogg_name)
697- self.verify_songs(src_ogg_file, songs_album_ogg, copied_album_ogg,
698+ dst_path = os.path.join(albums_dir.local_dst_path, album_ogg_dir.name)
699+ self.verify_songs(ogg_file, songs_album_ogg, dst_path,
700 test_data.get('ogg_file').album)
701
702 def test_copy_large_number_of_files(self):
703@@ -336,53 +178,43 @@
704 original.
705 """
706 amount = 100
707- src_file_name = test_data.get('text_file')
708- src_file = os.path.join(fs.DIR_TEST_DATA_TEXT, src_file_name)
709+ myfile = self.factory.create_file(
710+ os.path.join(fs.DIR_TEST_DATA_TEXT, test_data.get('text_file')))
711
712 # Create the dir to store the files in the host machine
713- (dir_name, dir_path) = self.create_remote_dir(TEMP_DIR)
714- self.addCleanup(self.remote_helper.remove_dir, dir_path)
715+ mydir = self.factory.create_remote_dir()
716
717 # Copy the src file to the ubuntu host machine
718- dst_tmp_file = self.copy_file_to_remote_host(src_file, TEMP_DIR)
719+ myfile.send_to_host(fs.DIR_TEMP)
720
721 # Replicate the src file 100 times
722- original_files = [src_file_name + "_" + str(i) for i in range(amount)]
723- self.replicate_file(dst_tmp_file, dir_path, original_files)
724+ original_files = [myfile.name + "_" + str(i) for i in range(amount)]
725+ self.mtp_helper.replicate_file(myfile, mydir, original_files)
726
727 # Copy the directory from the temporal dir in the ubuntu host
728 # machine to the dir which maps the documents dir in the device
729- device_mtp_dir_path = self.get_device_mtp_path(DOCS, dir_name)
730- logger.info("Copying remote files to mtp directory from {src_path} to "
731- "{mtp_path}".format(src_path=dir_path,
732- mtp_path=device_mtp_dir_path))
733- self.remote_helper.copy_dir(dir_path, device_mtp_dir_path)
734+ mydir.remote_copy(self.mtp_helper.get_mtp_path(fs.DIR_DOCUMENTS,
735+ mydir.name))
736
737 # Verify the files have ben copied correctly to the destiation
738- copied_dir = self.verify_dir_copied(DOCS_DIR, dir_name)
739- self.verify_copied_files(src_file, original_files, copied_dir)
740+ mydir.local_dst_path = os.path.join(fs.DIR_HOME_DOCUMENTS, mydir.name)
741+ self.assertTrue(os.path.isdir(mydir.local_dst_path))
742+ self.verify_copied_files(myfile, original_files, mydir.local_dst_path)
743
744 def _test_copy_big_file(self, kb=0, mb=0, gb=0):
745 # Create the remote file with random content and get the sha1 digest
746- file_name = fs.get_random_string() + ".tmp"
747- file_path = os.path.join(TEMP_DIR, file_name)
748-
749- self.remote_helper.create_random_file(file_path, kb=kb, mb=mb, gb=gb)
750- self.addCleanup(self.remote_helper.remove_file, file_path)
751- file_sha1 = self.remote_helper.get_sha1(file_path).strip()
752-
753+ file = self.factory.create_remote_file(ext='.tmp', kb=kb, mb=mb, gb=gb)
754 # Copy the directory from the temporal dir in the ubuntu host
755 # machine to the dir which maps the documents dir in the device
756- device_mtp_dst_path = self.get_device_mtp_path(DOCS, file_name)
757- logger.info("Copying remote files to mtp directory from {src_path} to "
758- "{mtp_path}".format(src_path=file_path,
759- mtp_path=device_mtp_dst_path))
760- self.remote_helper.copy_file(file_path, device_mtp_dst_path)
761+ file.remote_copy(self.mtp_helper.get_mtp_path(fs.DIR_DOCUMENTS,
762+ file.name))
763
764 # Verify the files have ben copied correctly to the destiation
765- copied_file = self.verify_file_copied(DOCS_DIR, file_name)
766- copied_sha1 = fs.calculate_file_sha1(copied_file)
767- self.assertEqual(file_sha1, copied_sha1)
768+ file.local_dst_path = os.path.join(fs.DIR_HOME_DOCUMENTS, file.name)
769+ self.assertTrue(os.path.isfile(file.local_dst_path))
770+
771+ copied_sha1 = fs.calculate_file_sha1(file.local_dst_path)
772+ self.assertEqual(file.sha1, copied_sha1)
773
774 def test_copy_big_1gb_file(self):
775 """ Copy a big file (almost 2GB) through mtp and check the file has
776@@ -415,21 +247,24 @@
777 """
778
779 # Create random source data and calculate the sha1 digest
780- song = self.create_random_file(MUSIC_DIR, ext='.mp3')
781- song.remote_src_path = self.get_device_mtp_path(MUSIC, song.name)
782-
783- video = self.create_random_file(VIDEOS_DIR, ext='.avi')
784- video.remote_src_path = self.get_device_mtp_path(VIDEOS, video.name)
785-
786- picture = self.create_random_file(PICTURES_DIR, ext='.jpg')
787- picture.remote_src_path = self.get_device_mtp_path(PICTURES,
788- picture.name)
789+ song = self.factory.create_random_file(fs.DIR_HOME_MUSIC, ext='.mp3')
790+ song.remote_src_path = \
791+ self.mtp_helper.get_mtp_path(fs.DIR_MUSIC, song.name)
792+
793+ video = self.factory.create_random_file(fs.DIR_HOME_VIDEOS, ext='.avi')
794+ video.remote_src_path = \
795+ self.mtp_helper.get_mtp_path(fs.DIR_VIDEOS, video.name)
796+
797+ picture = self.factory.create_random_file(fs.DIR_HOME_PICTURES,
798+ ext='.jpg')
799+ picture.remote_src_path = \
800+ self.mtp_helper.get_mtp_path(fs.DIR_PICTURES, picture.name)
801
802 files = [song, video, picture]
803
804 # Set destination path to files
805 for file in files:
806- file.remote_dst_path = os.path.join(TEMP_DIR, file.name)
807+ file.remote_dst_path = os.path.join(fs.DIR_TEMP, file.name)
808
809 # Copy the files from mtp to tmp directory and verify the sha1
810 for file in files:
811@@ -440,4 +275,4 @@
812 # Remove remote files and verify the files were deleted in the device
813 for file in files:
814 self.remote_helper.remove_file(file.remote_src_path)
815- self.assertFalse(os.path.isfile(file.local_path))
816+ self.assertFalse(os.path.isfile(file.local_src_path))

Subscribers

People subscribed via source and target branches

to all changes: