def setUp(self): self.m = random.randint(1, 6) self.k = self.m - 1 self.storage_manager = StorageManager() self.fec = FileFec(self.k, self.m) self.mapping = MappingConfigParser(create_random_dir(), generate_random_file_path()) self.handler = DemerioConductor(self.mapping, self.fec, self.storage_manager)
def launch_daemon(self): self.ui.launch_btn.hide() self.hide() self.ui.account_tab.setEnabled(True) number_of_storages = self.storage_manager.get_number_of_storages() self.event_handler = DemerioConductor(Mapping(demerio_dir, config_file), FileFec(PARTS_NEEDED, number_of_storages), self.storage_manager, ignore_patterns = IGNORE_PATTERNS) self.event_handler.conductor_exception.connect(self.tray.conductor_problem) self.event_handler.event_started.connect(self.tray.event_started) self.event_handler.event_finished.connect(self.tray.event_finished) self.event_handler.reconstruct_started.connect(self.init_progress_bar) self.event_handler.reconstruct_finished.connect(self.end_progress_bar) self.event_handler.reconstruct_update.connect(self.update_progress_bar) observer = Observer() self.daemon = DemerioDaemon(self.event_handler, observer, demerio_dir, should_exit=False) self.daemon.start() self.open_demerio_folder()
class TestDemerioHandler(unittest.TestCase): """ This is an integration testCase, we use Mock as storage_manager and as split to only test mapping integration """ def _mock_encode_path_in_dir(self, input_path, temp_dir): return [generate_random_file_name_in_dir(temp_dir) for i in range(self.m)] def _mock_storage_new_file(self, file_parts): return [ (generate_random_string(), file_part) for file_part in file_parts ] def setUp(self): self.m = random.randint(1, 6) self.k = self.m - 1 self.storage_manager = StorageManager() self.fec = FileFec(self.k, self.m) self.mapping = MappingConfigParser(create_random_dir(), generate_random_file_path()) self.handler = DemerioConductor(self.mapping, self.fec, self.storage_manager) def tearDown(self): delete_file(self.mapping.config_file_path) delete_dir(self.mapping.base_dir) def test_on_created_file_without_error(self): # Given new_file = generate_random_file_name_in_dir(self.mapping.base_dir) created_event = FileCreatedEvent(new_file) self.fec.encode_path_in_dir = self._mock_encode_path_in_dir self.storage_manager.new_file = self._mock_storage_new_file # When self.handler.on_created(created_event) # Then self.assertTrue(self.mapping.has_file(new_file)) self.assertTrue(self.mapping.get_state(new_file) == STATE.ok) def test_on_created_file_with_split_error(self): # Given new_file = generate_random_file_name_in_dir(self.mapping.base_dir) created_event = FileCreatedEvent(new_file) self.fec.encode_path_in_dir = MagicMock(side_effect=DemerioSplitError('')) # When self.handler.on_created(created_event) # Then self.assertTrue(self.mapping.has_file(new_file)) self.assertTrue(self.mapping.get_state(new_file) == STATE.detected) def test_after_reconstruct_i_have_the_same_number_of_files(self): # Given number_of_files = random.randint(1, 100) for file_number in range(number_of_files): file_path = generate_random_file_name_in_dir(self.mapping.base_dir) self.mapping.add_file(file_path, self.k, self.m) self.mapping.update_to_splitted_state(file_path, [generate_random_string() for i in range(self.m)]) output_dir = create_random_dir() self.addCleanup(lambda: delete_dir(output_dir)) self.storage_manager.download_file_chunks = mock_download_file_chunks self.fec.decode_path = mock_decode_path # When self.handler.reconstruct_dir(output_dir) # Then actual_number_of_files = count_files_recursively_in_dir(output_dir) self.assertEqual(number_of_files, actual_number_of_files) def test_reconstruct_with_subdirectories(self): # Given number_of_dir = random.randint(1, 10) number_of_files_in_dir = [random.randint(1, 100) for i in range(number_of_dir)] expected_number_of_files = sum(number_of_files_in_dir) for dir_number in range(number_of_dir): number_of_files_to_create = number_of_files_in_dir[dir_number] random_dir = create_random_dir(self.mapping.base_dir) for file_number in range(number_of_files_to_create): file_path = generate_random_file_name_in_dir(random_dir) self.mapping.add_file(file_path, self.k, self.m) self.mapping.update_to_splitted_state(file_path, [generate_random_string() for i in range(self.m)]) output_dir = create_random_dir() self.addCleanup(lambda: delete_dir(output_dir)) self.storage_manager.download_file_chunks = mock_download_file_chunks self.fec.decode_path = mock_decode_path # When self.handler.reconstruct_dir(output_dir) # Then actual_number_of_files = count_files_recursively_in_dir(output_dir) self.assertEqual(expected_number_of_files, actual_number_of_files)
class TestDemerioHandler(unittest.TestCase): """ This is an integration testCase, we use Mock as storage_manager and as split to only test mapping integration """ def _mock_encode_path_in_dir(self, input_path, temp_dir): return [ generate_random_file_name_in_dir(temp_dir) for i in range(self.m) ] def _mock_storage_new_file(self, file_parts): return [(generate_random_string(), file_part) for file_part in file_parts] def setUp(self): self.m = random.randint(1, 6) self.k = self.m - 1 self.storage_manager = StorageManager() self.fec = FileFec(self.k, self.m) self.mapping = MappingConfigParser(create_random_dir(), generate_random_file_path()) self.handler = DemerioConductor(self.mapping, self.fec, self.storage_manager) def tearDown(self): delete_file(self.mapping.config_file_path) delete_dir(self.mapping.base_dir) def test_on_created_file_without_error(self): # Given new_file = generate_random_file_name_in_dir(self.mapping.base_dir) created_event = FileCreatedEvent(new_file) self.fec.encode_path_in_dir = self._mock_encode_path_in_dir self.storage_manager.new_file = self._mock_storage_new_file # When self.handler.on_created(created_event) # Then self.assertTrue(self.mapping.has_file(new_file)) self.assertTrue(self.mapping.get_state(new_file) == STATE.ok) def test_on_created_file_with_split_error(self): # Given new_file = generate_random_file_name_in_dir(self.mapping.base_dir) created_event = FileCreatedEvent(new_file) self.fec.encode_path_in_dir = MagicMock( side_effect=DemerioSplitError('')) # When self.handler.on_created(created_event) # Then self.assertTrue(self.mapping.has_file(new_file)) self.assertTrue(self.mapping.get_state(new_file) == STATE.detected) def test_after_reconstruct_i_have_the_same_number_of_files(self): # Given number_of_files = random.randint(1, 100) for file_number in range(number_of_files): file_path = generate_random_file_name_in_dir(self.mapping.base_dir) self.mapping.add_file(file_path, self.k, self.m) self.mapping.update_to_splitted_state( file_path, [generate_random_string() for i in range(self.m)]) output_dir = create_random_dir() self.addCleanup(lambda: delete_dir(output_dir)) self.storage_manager.download_file_chunks = mock_download_file_chunks self.fec.decode_path = mock_decode_path # When self.handler.reconstruct_dir(output_dir) # Then actual_number_of_files = count_files_recursively_in_dir(output_dir) self.assertEqual(number_of_files, actual_number_of_files) def test_reconstruct_with_subdirectories(self): # Given number_of_dir = random.randint(1, 10) number_of_files_in_dir = [ random.randint(1, 100) for i in range(number_of_dir) ] expected_number_of_files = sum(number_of_files_in_dir) for dir_number in range(number_of_dir): number_of_files_to_create = number_of_files_in_dir[dir_number] random_dir = create_random_dir(self.mapping.base_dir) for file_number in range(number_of_files_to_create): file_path = generate_random_file_name_in_dir(random_dir) self.mapping.add_file(file_path, self.k, self.m) self.mapping.update_to_splitted_state( file_path, [generate_random_string() for i in range(self.m)]) output_dir = create_random_dir() self.addCleanup(lambda: delete_dir(output_dir)) self.storage_manager.download_file_chunks = mock_download_file_chunks self.fec.decode_path = mock_decode_path # When self.handler.reconstruct_dir(output_dir) # Then actual_number_of_files = count_files_recursively_in_dir(output_dir) self.assertEqual(expected_number_of_files, actual_number_of_files)
class MainWindow(QDialog): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = uic.loadUi(ui_full_path('main_window.ui'), self) self.ui.label_version.setText("Demerio version %s" % (get_versions()['version'],)) self.ui.progress_bar.setVisible(False) self.ui.tabWidget.setCurrentIndex(0) self.ui.launch_btn.clicked.connect(self.launch_daemon) self.ui.output_btn.clicked.connect(self.validate) self.tray = SystemTray(self) self.tray.show() self.create_tray_actions() self.init_storage_manager() self.add_clouds_to_view() self.daemon = None self.check_if_already_connected() def create_tray_actions(self): self.tray.add_action("Open Demerio Folder", self.open_demerio_folder) self.tray.add_action("Preference", self.show) self.tray.add_separator() self.tray.add_action("Quit", self.quit_app) """ should be done in cloud widget class with a proper model and view """ def init_storage_manager(self): self.storage_manager = StorageManager() drive_api = GoogleDriveAPI(demerio_config_dir) self.storage_manager.add_storage("google_drive", drive_api) dropbox = DropboxAPI(demerio_config_dir) self.storage_manager.add_storage("dropbox", dropbox) box = BoxAPI(demerio_config_dir) self.storage_manager.add_storage("box", box) def add_clouds_to_view(self): self.ui.listWidget.setResizeMode(QListView.Adjust) for cloud_name in self.storage_manager.map_of_storage.keys(): cloud_widget = CloudWidget(cloud_name, self) cloud_widget.pushed.connect(self.authenticate) item = QListWidgetItem() item.setSizeHint(cloud_widget.sizeHint()) self.ui.listWidget.addItem(item) self.ui.listWidget.setItemWidget(item, cloud_widget) @pyqtSlot() def authenticate(self): cloud_storage = self.storage_manager.map_of_storage[self.sender().name] cloud_storage.authorize() if cloud_storage.is_connected(): self.sender().ui.cloudAction.setEnabled(False) self.update_launch_btn_state() @pyqtSlot() def open_demerio_folder(self): QDesktopServices.openUrl(QUrl.fromLocalFile(demerio_dir)) def update_launch_btn_state(self): for cloud in self.storage_manager.map_of_storage.values(): if not cloud.is_connected(): return False self.ui.launch_btn.setEnabled(True) self.ui.label.setText("") @pyqtSlot() def launch_daemon(self): self.ui.launch_btn.hide() self.hide() self.ui.account_tab.setEnabled(True) number_of_storages = self.storage_manager.get_number_of_storages() self.event_handler = DemerioConductor(Mapping(demerio_dir, config_file), FileFec(PARTS_NEEDED, number_of_storages), self.storage_manager, ignore_patterns = IGNORE_PATTERNS) self.event_handler.conductor_exception.connect(self.tray.conductor_problem) self.event_handler.event_started.connect(self.tray.event_started) self.event_handler.event_finished.connect(self.tray.event_finished) self.event_handler.reconstruct_started.connect(self.init_progress_bar) self.event_handler.reconstruct_finished.connect(self.end_progress_bar) self.event_handler.reconstruct_update.connect(self.update_progress_bar) observer = Observer() self.daemon = DemerioDaemon(self.event_handler, observer, demerio_dir, should_exit=False) self.daemon.start() self.open_demerio_folder() @pyqtSlot(int) def init_progress_bar(self, number_of_files): self.ui.progress_bar.setVisible(True) self.ui.progress_bar.setMaximum(number_of_files) self.ui.progress_bar.setTextVisible(True) @pyqtSlot(int) def update_progress_bar(self, value): self.ui.progress_bar.setValue(value) @pyqtSlot() def end_progress_bar(self): self.ui.progress_bar.setVisible(False) self.ui.start_label.setText("") @pyqtSlot() def validate(self): self.dir_selected = QFileDialog.getExistingDirectory(self, "Select Directory") self.ui.start_label.setText("Your datas will be reconstructed in : %s directory" %(self.dir_selected,)) self.event_handler.reconstruct_dir(self.dir_selected) @pyqtSlot() def quit_app(self): if self.daemon is not None: self.daemon.should_exit = True self.daemon.join() QCoreApplication.instance().quit() def check_if_already_connected(self): QApplication.processEvents() for index in range(self.ui.listWidget.count()): QApplication.processEvents() cloud_widget = self.ui.listWidget.itemWidget(self.ui.listWidget.item(index)) if self.storage_manager.map_of_storage[cloud_widget.name].is_connected(): cloud_widget.ui.cloudAction.setEnabled(False) self.update_launch_btn_state() if self.ui.launch_btn.isEnabled(): self.launch_daemon() else: self.show()