1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
"""
Application for testing syncing algorithm
(c) 2013-2014 by Mega Limited, Wellsford, New Zealand
This file is part of the MEGA SDK - Client Access Engine.
Applications using the MEGA API must present a valid application key
and comply with the the rules set forth in the Terms of Service.
The MEGA SDK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@copyright Simplified (2-clause) BSD License.
You should have received a copy of the license along with this
program.
"""
import os
import time
import random
from sync_test_base import get_random_str
import shutil
import logging
import datetime
class SyncTestApp(object):
"""
test application base class
"""
def __init__(self, local_mount_in, local_mount_out, work_folder, delete_tmp_files=True, use_large_files=True):
"""
work_dir: a temporary folder to place generated files
remote_folder: a remote folder to sync
"""
self.start_time = time.time()
random.seed(time.time())
self.local_mount_in = local_mount_in
self.local_mount_out = local_mount_out
self.rnd_folder = get_random_str()
self.local_folder_in = os.path.join(self.local_mount_in, self.rnd_folder)
self.local_folder_out = os.path.join(self.local_mount_out, self.rnd_folder)
self.work_folder = os.path.join(work_folder, self.rnd_folder)
self.nr_retries = 200
self.delete_tmp_files = delete_tmp_files
self.use_large_files = use_large_files
def change_folders(self):
"""
cleans directories and call finish
"""
time.sleep(0.2) # to prevent from sync algorithm interpreting we are renaming
if self.delete_tmp_files:
try:
shutil.rmtree(self.local_folder_in)
except OSError:
pass
time.sleep(1.2) # to prevent from sync algorithm interpreting we are renaming
self.rnd_folder = get_random_str()
self.local_folder_in = os.path.join(self.local_mount_in, self.rnd_folder)
self.local_folder_out = os.path.join(self.local_mount_out, self.rnd_folder)
self.work_folder = os.path.join(self.work_folder, self.rnd_folder)
self.prepare_folders();
def __enter__(self):
# call subclass function
res = self.start()
if not res:
self.stop()
raise Exception('Failed to start app!')
res = self.prepare_folders()
if not res:
self.stop()
raise Exception('Failed to start app!')
return self
def __exit__(self, exc_type, exc_value, traceback):
# remove tmp folders
if self.delete_tmp_files:
try:
logging.debug("Deleting %s" % self.local_folder_in)
shutil.rmtree(self.local_folder_in)
except OSError:
pass
try:
logging.debug("Deleting %s" % self.local_folder_out)
shutil.rmtree(self.local_folder_out)
except OSError:
pass
try:
logging.debug("Deleting %s" % self.work_folder)
shutil.rmtree(self.work_folder)
except OSError:
pass
# terminate apps
self.stop()
logging.info("Execution time: %s" % str(datetime.timedelta(seconds=time.time()-self.start_time)))
@staticmethod
def touch(path):
"""
create an empty file
update utime
"""
with open(path, 'a'):
os.utime(path, None)
def prepare_folders(self):
"""
prepare upsync, downsync and work directories
"""
# create "in" folder
logging.info("IN folder: %s" % self.local_folder_in)
try:
os.makedirs(self.local_folder_in)
except OSError, e:
logging.error("Failed to create directory: %s (%s)" % (self.local_folder_in, e))
return False
logging.info("OUT folder: %s" % self.local_folder_out)
self.sync()
# temporary workaround
#tmp_fix_file = os.path.join(self.local_mount_out, "tmp_fix")
success = False
# try to access the dir
for r in range(0, self.nr_retries):
self.attempt=r
try:
if os.path.isdir(self.local_folder_out):
success = True
break
else:
# wait for a dir
logging.debug("Directory %s not found! Retrying [%d/%d] .." % (self.local_folder_out, r + 1, self.nr_retries))
#self.touch(tmp_fix_file)
self.sync()
except OSError:
# wait for a dir
logging.debug("Directory %s not found! Retrying [%d/%d] .." % (self.local_folder_out, r + 1, self.nr_retries))
#self.touch(tmp_fix_file)
self.sync()
if success is False:
logging.error("Failed to access directory: %s" % self.local_folder_out)
return False
# create work folder
logging.debug("Work folder: %s" % self.work_folder)
try:
os.makedirs(self.work_folder)
except OSError, e:
logging.error("Failed to create directory: %s (%s)" % (self.work_folder, e))
return False
return True
def stop(self):
"""
cleans directories and call finish
"""
if self.delete_tmp_files:
try:
shutil.rmtree(self.local_folder_in)
except OSError:
pass
self.sync()
self.finish()
# virtual methods
def start(self):
"""
start application
"""
raise NotImplementedError("Not Implemented !")
def finish(self):
"""
stop application
"""
raise NotImplementedError("Not Implemented !")
def sync(self):
"""
wait for full synchronization
"""
raise NotImplementedError("Not Implemented !")
def pause(self):
"""
pause application
"""
raise NotImplementedError("Not Implemented !")
def unpause(self):
"""
unpause application
"""
raise NotImplementedError("Not Implemented !")
def is_alive(self):
"""
return True if application instance is running
"""
raise NotImplementedError("Not Implemented !")
|