Comparar commits

..

53 Commits

Autor SHA1 Mensagem Data
Jenkins for ownCloud 88da5f6592 [tx-robot] updated from transifex 2017-02-16 02:18:36 +01:00
Olivier Goffart e8c10501a5 Folder: Keep files option after aboutToRemoveAllFiles should not clear selective sync list (#5531)
We were removing the wholme journal db when the user wanted to keep all files,
But that would also remove the selective sync lists.
We should only remove the metadata table.

Issue #5484
2017-02-15 13:27:41 +01:00
Roeland Jago Douma 99aaf22ae5 Update windows docker file to use 2.3 OBS repo
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
2017-02-15 09:49:29 +01:00
Jenkins for ownCloud 3943016f3b [tx-robot] updated from transifex 2017-02-15 02:18:29 +01:00
Olivier Goffart 172689d35c Merge remote-tracking branch 'origin/2.3' 2017-02-14 15:08:10 +01:00
Jocelyn Turcotte 60a4a742a3 Disable tests uncompatible with Qt4 for that build 2017-02-14 14:32:41 +01:00
Jocelyn Turcotte b26db062d2 Fix the UNIT_TESTING build on Windows
- Put all tests in the bin directory so that DLLs can be loaded
- Add missing exports
- Skip tests that use code depending on zlib
- The "GMT" timezone is named differently, use the int constructor instead

5 tests are still failing, it's not really worth fixing at the moment
since no developper is currently using Windows as its main platform.
2017-02-14 14:32:41 +01:00
Jocelyn Turcotte 611f633ba8 Fix FolderManTest on macOS
On macOS /var is a symlink to /private/var and we have to make sure that we
use the canonical path before and after it enters the code to make sure we
compare paths correctly.
2017-02-14 14:32:41 +01:00
Jocelyn Turcotte 3265948458 Fix ExcludedFilesTest on macOS
Use the same logic to find sync-exclude as check_csync_exclude.c
2017-02-14 14:32:41 +01:00
Jocelyn Turcotte 0e3e9d5991 Fix FileSystemTest on macOS 2017-02-14 14:32:41 +01:00
Jocelyn Turcotte 0be6cd3bf7 Fix FolderWatcherTest on macOS and Windows
- We need to use a QGuiApplication on macOS or else we don't get notifications
- Switch to use QSignalSpy rather than lists and sleeps
- Use system() for all modifications since we pass kFSEventStreamCreateFlagIgnoreSelf
- Keep using the local process on Windows since it catches its own events
2017-02-14 14:32:41 +01:00
Jocelyn Turcotte 867b78052d Fix UtilityTest on macOS 2017-02-14 14:32:41 +01:00
Olivier Goffart 058f7df635 Folder: remove unused variable 2017-02-14 10:10:07 +01:00
Jenkins for ownCloud c1552d7984 [tx-robot] updated from transifex 2017-02-14 02:18:27 +01:00
Markus Goetz 575b981542 Modify Jenkinsfile for 2.3 2017-02-13 14:47:51 +01:00
Jenkins for ownCloud 0d0af95956 [tx-robot] updated from transifex 2017-02-13 02:18:28 +01:00
Jenkins for ownCloud 6c5d873647 [tx-robot] updated from transifex 2017-02-12 02:18:28 +01:00
Jenkins for ownCloud 71187e1744 [tx-robot] updated from transifex 2017-02-11 02:18:34 +01:00
Christian Kamm 006ce854a6 Doc: For conflicts, the local file is renamed #5521 2017-02-10 12:50:35 +01:00
Jenkins for ownCloud 697178bab6 [tx-robot] updated from transifex 2017-02-10 02:18:29 +01:00
Jenkins for ownCloud d8a86da377 [tx-robot] updated from transifex 2017-02-09 02:18:33 +01:00
Jocelyn Turcotte d1dace9e7f Remove unneeded Q_DECLARE_METATYPE 2017-02-08 17:57:20 +01:00
Jocelyn Turcotte 1cec2ca13d Fix TestSyncEngine::abortAfterFailedMkdir
It could be possible that _firstJob is marked as finished if
aborted before its parent PropagateDirectory was marked as finished,
allowing a posted scheduleNextJob call to schedule the child job
in-between.
2017-02-08 17:32:04 +01:00
Jocelyn Turcotte 1d9e08d109 Skip TestSyncEngine::abortAfterFailedMkdir 2017-02-08 17:25:32 +01:00
ckamm 7879c470b3 Merge pull request #5518 from ckamm/asserts
Improve usage of asserts
2017-02-08 15:25:02 +01:00
Christian Kamm 3c7545a45f CMake: Don't force-enable asserts #5429
Should be safer now that we've gone through asserts and assured that
one ones that should be fatal continue to exist in release builds
independently of QT_NO_DEBUG.
2017-02-08 15:15:19 +01:00
Christian Kamm 4c1fdf1dee Double check usage of asserts #5429
A few are supposed to be fatal.
2017-02-08 15:15:19 +01:00
Christian Kamm 18e25122db Performance: reserve() _remotePerm #5496 2017-02-08 15:06:09 +01:00
Olivier Goffart 439e688906 Folder: Change the wording for the massive deletion message
Issue #5503
2017-02-08 14:30:14 +01:00
ckamm 4198d9f420 Settings: Don't migrate settings on access error #5499 (#5523)
Previously, we'd try migrating from legacy settings if reading
the settings failed with an error. Now, we try again after a
couple of seconds and eventually give up.
2017-02-08 14:28:50 +01:00
Olivier Goffart 06579a5c70 AccountManager: Fix small leak in the account migration code
The QSettings object was not deleted in every possible code paths
2017-02-08 12:31:07 +01:00
Markus Goetz df773ea8bb CentOS: More build fixes 2017-02-08 11:39:28 +01:00
Markus Goetz e7be4faac8 CentOS: Another attempt 2017-02-08 11:15:23 +01:00
Jenkins for ownCloud a184c6bec1 [tx-robot] updated from transifex 2017-02-08 02:18:27 +01:00
Markus Goetz 1102ac20ac Improve previous fix
After comment on https://github.com/owncloud/client/commit/78a798eef3eb8d04360c6d9542db55469f59cacd
2017-02-07 19:40:32 +01:00
Markus Goetz 6a4ae63f14 CentOS: Another fix for old compiler version (2) 2017-02-07 19:22:04 +01:00
Markus Goetz 6c6961e4d9 ChangeLog for 2.3 additions 2017-02-07 19:04:00 +01:00
Markus Goetz 78a798eef3 Old Qt: Another build fix 2017-02-07 18:54:40 +01:00
Markus Goetz 19dd656989 CentOS: Another fix for old compiler version 2017-02-07 18:32:34 +01:00
Markus Goetz d9fac50e9b CentOS: Fix build for old compiler version 2017-02-07 18:05:29 +01:00
Markus Goetz 9614a94035 Revert "Disable RTTI"
This reverts commit 85d3de1589.
This breaks our old Qt on CentOS.

We can re-introduce this with #5470
2017-02-07 17:35:04 +01:00
Jenkins for ownCloud 5002964546 [tx-robot] updated from transifex 2017-02-07 02:18:27 +01:00
Jenkins for ownCloud 4cca1ba55f [tx-robot] updated from transifex 2017-02-06 02:18:27 +01:00
Jenkins for ownCloud 3e99c32582 [tx-robot] updated from transifex 2017-02-05 02:18:27 +01:00
Jenkins for ownCloud 74ce597f8d [tx-robot] updated from transifex 2017-02-04 02:18:27 +01:00
Jenkins for ownCloud a27b2d94b3 [tx-robot] updated from transifex 2017-02-03 02:18:27 +01:00
Jenkins for ownCloud 890e771ec1 [tx-robot] updated from transifex 2017-02-02 02:18:27 +01:00
Jenkins for ownCloud 5df10cb8f8 [tx-robot] updated from transifex 2017-02-01 02:18:28 +01:00
Jenkins for ownCloud 9acc974268 [tx-robot] updated from transifex 2017-01-31 02:18:26 +01:00
Jenkins for ownCloud 42e64026ae [tx-robot] updated from transifex 2017-01-30 02:18:28 +01:00
Jenkins for ownCloud 78e7d13f9f [tx-robot] updated from transifex 2017-01-29 02:18:27 +01:00
Jenkins for ownCloud 2d55332a45 [tx-robot] updated from transifex 2017-01-28 02:18:34 +01:00
Jenkins for ownCloud 72cd9abd4a [tx-robot] updated from transifex 2017-01-28 01:15:15 +01:00
89 arquivos alterados com 9108 adições e 6696 exclusões
+2 -3
Ver Arquivo
@@ -7,6 +7,8 @@ endif()
project(client)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(OEM_THEME_DIR "" CACHE STRING "Define directory containing a custom theme")
if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
include ( ${OEM_THEME_DIR}/OEM.cmake )
@@ -58,9 +60,6 @@ if( UNIX AND NOT APPLE )
endif()
####
# Enable Q_ASSERT etc. in all builds
add_definitions( -DQT_FORCE_ASSERTS )
include(GNUInstallDirs)
include(DefineInstallationPaths)
include(GenerateExportHeader)
+5 -4
Ver Arquivo
@@ -1,10 +1,11 @@
ChangeLog
=========
version 2.3.0 (2017-0x-xx)
* WiP!
* WiP Switch Windows and OS X build to 5.6.2
* WiP Performance improvements for exclude detection
version 2.3.0 (2017-02-xx)
* Decreased memory usage during sync
* Overlay icons: Lower CPU usage
* Allow to not sync the server's external storages by default
* Switch Windows and OS X build to 5.6.2
* Switch to new ownCloud server WebDAV endpoint
* Chunking NG: New file upload chunking algorithmn for ownCloud server 9.2
* Allow to sync a folder to multiple different servers (Filename change from .csync_journal.db to _sync_$HASH.db)
+1 -1
Ver Arquivo
@@ -39,7 +39,7 @@ node('CLIENT') {
stage 'Win32'
def win32 = docker.image('deepdiver/docker-owncloud-client-win32:latest')
def win32 = docker.image('guruz/docker-owncloud-client-win32:latest')
win32.pull() // make sure we have the latest available from Docker Hub
win32.inside {
sh '''
+1 -1
Ver Arquivo
@@ -9,7 +9,7 @@ ENV REFRESHED_AT 20160421
RUN zypper --non-interactive --gpg-auto-import-keys refresh
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_42.1/windows:mingw.repo
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/isv:ownCloud:toolchains:mingw:win32:2.2/openSUSE_Leap_42.1/isv:ownCloud:toolchains:mingw:win32:2.2.repo
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/isv:ownCloud:toolchains:mingw:win32:2.3/openSUSE_Leap_42.1/isv:ownCloud:toolchains:mingw:win32:2.3.repo
RUN zypper --non-interactive --gpg-auto-import-keys install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \
mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \
mingw32-headers mingw32-runtime site-config mingw32-libwebp \
+1 -1
Ver Arquivo
@@ -3,7 +3,7 @@ StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Показати примітки
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Знайдено процес(и) ${APPLICATION_EXECUTABLE}, які необхідно зупинити.$\nХочете щоб програма установки зробила це самостійно?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Завершення процесів ${APPLICATION_EXECUTABLE}."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Не знайдено процеси, які необхідно зупинити!"
StrCpy $PageReinstall_NEW_Field_1 "Знайдено застарілу версію програми ${APPLICATION_NAME}. Рекомендуємо її спочатку видалити. Оберіть подальшу дію та натисніть $\"Далі$\"."
StrCpy $PageReinstall_NEW_Field_1 "У вашої системі встановлена застаріла версія додатку ${APPLICATION_NAME}. Рекомендуємо видалити її перед початком встановлення поточної версії. Оберіть подальшу дію та натисніть $\"Далі$\"."
StrCpy $PageReinstall_NEW_Field_2 "Видалити перед установкою"
StrCpy $PageReinstall_NEW_Field_3 "Не видаляти"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Установлено"
-1
Ver Arquivo
@@ -28,7 +28,6 @@ include(ConfigureChecks.cmake)
set(SOURCE_DIR ${CMAKE_SOURCE_DIR})
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
include_directories(${CMAKE_CURRENT_BINARY_DIR})
+1 -1
Ver Arquivo
@@ -207,7 +207,7 @@ __attribute__ ((packed))
#endif
;
void csync_file_stat_free(csync_file_stat_t *st);
OCSYNC_EXPORT void csync_file_stat_free(csync_file_stat_t *st);
/*
* context for the treewalk function
+5 -7
Ver Arquivo
@@ -56,17 +56,15 @@ int csync_get_statedb_exists(CSYNC *ctx);
*
* @return 0 on success, less than 0 if an error occurred with errno set.
*/
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
OCSYNC_EXPORT int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
int csync_statedb_close(CSYNC *ctx);
OCSYNC_EXPORT int csync_statedb_close(CSYNC *ctx);
csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
char *csync_statedb_get_etag(CSYNC *ctx, uint64_t jHash);
OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
/**
* @brief Query all files metadata inside and below a path.
+10 -5
Ver Arquivo
@@ -132,11 +132,16 @@ changed and no synchronization occurs.
In the event a file has changed on both the local and the remote repository
since the last sync run, it can not easily be decided which version of the file
is the one that should be used. However, changes to any side will not be lost. Instead,
a *conflict case* is created. The client resolves this conflict by creating a
conflict file of the older of the two files and saving the newer file under the
original file name. Conflict files are always created on the client and never
on the server. The conflict file uses the same name as the original file, but
is appended with the timestamp of the conflict detection.
a *conflict case* is created. The client resolves this conflict by renaming the
local file, appending a conflict label and timestamp, and saving the remote file
under the original file name.
Example: Assume there is a conflict in message.txt because its contents have
changed both locally and remotely since the last sync run. The local file with
the local changes will be renamed to message_conflict-20160101-153110.txt and
the remote file will be downloaded and saved as message.txt.
Conflict files are always created on the client and never on the server.
.. _ignored-files-label:
+77 -8
Ver Arquivo
@@ -661,6 +661,66 @@ X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
GenericName[oc]=Dorsièr de Sincronizacion
@@ -686,7 +746,9 @@ Comment[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
GenericName[ja_JP]=フォルダー同期
Name[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
Icon[ja_JP]=@APPLICATION_EXECUTABLE@
Comment[el]=@ΟΝΟΜΑ_ΕΦΑΡΜΟΓΗΣ@ συγχρονισμός επιφάνειας εργασίας πελάτη
GenericName[el]=Συγχρονισμός φακέλου
Name[el]=@ΟΝΟΜΑ_ΕΦΑΡΜΟΓΗΣ@ συγχρονισμός επιφάνειας εργασίας πελάτη
Icon[el]=@APPLICATION_EXECUTABLE@
Comment[en_GB]=@APPLICATION_NAME@ desktop synchronisation client
GenericName[en_GB]=Folder Sync
@@ -700,10 +762,13 @@ Comment[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
GenericName[de_DE]=Ordner-Synchronisation
Name[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
Icon[de_DE]=@APPLICATION_EXECUTABLE@
Comment[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
GenericName[pl]=Folder Synchronizacji
Name[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
Icon[pl]=@APPLICATION_EXECUTABLE@
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
GenericName[fa]=همسان سازی پوشه‌ها
Name[fa]=@APPLICATION_EXECUTABLE@ نسخه‌ی همسان سازی مشتری
Icon[fa]=@APPLICATION_EXECUTABLE@
Comment[fr]=@APPLICATION_NAME@ synchronisation du client
GenericName[fr]=Dossier de Synchronisation
Name[fr]=@APPLICATION_NAME@ synchronisation du client
@@ -712,6 +777,10 @@ Comment[he]=@APPLICATION_NAME@ לקוח סנכון שולחן עבודה
GenericName[he]=סנכון תיקייה
Name[he]=@APPLICATION_NAME@ לקוח סנכרון שולחן עבודה
Icon[he]=@APPLICATION_EXECUTABLE@
Comment[ia]=@APPLICATION_NAME@ cliente de synchronisation pro scriptorio
GenericName[ia]=Synchronisar Dossier
Name[ia]=@APPLICATION_NAME@ cliente de synchronisation pro scriptorio
Icon[ia]=@APPLICATION_EXECUTABLE@
Comment[id]=Klien sinkronisasi desktop @APPLICATION_NAME@
GenericName[id]=Folder Sync
Name[id]=Klien sync desktop @APPLICATION_NAME@
@@ -739,10 +808,10 @@ Comment[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
GenericName[et_EE]=Kaustade sünkroonimine
Name[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
Icon[et_EE]=@APPLICATION_EXECUTABLE@
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
Comment[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
GenericName[pl]=Folder Synchronizacji
Name[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
Icon[pl]=@APPLICATION_EXECUTABLE@
Comment[pt_BR]=@APPLICATION_NAME@ cliente de sincronização do computador
GenericName[pt_BR]=Sincronização de Pasta
Name[pt_BR]=@APPLICATION_NAME@ cliente de sincronização de desktop
-1
Ver Arquivo
@@ -1,7 +1,6 @@
# TODO: OSX and LIB_ONLY seem to require this to go to binary dir only
if(NOT TOKEN_AUTH_ONLY)
endif()
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(synclib_NAME ${APPLICATION_EXECUTABLE}sync)
-2
Ver Arquivo
@@ -1,8 +1,6 @@
project(cmd)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
set(cmd_NAME ${APPLICATION_EXECUTABLE}cmd)
set(cmd_SRC
cmd.cpp
-2
Ver Arquivo
@@ -3,8 +3,6 @@ set(CMAKE_AUTOMOC TRUE)
add_subdirectory(updater)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
#TODO Move resources files
qt_add_resources(MIRALL_RC_SRC ../../client.qrc)
if ( IS_DIRECTORY ${OEM_THEME_DIR} )
+12 -5
Ver Arquivo
@@ -46,11 +46,17 @@ AccountManager *AccountManager::instance()
bool AccountManager::restore()
{
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
if (settings->status() != QSettings::NoError) {
qDebug() << "Could not read settings from" << settings->fileName()
<< settings->status();
return false;
}
// If there are no accounts, check the old format.
if (settings->childGroups().isEmpty()
&& !settings->contains(QLatin1String(versionC))) {
return restoreFromLegacySettings();
restoreFromLegacySettings();
return true;
}
foreach (const auto& accountId, settings->childGroups()) {
@@ -69,6 +75,9 @@ bool AccountManager::restore()
bool AccountManager::restoreFromLegacySettings()
{
qDebug() << "Migrate: restoreFromLegacySettings, checking settings group"
<< Theme::instance()->appName();
// try to open the correctly themed settings
auto settings = Utility::settingsWithGroup(Theme::instance()->appName());
@@ -86,7 +95,7 @@ bool AccountManager::restoreFromLegacySettings()
QFileInfo fi( oCCfgFile );
if( fi.isReadable() ) {
QSettings *oCSettings = new QSettings(oCCfgFile, QSettings::IniFormat);
std::unique_ptr<QSettings> oCSettings(new QSettings(oCCfgFile, QSettings::IniFormat));
oCSettings->beginGroup(QLatin1String("ownCloud"));
// Check the theme url to see if it is the same url that the oC config was for
@@ -101,9 +110,7 @@ bool AccountManager::restoreFromLegacySettings()
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
<< (oCUrl == overrideUrl ? "Yes" : "No");
if( oCUrl == overrideUrl ) {
settings.reset( oCSettings );
} else {
delete oCSettings;
settings = std::move(oCSettings);
}
}
}
+3 -1
Ver Arquivo
@@ -36,7 +36,9 @@ public:
/**
* Creates account objects from a given settings file.
* return true if the account was restored
*
* Returns false if there was an error reading the settings,
* but note that settings not existing is not an error.
*/
bool restore();
+17 -1
Ver Arquivo
@@ -156,7 +156,23 @@ Application::Application(int &argc, char **argv) :
connect(this, SIGNAL(messageReceived(QString, QObject*)), SLOT(slotParseMessage(QString, QObject*)));
AccountManager::instance()->restore();
if (!AccountManager::instance()->restore()) {
// If there is an error reading the account settings, try again
// after a couple of seconds, if that fails, give up.
// (non-existence is not an error)
Utility::sleep(5);
if (!AccountManager::instance()->restore()) {
qDebug() << "Could not read the account settings, quitting";
QMessageBox::critical(
0,
tr("Error accessing the configuration file"),
tr("There was an error while accessing the configuration "
"file at %1.").arg(ConfigFile().configFile()),
tr("Quit ownCloud"));
QTimer::singleShot(0, qApp, SLOT(quit()));
return;
}
}
FolderMan::instance()->setSyncEnabled(true);
+1 -2
Ver Arquivo
@@ -53,7 +53,6 @@ Folder::Folder(const FolderDefinition& definition,
, _accountState(accountState)
, _definition(definition)
, _csyncUnavail(false)
, _wipeDb(false)
, _proxyDirty(true)
, _lastSyncDuration(0)
, _consecutiveFailingSyncs(0)
@@ -909,7 +908,7 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, bool *cancel
}
*cancel = msgBox.clickedButton() == keepBtn;
if (*cancel) {
wipe();
journalDb()->clearFileTable();
_lastEtag.clear();
slotScheduleThisFolder();
}
-1
Ver Arquivo
@@ -324,7 +324,6 @@ private:
SyncResult _syncResult;
QScopedPointer<SyncEngine> _engine;
bool _csyncUnavail;
bool _wipeDb;
bool _proxyDirty;
QPointer<RequestEtagJob> _requestEtagJob;
QString _lastEtag;
+5 -3
Ver Arquivo
@@ -23,6 +23,7 @@
#include "accountmanager.h"
#include "filesystem.h"
#include "lockwatcher.h"
#include "asserts.h"
#include <syncengine.h>
#ifdef Q_OS_MAC
@@ -48,7 +49,7 @@ FolderMan::FolderMan(QObject *parent) :
_lockWatcher(new LockWatcher),
_appRestartRequired(false)
{
Q_ASSERT(!_instance);
ASSERT(!_instance);
_instance = this;
_socketApi.reset(new SocketApi);
@@ -133,12 +134,13 @@ int FolderMan::unloadAndDeleteAllFolders()
delete f;
cnt++;
}
ASSERT(_folderMap.isEmpty());
_lastSyncFolder = 0;
_currentSyncFolder = 0;
_scheduledFolders.clear();
emit scheduleQueueChanged();
Q_ASSERT(_folderMap.count() == 0);
return cnt;
}
@@ -462,7 +464,7 @@ void FolderMan::slotFolderSyncPaused( Folder *f, bool paused )
void FolderMan::slotFolderCanSyncChanged()
{
Folder *f = qobject_cast<Folder*>(sender());
Q_ASSERT(f);
ASSERT(f);
if (f->canSync()) {
_socketApi->slotRegisterPath(f->alias());
} else {
+8 -7
Ver Arquivo
@@ -16,6 +16,7 @@
#include "folderman.h"
#include "accountstate.h"
#include "utility.h"
#include "asserts.h"
#include <theme.h>
#include <account.h>
#include "folderstatusdelegate.h"
@@ -480,14 +481,14 @@ QModelIndex FolderStatusModel::parent(const QModelIndex& child) const
}
auto pathIdx = static_cast<SubFolderInfo*>(child.internalPointer())->_pathIdx;
int i = 1;
Q_ASSERT(pathIdx.at(0) < _folders.count());
ASSERT(pathIdx.at(0) < _folders.count());
if (pathIdx.count() == 1) {
return createIndex(pathIdx.at(0), 0/*, nullptr*/);
}
const SubFolderInfo *info = &_folders[pathIdx.at(0)];
while (i < pathIdx.count() - 1) {
Q_ASSERT(pathIdx.at(i) < info->_subs.count());
ASSERT(pathIdx.at(i) < info->_subs.count());
info = &info->_subs[pathIdx.at(i)];
++i;
}
@@ -576,7 +577,7 @@ void FolderStatusModel::slotGatherPermissions(const QString &href, const QMap<QS
auto job = sender();
auto permissionMap = job->property(propertyPermissionMap).toMap();
job->setProperty(propertyPermissionMap, QVariant()); // avoid a detach of the map while it is modified
Q_ASSERT(!href.endsWith(QLatin1Char('/'))); // LsColXMLParser::parse removes the trailing slash before calling us.
ASSERT(!href.endsWith(QLatin1Char('/')), "LsColXMLParser::parse should remove the trailing slash before calling us.");
permissionMap[href] = *it;
job->setProperty(propertyPermissionMap, permissionMap);
}
@@ -584,7 +585,7 @@ void FolderStatusModel::slotGatherPermissions(const QString &href, const QMap<QS
void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
{
auto job = qobject_cast<LsColJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
QModelIndex idx = qvariant_cast<QPersistentModelIndex>(job->property(propertyParentIndexC));
auto parentInfo = infoForIndex(idx);
if (!parentInfo) {
@@ -715,7 +716,7 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
{
auto job = qobject_cast<LsColJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
QModelIndex idx = qvariant_cast<QPersistentModelIndex>(job->property(propertyParentIndexC));
if (!idx.isValid()) {
return;
@@ -730,7 +731,7 @@ void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
if (r->error() == QNetworkReply::ContentNotFoundError) {
parentInfo->_fetched = true;
} else {
Q_ASSERT(!parentInfo->hasLabel());
ASSERT(!parentInfo->hasLabel());
beginInsertRows(idx, 0, 0);
parentInfo->_hasError = true;
endInsertRows();
@@ -1135,7 +1136,7 @@ void FolderStatusModel::slotSyncNoPendingBigFolders()
void FolderStatusModel::slotNewBigFolder()
{
auto f = qobject_cast<Folder *>(sender());
Q_ASSERT(f);
ASSERT(f);
int folderIndex = -1;
for (int i = 0; i < _folders.count(); ++i) {
+7 -1
Ver Arquivo
@@ -38,7 +38,8 @@ namespace OCC {
GeneralSettings::GeneralSettings(QWidget *parent) :
QWidget(parent),
_ui(new Ui::GeneralSettings)
_ui(new Ui::GeneralSettings),
_currentlyLoading(false)
{
_ui->setupUi(this);
@@ -104,7 +105,12 @@ QSize GeneralSettings::sizeHint() const {
void GeneralSettings::loadMiscSettings()
{
#if QT_VERSION < QT_VERSION_CHECK( 5, 4, 0 )
QScopedValueRollback<bool> scope(_currentlyLoading);
_currentlyLoading = true;
#else
QScopedValueRollback<bool> scope(_currentlyLoading, true);
#endif
ConfigFile cfgFile;
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
_ui->desktopNotificationsCheckBox->setChecked(cfgFile.optionalDesktopNotifications());
+1 -1
Ver Arquivo
@@ -52,7 +52,7 @@ private:
Ui::GeneralSettings *_ui;
QPointer<IgnoreListEditor> _ignoreEditor;
QPointer<SyncLogDialog> _syncLogDialog;
bool _currentlyLoading = false;
bool _currentlyLoading;
};
+2 -1
Ver Arquivo
@@ -15,6 +15,7 @@
#include "notificationwidget.h"
#include "QProgressIndicator.h"
#include "utility.h"
#include "asserts.h"
#include <QPushButton>
@@ -33,8 +34,8 @@ void NotificationWidget::setActivity(const Activity& activity)
{
_myActivity = activity;
Q_ASSERT( !activity._accName.isEmpty() );
_accountName = activity._accName;
ASSERT(!_accountName.isEmpty());
// _ui._headerLabel->setText( );
_ui._subjectLabel->setVisible( !activity._subject.isEmpty() );
+1 -1
Ver Arquivo
@@ -229,7 +229,7 @@ void ShareLinkWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shar
Q_FOREACH(auto share, shares) {
if (share->getShareType() == Share::TypeLink) {
_share = qSharedPointerObjectCast<LinkShare>(share);
_share = qSharedPointerDynamicCast<LinkShare>(share);
_ui->pushButton_copy->show();
_ui->pushButton_mail->show();
+5 -7
Ver Arquivo
@@ -31,6 +31,7 @@
#include "accountstate.h"
#include "account.h"
#include "capabilities.h"
#include "asserts.h"
#include <QBitArray>
#include <QDebug>
@@ -60,9 +61,6 @@
#define DEBUG qDebug() << "SocketApi: "
Q_DECLARE_METATYPE(OCC::SocketListener)
static inline QString removeTrailingSlash(QString path)
{
Q_ASSERT(path.endsWith(QLatin1Char('/')));
@@ -113,7 +111,7 @@ class SocketListener {
public:
QIODevice* socket;
SocketListener(QIODevice* socket = nullptr) : socket(socket) { }
SocketListener(QIODevice* socket = 0) : socket(socket) { }
void sendMessage(const QString& message, bool doWait = false) const
{
@@ -216,7 +214,7 @@ SocketApi::~SocketApi()
DEBUG << "dtor";
_localServer.close();
// All remaining sockets will be destroyed with _localServer, their parent
Q_ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer);
ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer);
_listeners.clear();
}
@@ -231,7 +229,7 @@ void SocketApi::slotNewConnection()
connect(socket, SIGNAL(readyRead()), this, SLOT(slotReadSocket()));
connect(socket, SIGNAL(disconnected()), this, SLOT(onLostConnection()));
connect(socket, SIGNAL(destroyed(QObject*)), this, SLOT(slotSocketDestroyed(QObject*)));
Q_ASSERT(socket->readAll().isEmpty());
ASSERT(socket->readAll().isEmpty());
_listeners.append(SocketListener(socket));
SocketListener &listener = _listeners.last();
@@ -259,7 +257,7 @@ void SocketApi::slotSocketDestroyed(QObject* obj)
void SocketApi::slotReadSocket()
{
QIODevice* socket = qobject_cast<QIODevice*>(sender());
Q_ASSERT(socket);
ASSERT(socket);
SocketListener *listener = &*std::find_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket));
while(socket->canReadLine()) {
-2
Ver Arquivo
@@ -1,8 +1,6 @@
project(libsync)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
configure_file( version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h" )
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+4 -2
Ver Arquivo
@@ -20,6 +20,7 @@
#include "creds/abstractcredentials.h"
#include "capabilities.h"
#include "theme.h"
#include "asserts.h"
#include <QSettings>
#include <QMutex>
@@ -153,8 +154,9 @@ QUrl Account::davUrl() const
*/
void Account::clearCookieJar()
{
Q_ASSERT(qobject_cast<CookieJar*>(_am->cookieJar()));
static_cast<CookieJar*>(_am->cookieJar())->setAllCookies(QList<QNetworkCookie>());
auto jar = qobject_cast<CookieJar*>(_am->cookieJar());
ASSERT(jar);
jar->setAllCookies(QList<QNetworkCookie>());
emit wantsAccountSaved(this);
}
+52
Ver Arquivo
@@ -0,0 +1,52 @@
#ifndef OWNCLOUD_ASSERTS_H
#define OWNCLOUD_ASSERTS_H
#include <qglobal.h>
#if defined(QT_FORCE_ASSERTS) || !defined(QT_NO_DEBUG)
#define OC_ASSERT_MSG qFatal
#else
#define OC_ASSERT_MSG qWarning
#endif
// For overloading macros by argument count
// See stackoverflow.com/questions/16683146/can-macros-be-overloaded-by-number-of-arguments
#define OC_ASSERT_CAT(A, B) A ## B
#define OC_ASSERT_SELECT(NAME, NUM) OC_ASSERT_CAT(NAME ## _, NUM)
#define OC_ASSERT_GET_COUNT(_1, _2, _3, COUNT, ...) COUNT
#define OC_ASSERT_VA_SIZE(...) OC_ASSERT_GET_COUNT(__VA_ARGS__, 3, 2, 1, 0)
#define OC_ASSERT_OVERLOAD(NAME, ...) OC_ASSERT_SELECT(NAME, OC_ASSERT_VA_SIZE(__VA_ARGS__))(__VA_ARGS__)
// Default assert: If the condition is false in debug builds, terminate.
//
// Prints a message on failure, even in release builds.
#define ASSERT(...) OC_ASSERT_OVERLOAD(ASSERT, __VA_ARGS__)
#define ASSERT_1(cond) \
if (!(cond)) { \
OC_ASSERT_MSG("ASSERT: \"%s\" in file %s, line %d", #cond, __FILE__, __LINE__); \
} else {}
#define ASSERT_2(cond, message) \
if (!(cond)) { \
OC_ASSERT_MSG("ASSERT: \"%s\" in file %s, line %d with message: %s", #cond, __FILE__, __LINE__, message); \
} else {}
// Enforce condition to be true, even in release builds.
//
// Prints 'message' and aborts execution if 'cond' is false.
#define ENFORCE(...) OC_ASSERT_OVERLOAD(ENFORCE, __VA_ARGS__)
#define ENFORCE_1(cond) \
if (!(cond)) { \
qFatal("ENFORCE: \"%s\" in file %s, line %d", #cond, __FILE__, __LINE__); \
} else {}
#define ENFORCE_2(cond, message) \
if (!(cond)) { \
qFatal("ENFORCE: \"%s\" in file %s, line %d with message: %s", #cond, __FILE__, __LINE__, message); \
} else {}
// An assert that is only present in debug builds: typically used for
// asserts that are too expensive for release mode.
//
// Q_ASSERT
#endif
+10 -9
Ver Arquivo
@@ -17,6 +17,7 @@
#include "configfile.h"
#include "theme.h"
#include "utility.h"
#include "asserts.h"
#include "creds/abstractcredentials.h"
@@ -139,7 +140,7 @@ void ConfigFile::setOptionalDesktopNotifications(bool show)
void ConfigFile::saveGeometry(QWidget *w)
{
#ifndef TOKEN_AUTH_ONLY
Q_ASSERT(!w->objectName().isNull());
ASSERT(!w->objectName().isNull());
QSettings settings(configFile(), QSettings::IniFormat);
settings.beginGroup(w->objectName());
settings.setValue(QLatin1String(geometryC), w->saveGeometry());
@@ -158,7 +159,7 @@ void ConfigFile::saveGeometryHeader(QHeaderView *header)
{
#ifndef TOKEN_AUTH_ONLY
if(!header) return;
Q_ASSERT(!header->objectName().isEmpty());
ASSERT(!header->objectName().isEmpty());
QSettings settings(configFile(), QSettings::IniFormat);
settings.beginGroup(header->objectName());
@@ -171,7 +172,7 @@ void ConfigFile::restoreGeometryHeader(QHeaderView *header)
{
#ifndef TOKEN_AUTH_ONLY
if(!header) return;
Q_ASSERT(!header->objectName().isNull());
ASSERT(!header->objectName().isNull());
QSettings settings(configFile(), QSettings::IniFormat);
settings.beginGroup(header->objectName());
@@ -230,8 +231,8 @@ QString ConfigFile::excludeFile(Scope scope) const
// directories.
QFileInfo fi;
if (scope != SystemScope) {
QFileInfo fi;
switch (scope) {
case UserScope:
fi.setFile( configPath(), exclFile );
if( ! fi.isReadable() ) {
@@ -241,12 +242,12 @@ QString ConfigFile::excludeFile(Scope scope) const
fi.setFile( configPath(), exclFile );
}
return fi.absoluteFilePath();
} else if (scope != UserScope) {
case SystemScope:
return ConfigFile::excludeFileFromSystem();
} else {
Q_ASSERT(false);
return QString(); // unreachable
}
ASSERT(false);
return QString();
}
QString ConfigFile::excludeFileFromSystem()
+2 -2
Ver Arquivo
@@ -12,10 +12,10 @@
* for more details.
*/
#include <QString>
#include <QDebug>
#include "asserts.h"
#include "creds/abstractcredentials.h"
namespace OCC
@@ -28,7 +28,7 @@ AbstractCredentials::AbstractCredentials()
void AbstractCredentials::setAccount(Account *account)
{
Q_ASSERT(!_account);
ENFORCE(!_account, "should only setAccount once");
_account = account;
}
+8 -5
Ver Arquivo
@@ -13,14 +13,17 @@
*/
#include "discoveryphase.h"
#include "account.h"
#include "theme.h"
#include "asserts.h"
#include <csync_private.h>
#include <csync_rename.h>
#include <qdebug.h>
#include <qdebug.h>
#include <QUrl>
#include "account.h"
#include <QFileInfo>
#include "theme.h"
#include <cstring>
@@ -244,7 +247,7 @@ int get_errno_from_http_errcode( int err, const QString & reason ) {
DiscoverySingleDirectoryJob::DiscoverySingleDirectoryJob(const AccountPtr &account, const QString &path, QObject *parent)
: QObject(parent), _subPath(path), _account(account), _ignoredFirst(false), _isRootPath(false)
: QObject(parent), _subPath(path), _account(account), _ignoredFirst(false), _isRootPath(false), _isExternalStorage(false)
{
}
@@ -370,7 +373,7 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file, con
/* All the entries in a external storage have 'M' in their permission. However, for all
purposes in the desktop client, we only need to know about the mount points.
So replace the 'M' by a 'm' for every sub entries in an external storage */
std::replace(std::begin(file_stat->remotePerm), std::end(file_stat->remotePerm),
std::replace(file_stat->remotePerm, file_stat->remotePerm + strlen(file_stat->remotePerm),
'M', 'm');
}
+4 -3
Ver Arquivo
@@ -35,11 +35,12 @@ class Account;
*/
struct SyncOptions {
SyncOptions() : _newBigFolderSizeLimit(-1), _confirmExternalStorage(false) {}
/** Maximum size (in Bytes) a folder can have without asking for confirmation.
* -1 means infinite */
qint64 _newBigFolderSizeLimit = -1;
qint64 _newBigFolderSizeLimit;
/** If a confirmation should be asked for external storages */
bool _confirmExternalStorage = false;
bool _confirmExternalStorage;
};
@@ -117,7 +118,7 @@ private:
// Set to true if this is the root path and we need to check the data-fingerprint
bool _isRootPath;
// If this directory is an external storage (The first item has 'M' in its permission)
bool _isExternalStorage = false;
bool _isExternalStorage;
QPointer<LsColJob> _lsColJob;
public:
+1 -1
Ver Arquivo
@@ -84,7 +84,7 @@ QString OWNCLOUDSYNC_EXPORT longWinPath( const QString& inpath );
*/
time_t OWNCLOUDSYNC_EXPORT getModTime(const QString& filename);
bool setModTime(const QString &filename, time_t modTime);
bool OWNCLOUDSYNC_EXPORT setModTime(const QString &filename, time_t modTime);
/**
* @brief Get the size for a file
+6 -4
Ver Arquivo
@@ -25,6 +25,7 @@
#include "configfile.h"
#include "utility.h"
#include "account.h"
#include "asserts.h"
#include <json.h>
#ifdef Q_OS_WIN
@@ -638,7 +639,7 @@ bool PropagateDirectory::scheduleNextJob()
return true;
}
Q_ASSERT(_subJobs.at(i)->_state == Running);
ASSERT(_subJobs.at(i)->_state == Running);
auto paral = _subJobs.at(i)->parallelism();
if (paral == WaitForFinished) {
@@ -654,16 +655,17 @@ bool PropagateDirectory::scheduleNextJob()
void PropagateDirectory::slotSubJobFinished(SyncFileItem::Status status)
{
PropagatorJob *subJob = static_cast<PropagatorJob *>(sender());
ASSERT(subJob);
// Delete the job and remove it from our list of jobs.
subJob->deleteLater();
bool wasFirstJob = false;
if (subJob == _firstJob.data()) {
wasFirstJob = true;
_firstJob.reset();
_firstJob.take();
} else {
int i = _subJobs.indexOf(subJob);
Q_ASSERT(i >= 0);
ASSERT(i >= 0);
_subJobs.remove(i);
}
@@ -759,7 +761,7 @@ void CleanupPollsJob::start()
void CleanupPollsJob::slotPollFinished()
{
PollJob *job = qobject_cast<PollJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
if (job->_item->_status == SyncFileItem::FatalError) {
emit aborted(job->_item->_errorString);
deleteLater();
+1 -1
Ver Arquivo
@@ -227,7 +227,7 @@ public:
private slots:
bool possiblyRunNextJob(PropagatorJob *next) {
if (next->_state == NotYetStarted) {
connect(next, SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotSubJobFinished(SyncFileItem::Status)), Qt::QueuedConnection);
connect(next, SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotSubJobFinished(SyncFileItem::Status)));
connect(next, SIGNAL(itemCompleted(const SyncFileItemPtr &)), this, SIGNAL(itemCompleted(const SyncFileItemPtr &)));
connect(next, SIGNAL(progress(const SyncFileItem &,quint64)), this, SIGNAL(progress(const SyncFileItem &,quint64)));
connect(next, SIGNAL(ready()), this, SIGNAL(ready()));
+56 -59
Ver Arquivo
@@ -20,6 +20,7 @@
#include "ownsql.h"
#include "utility.h"
#include "asserts.h"
#define SQLITE_SLEEP_TIME_USEC 100000
#define SQLITE_REPEAT_COUNT 20
@@ -147,10 +148,8 @@ void SqlDatabase::close()
{
if( _db ) {
SQLITE_DO(sqlite3_close(_db) );
if (_errId != SQLITE_OK) {
qWarning() << "ERROR When closing DB" << _error;
Q_ASSERT(!"SQLite Close Error");
}
// Fatal because reopening an unclosed db might be problematic.
ENFORCE(_errId == SQLITE_OK, "Error when closing DB");
_db = 0;
}
}
@@ -223,11 +222,7 @@ int SqlQuery::prepare( const QString& sql, bool allow_failure )
if( _errId != SQLITE_OK ) {
_error = QString::fromUtf8(sqlite3_errmsg(_db));
qWarning() << "Sqlite prepare statement error:" << _error << "in" <<_sql;
if (!allow_failure) {
qFatal("SQLITE Prepare error: %s in %s",
_error.toLocal8Bit().data(),
sql.toLocal8Bit().data());
}
ENFORCE(allow_failure, "SQLITE Prepare error");
}
}
return _errId;
@@ -284,61 +279,63 @@ bool SqlQuery::next()
void SqlQuery::bindValue(int pos, const QVariant& value)
{
int res = -1;
Q_ASSERT(_stmt);
if( _stmt ) {
switch (value.type()) {
case QVariant::Int:
case QVariant::Bool:
res = sqlite3_bind_int(_stmt, pos, value.toInt());
break;
case QVariant::Double:
res = sqlite3_bind_double(_stmt, pos, value.toDouble());
break;
case QVariant::UInt:
case QVariant::LongLong:
res = sqlite3_bind_int64(_stmt, pos, value.toLongLong());
break;
case QVariant::DateTime: {
const QDateTime dateTime = value.toDateTime();
const QString str = dateTime.toString(QLatin1String("yyyy-MM-ddThh:mm:ss.zzz"));
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
}
case QVariant::Time: {
const QTime time = value.toTime();
const QString str = time.toString(QLatin1String("hh:mm:ss.zzz"));
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
}
case QVariant::String: {
if( !value.toString().isNull() ) {
// lifetime of string == lifetime of its qvariant
const QString *str = static_cast<const QString*>(value.constData());
res = sqlite3_bind_text16(_stmt, pos, str->utf16(),
(str->size()) * sizeof(QChar), SQLITE_TRANSIENT);
} else {
res = sqlite3_bind_null(_stmt, pos);
}
break; }
case QVariant::ByteArray: {
auto ba = value.toByteArray();
res = sqlite3_bind_text(_stmt, pos, ba.constData(), ba.size(), SQLITE_TRANSIENT);
break;
}
default: {
QString str = value.toString();
// SQLITE_TRANSIENT makes sure that sqlite buffers the data
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
(str.size()) * sizeof(QChar), SQLITE_TRANSIENT);
break; }
if (!_stmt) {
ASSERT(false);
return;
}
switch (value.type()) {
case QVariant::Int:
case QVariant::Bool:
res = sqlite3_bind_int(_stmt, pos, value.toInt());
break;
case QVariant::Double:
res = sqlite3_bind_double(_stmt, pos, value.toDouble());
break;
case QVariant::UInt:
case QVariant::LongLong:
res = sqlite3_bind_int64(_stmt, pos, value.toLongLong());
break;
case QVariant::DateTime: {
const QDateTime dateTime = value.toDateTime();
const QString str = dateTime.toString(QLatin1String("yyyy-MM-ddThh:mm:ss.zzz"));
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
}
case QVariant::Time: {
const QTime time = value.toTime();
const QString str = time.toString(QLatin1String("hh:mm:ss.zzz"));
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
}
case QVariant::String: {
if( !value.toString().isNull() ) {
// lifetime of string == lifetime of its qvariant
const QString *str = static_cast<const QString*>(value.constData());
res = sqlite3_bind_text16(_stmt, pos, str->utf16(),
(str->size()) * sizeof(QChar), SQLITE_TRANSIENT);
} else {
res = sqlite3_bind_null(_stmt, pos);
}
break; }
case QVariant::ByteArray: {
auto ba = value.toByteArray();
res = sqlite3_bind_text(_stmt, pos, ba.constData(), ba.size(), SQLITE_TRANSIENT);
break;
}
default: {
QString str = value.toString();
// SQLITE_TRANSIENT makes sure that sqlite buffers the data
res = sqlite3_bind_text16(_stmt, pos, str.utf16(),
(str.size()) * sizeof(QChar), SQLITE_TRANSIENT);
break; }
}
if (res != SQLITE_OK) {
qDebug() << Q_FUNC_INFO << "ERROR" << value << res;
}
Q_ASSERT( res == SQLITE_OK );
ASSERT( res == SQLITE_OK );
}
bool SqlQuery::nullValue(int index)
+2 -1
Ver Arquivo
@@ -23,6 +23,7 @@
#include "filesystem.h"
#include "propagatorjobs.h"
#include "checksums.h"
#include "asserts.h"
#include <json.h>
#include <QNetworkAccessManager>
@@ -441,7 +442,7 @@ void PropagateDownloadFile::slotGetFinished()
propagator()->_activeJobList.removeOne(this);
GETFileJob *job = qobject_cast<GETFileJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
qDebug() << Q_FUNC_INFO << job->reply()->request().url() << "FINISHED WITH STATUS"
<< job->reply()->error()
+2 -1
Ver Arquivo
@@ -15,6 +15,7 @@
#include "propagateremotedelete.h"
#include "owncloudpropagator_p.h"
#include "account.h"
#include "asserts.h"
namespace OCC {
@@ -81,7 +82,7 @@ void PropagateRemoteDelete::slotDeleteJobFinished()
{
propagator()->_activeJobList.removeOne(this);
Q_ASSERT(_job);
ASSERT(_job);
qDebug() << Q_FUNC_INFO << _job->reply()->request().url() << "FINISHED WITH STATUS"
<< _job->reply()->error()
+2 -1
Ver Arquivo
@@ -17,6 +17,7 @@
#include "account.h"
#include "syncjournalfilerecord.h"
#include "propagateremotedelete.h"
#include "asserts.h"
#include <QFile>
namespace OCC {
@@ -70,7 +71,7 @@ void PropagateRemoteMkdir::slotMkcolJobFinished()
{
propagator()->_activeJobList.removeOne(this);
Q_ASSERT(_job);
ASSERT(_job);
qDebug() << Q_FUNC_INFO << _job->reply()->request().url() << "FINISHED WITH STATUS"
<< _job->reply()->error()
+4 -3
Ver Arquivo
@@ -18,6 +18,7 @@
#include "account.h"
#include "syncjournalfilerecord.h"
#include "filesystem.h"
#include "asserts.h"
#include <QFile>
#include <QStringList>
#include <QDir>
@@ -123,7 +124,7 @@ void PropagateRemoteMove::slotMoveJobFinished()
{
propagator()->_activeJobList.removeOne(this);
Q_ASSERT(_job);
ASSERT(_job);
qDebug() << Q_FUNC_INFO << _job->reply()->request().url() << "FINISHED WITH STATUS"
<< _job->reply()->error()
@@ -207,8 +208,8 @@ bool PropagateRemoteMove::adjustSelectiveSync(SyncJournalDb *journal, const QStr
return false;
bool changed = false;
Q_ASSERT(!from_.endsWith(QLatin1String("/")));
Q_ASSERT(!to_.endsWith(QLatin1String("/")));
ASSERT(!from_.endsWith(QLatin1String("/")));
ASSERT(!to_.endsWith(QLatin1String("/")));
QString from = from_ + QLatin1String("/");
QString to = to_ + QLatin1String("/");
+3 -2
Ver Arquivo
@@ -25,6 +25,7 @@
#include "checksums.h"
#include "syncengine.h"
#include "propagateremotedelete.h"
#include "asserts.h"
#include <json.h>
#include <QNetworkAccessManager>
@@ -375,7 +376,7 @@ bool UploadDevice::prepareAndOpen(const QString& fileName, qint64 start, qint64
qint64 UploadDevice::writeData(const char* , qint64 ) {
Q_ASSERT(!"write to read only device");
ASSERT(false, "write to read only device");
return 0;
}
@@ -486,7 +487,7 @@ void PropagateUploadFileCommon::startPollJob(const QString& path)
void PropagateUploadFileCommon::slotPollFinished()
{
PollJob *job = qobject_cast<PollJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
propagator()->_activeJobList.removeOne(this);
+9 -7
Ver Arquivo
@@ -25,7 +25,7 @@
#include "syncengine.h"
#include "propagateremotemove.h"
#include "propagateremotedelete.h"
#include "asserts.h"
#include <QNetworkAccessManager>
#include <QFileInfo>
@@ -188,7 +188,7 @@ void PropagateUploadFileNG::slotPropfindFinishedWithError()
void PropagateUploadFileNG::slotDeleteJobFinished()
{
auto job = qobject_cast<DeleteJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
_jobs.remove(_jobs.indexOf(job));
QNetworkReply::NetworkError err = job->reply()->error();
@@ -220,7 +220,7 @@ void PropagateUploadFileNG::slotDeleteJobFinished()
void PropagateUploadFileNG::startNewUpload()
{
Q_ASSERT(propagator()->_activeJobList.count(this) == 1);
ASSERT(propagator()->_activeJobList.count(this) == 1);
_transferId = qrand() ^ _item->_modtime ^ (_item->_size << 16) ^ qHash(_item->_file);
_sent = 0;
_currentChunk = 0;
@@ -270,11 +270,12 @@ void PropagateUploadFileNG::startNextChunk()
return;
quint64 fileSize = _item->_size;
Q_ASSERT(fileSize >= _sent);
ENFORCE(fileSize >= _sent, "Sent data exceeds file size");
quint64 currentChunkSize = qMin(chunkSize(), fileSize - _sent);
if (currentChunkSize == 0) {
Q_ASSERT(_jobs.isEmpty()); // There should be no running job anymore
ASSERT(_jobs.isEmpty());
_finished = true;
// Finish with a MOVE
QString destination = QDir::cleanPath(propagator()->account()->url().path() + QLatin1Char('/')
@@ -343,7 +344,8 @@ void PropagateUploadFileNG::startNextChunk()
void PropagateUploadFileNG::slotPutFinished()
{
PUTFileJob *job = qobject_cast<PUTFileJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
slotJobDestroyed(job); // remove it from the _jobs list
qDebug() << job->reply()->request().url() << "FINISHED WITH STATUS"
@@ -391,7 +393,7 @@ void PropagateUploadFileNG::slotPutFinished()
return;
}
Q_ASSERT(_sent <= _item->_size);
ENFORCE(_sent <= _item->_size, "can't send more than size");
bool finished = _sent == _item->_size;
// Check if the file still exists
+3 -1
Ver Arquivo
@@ -25,6 +25,7 @@
#include "checksums.h"
#include "syncengine.h"
#include "propagateremotedelete.h"
#include "asserts.h"
#include <json.h>
#include <QNetworkAccessManager>
@@ -171,7 +172,8 @@ void PropagateUploadFileV1::startNextChunk()
void PropagateUploadFileV1::slotPutFinished()
{
PUTFileJob *job = qobject_cast<PUTFileJob *>(sender());
Q_ASSERT(job);
ASSERT(job);
slotJobDestroyed(job); // remove it from the _jobs list
qDebug() << Q_FUNC_INFO << job->reply()->request().url() << "FINISHED WITH STATUS"
+15 -8
Ver Arquivo
@@ -24,6 +24,7 @@
#include "csync_private.h"
#include "filesystem.h"
#include "propagateremotedelete.h"
#include "asserts.h"
#ifdef Q_OS_WIN
#include <windows.h>
@@ -83,7 +84,7 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
qRegisterMetaType<SyncFileItem::Direction>("SyncFileItem::Direction");
// Everything in the SyncEngine expects a trailing slash for the localPath.
Q_ASSERT(localPath.endsWith(QLatin1Char('/')));
ASSERT(localPath.endsWith(QLatin1Char('/')));
csync_create(&_csync_ctx, localPath.toUtf8().data());
@@ -353,7 +354,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
QTextCodec::ConverterState utf8State;
static QTextCodec *codec = QTextCodec::codecForName("UTF-8");
Q_ASSERT(codec);
ASSERT(codec);
QString fileUtf8 = codec->toUnicode(file->path, qstrlen(file->path), &utf8State);
QString renameTarget;
QString key = fileUtf8;
@@ -389,9 +390,11 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
item->_modtime = file->modtime;
} else {
if (instruction != CSYNC_INSTRUCTION_NONE) {
qDebug() << "ERROR: Instruction" << item->_instruction << "vs" << instruction << "for" << fileUtf8;
Q_ASSERT(!"Instructions are both unequal NONE");
return -1;
qWarning() << "ERROR: Instruction" << item->_instruction << "vs" << instruction << "for" << fileUtf8;
ASSERT(false);
// Set instruction to NONE for safety.
file->instruction = item->_instruction = instruction = CSYNC_INSTRUCTION_NONE;
return -1; // should lead to treewalk error
}
}
@@ -499,7 +502,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
item->_status = SyncFileItem::SoftError;
break;
default:
Q_ASSERT("Non handled error-status");
ASSERT(false, "Non handled error-status");
/* No error string */
}
@@ -709,8 +712,11 @@ void SyncEngine::startSync()
}
}
Q_ASSERT(!s_anySyncRunning);
Q_ASSERT(!_syncRunning);
if (s_anySyncRunning || _syncRunning) {
ASSERT(false);
return;
}
s_anySyncRunning = true;
_syncRunning = true;
_anotherSyncNeeded = NoFollowUpSync;
@@ -892,6 +898,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
_backInTimeFiles = 0;
bool walkOk = true;
_remotePerms.clear();
_remotePerms.reserve(c_rbtree_size(_csync_ctx->remote.tree));
_seenFiles.clear();
_temporarilyUnavailablePaths.clear();
_renamedFolders.clear();
+8 -7
Ver Arquivo
@@ -17,6 +17,7 @@
#include "syncengine.h"
#include "syncjournaldb.h"
#include "syncjournalfilerecord.h"
#include "asserts.h"
namespace OCC {
@@ -86,7 +87,7 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
{
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
ASSERT(!relativePath.endsWith(QLatin1Char('/')));
if (relativePath.isEmpty()) {
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so resolve manually.
@@ -121,8 +122,8 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
{
QString folderPath = _syncEngine->localPath();
Q_ASSERT(fileName.startsWith(folderPath));
ASSERT(fileName.startsWith(folderPath));
QString localPath = fileName.mid(folderPath.size());
_dirtyPaths.insert(localPath);
@@ -141,7 +142,7 @@ void SyncFileStatusTracker::incSyncCountAndEmitStatusChanged(const QString &rela
// We passed from OK to SYNC, increment the parent to keep it marked as
// SYNC while we propagate ourselves and our own children.
Q_ASSERT(!relativePath.endsWith('/'));
ASSERT(!relativePath.endsWith('/'));
int lastSlashIndex = relativePath.lastIndexOf('/');
if (lastSlashIndex != -1)
incSyncCountAndEmitStatusChanged(relativePath.left(lastSlashIndex), UnknownShared);
@@ -163,7 +164,7 @@ void SyncFileStatusTracker::decSyncCountAndEmitStatusChanged(const QString &rela
emit fileStatusChanged(getSystemDestination(relativePath), status);
// We passed from SYNC to OK, decrement our parent.
Q_ASSERT(!relativePath.endsWith('/'));
ASSERT(!relativePath.endsWith('/'));
int lastSlashIndex = relativePath.lastIndexOf('/');
if (lastSlashIndex != -1)
decSyncCountAndEmitStatusChanged(relativePath.left(lastSlashIndex), UnknownShared);
@@ -174,7 +175,7 @@ void SyncFileStatusTracker::decSyncCountAndEmitStatusChanged(const QString &rela
void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
{
Q_ASSERT(_syncCount.isEmpty());
ASSERT(_syncCount.isEmpty());
std::map<QString, SyncFileStatus::SyncFileStatusTag> oldProblems;
std::swap(_syncProblems, oldProblems);
@@ -277,8 +278,8 @@ SyncFileStatus SyncFileStatusTracker::resolveSyncAndErrorStatus(const QString &r
status.set(problemStatus);
}
// The shared status needs to have been fetched from a SyncFileItem or the DB at this point.
Q_ASSERT(sharedFlag != UnknownShared);
ASSERT(sharedFlag != UnknownShared,
"The shared status needs to have been fetched from a SyncFileItem or the DB at this point.");
if (sharedFlag == Shared)
status.setSharedWithMe(true);
+14 -2
Ver Arquivo
@@ -27,6 +27,7 @@
#include "utility.h"
#include "version.h"
#include "filesystem.h"
#include "asserts.h"
#include "../../csync/src/std/c_jhash.h"
@@ -178,7 +179,7 @@ bool SyncJournalDb::sqlFail( const QString& log, const SqlQuery& query )
{
commitTransaction();
qWarning() << "SQL Error" << log << query.error();
Q_ASSERT(!"SQL ERROR");
ASSERT(false);
_db.close();
return false;
}
@@ -1607,7 +1608,7 @@ void SyncJournalDb::setPollInfo(const SyncJournalDb::PollInfo& info)
QStringList SyncJournalDb::getSelectiveSyncList(SyncJournalDb::SelectiveSyncListType type, bool *ok )
{
QStringList result;
Q_ASSERT(ok);
ASSERT(ok);
QMutexLocker locker(&_mutex);
if( !checkConnect() ) {
@@ -1835,6 +1836,17 @@ void SyncJournalDb::setDataFingerprint(const QByteArray &dataFingerprint)
}
}
void SyncJournalDb::clearFileTable()
{
SqlQuery query(_db);
query.prepare("DELETE FROM metadata;");
if (!query.exec()) {
qWarning() << "SQL error in clearFileTable" << query.error();
} else {
qDebug() << query.lastQuery() << "(" << query.numRowsAffected() << " rows)";
}
}
void SyncJournalDb::commit(const QString& context, bool startTrans)
{
QMutexLocker lock(&_mutex);
+7
Ver Arquivo
@@ -173,6 +173,13 @@ public:
void setDataFingerprint(const QByteArray &dataFingerprint);
QByteArray dataFingerprint();
/**
* Delete any file entry. This will force the next sync to re-sync everything as if it was new,
* restoring everyfile on every remote. If a file is there both on the client and server side,
* it will be a conflict that will be automatically resolved if the file is the same.
*/
void clearFileTable();
private:
bool updateDatabaseStructure();
bool updateMetadataTableStructure();
+7 -8
Ver Arquivo
@@ -273,14 +273,13 @@ void Utility::usleep(int usec)
bool Utility::fsCasePreserving()
{
bool re = false;
if( isWindows() || isMac() ) {
re = true;
} else {
bool isTest = qgetenv("OWNCLOUD_TEST_CASE_PRESERVING").toInt();
re = isTest;
}
return re;
#ifndef WITH_TESTING
QByteArray env = qgetenv("OWNCLOUD_TEST_CASE_PRESERVING");
if (!env.isEmpty())
return env.toInt();
#endif
return isWindows() || isMac();
}
bool Utility::fileNamesEqual( const QString& fn1, const QString& fn2)
+9 -15
Ver Arquivo
@@ -2,7 +2,6 @@ include_directories(${CMAKE_BINARY_DIR}/csync ${CMAKE_BINARY_DIR}/csync/src ${CM
include_directories(${CMAKE_SOURCE_DIR}/csync/src/)
include_directories(${CMAKE_SOURCE_DIR}/csync/src/std ${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
include(QtVersionAbstraction)
setup_qt()
@@ -10,7 +9,6 @@ setup_qt()
include(owncloud_add_test.cmake)
owncloud_add_test(OwncloudPropagator "")
owncloud_add_test(Utility "")
owncloud_add_test(Updater "")
SET(FolderWatcher_SRC ../src/gui/folderwatcher.cpp)
@@ -25,31 +23,30 @@ IF( APPLE )
list(APPEND FolderWatcher_SRC ../src/gui/folderwatcher_mac.cpp)
list(APPEND FolderWatcher_SRC ../src/gui/socketapisocket_mac.mm)
ENDIF()
owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}")
if( UNIX AND NOT APPLE )
if(HAVE_QT5 AND NOT BUILD_WITH_QT4)
owncloud_add_test(InotifyWatcher "${FolderWatcher_SRC}")
endif(HAVE_QT5 AND NOT BUILD_WITH_QT4)
endif(UNIX AND NOT APPLE)
owncloud_add_test(CSyncSqlite "")
owncloud_add_test(NetrcParser ../src/cmd/netrcparser.cpp)
owncloud_add_test(OwnSql "")
owncloud_add_test(SyncJournalDB "")
owncloud_add_test(SyncFileItem "")
owncloud_add_test(ConcatUrl "")
owncloud_add_test(XmlParse "")
owncloud_add_test(FileSystem "")
owncloud_add_test(ChecksumValidator "")
owncloud_add_test(ExcludedFiles "")
if(HAVE_QT5 AND NOT BUILD_WITH_QT4)
owncloud_add_test(FileSystem "")
owncloud_add_test(Utility "")
owncloud_add_test(SyncEngine "syncenginetestutils.h")
owncloud_add_test(SyncFileStatusTracker "syncenginetestutils.h")
owncloud_add_test(ChunkingNg "syncenginetestutils.h")
owncloud_add_test(UploadReset "syncenginetestutils.h")
owncloud_add_test(AllFilesDeleted "syncenginetestutils.h")
owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}")
if( UNIX AND NOT APPLE )
owncloud_add_test(InotifyWatcher "${FolderWatcher_SRC}")
endif(UNIX AND NOT APPLE)
owncloud_add_benchmark(LargeSync "syncenginetestutils.h")
endif(HAVE_QT5 AND NOT BUILD_WITH_QT4)
@@ -61,8 +58,5 @@ list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp )
list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp )
list(APPEND FolderMan_SRC ${FolderWatcher_SRC})
list(APPEND FolderMan_SRC stub.cpp )
#include_directories(${QTKEYCHAIN_INCLUDE_DIR})
#include_directories(${CMAKE_BINARY_DIR}/src/gui)
#include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/qjson)
owncloud_add_test(FolderMan "${FolderMan_SRC}")
+2
Ver Arquivo
@@ -12,6 +12,7 @@ macro(owncloud_add_test test_class additional_cpp)
add_executable(${OWNCLOUD_TEST_CLASS}Test test${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp})
qt5_use_modules(${OWNCLOUD_TEST_CLASS}Test Test Sql Xml Network)
set_target_properties(${OWNCLOUD_TEST_CLASS}Test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY})
target_link_libraries(${OWNCLOUD_TEST_CLASS}Test
updater
@@ -40,6 +41,7 @@ macro(owncloud_add_benchmark test_class additional_cpp)
add_executable(${OWNCLOUD_TEST_CLASS}Bench benchmarks/bench${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp})
qt5_use_modules(${OWNCLOUD_TEST_CLASS}Bench Test Sql Xml Network)
set_target_properties(${OWNCLOUD_TEST_CLASS}Bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY})
target_link_libraries(${OWNCLOUD_TEST_CLASS}Bench
updater
+2 -2
Ver Arquivo
@@ -226,7 +226,7 @@ public:
etag = file->etag;
return file;
}
return nullptr;
return 0;
}
FileInfo *createDir(const QString &relativePath) {
@@ -345,7 +345,7 @@ public:
} else
xml.writeEmptyElement(davUri, QStringLiteral("resourcetype"));
auto gmtDate = fileInfo.lastModified.toTimeZone(QTimeZone("GMT"));
auto gmtDate = fileInfo.lastModified.toTimeZone(QTimeZone(0));
auto stringDate = gmtDate.toString("ddd, dd MMM yyyy HH:mm:ss 'GMT'");
xml.writeTextElement(davUri, QStringLiteral("getlastmodified"), stringDate);
xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.size));
+118
Ver Arquivo
@@ -0,0 +1,118 @@
/*
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
*/
#include <QtTest>
#include "syncenginetestutils.h"
#include <syncengine.h>
using namespace OCC;
/*
* This test ensure that the SyncEngine::aboutToRemoveAllFiles is correctly called and that when
* we the user choose to remove all files SyncJournalDb::clearFileTable makes works as expected
*/
class TestAllFilesDeleted : public QObject
{
Q_OBJECT
private slots:
void testAllFilesDeletedKeep_data()
{
QTest::addColumn<bool>("deleteOnRemote");
QTest::newRow("local") << false;
QTest::newRow("remote") << true;
}
/*
* In this test, all files are deleted in the client, or the server, and we simulate
* that the users press "keep"
*/
void testAllFilesDeletedKeep()
{
QFETCH(bool, deleteOnRemote);
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
//Just set a blacklist so we can check it is still there. This directory does not exists but
// that does not matter for our purposes.
QStringList selectiveSyncBlackList = { "Q/" };
fakeFolder.syncEngine().journal()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList,
selectiveSyncBlackList);
auto initialState = fakeFolder.currentLocalState();
int aboutToRemoveAllFilesCalled = 0;
QObject::connect(&fakeFolder.syncEngine(), &SyncEngine::aboutToRemoveAllFiles,
[&](SyncFileItem::Direction dir, bool *cancel) {
QCOMPARE(aboutToRemoveAllFilesCalled, 0);
aboutToRemoveAllFilesCalled++;
QCOMPARE(dir, deleteOnRemote ? SyncFileItem::Down : SyncFileItem::Up);
*cancel = true;
fakeFolder.syncEngine().journal()->clearFileTable(); // That's what Folder is doing
});
auto &modifier = deleteOnRemote ? fakeFolder.remoteModifier() : fakeFolder.localModifier();
for (const auto &s : fakeFolder.currentRemoteState().children.keys())
modifier.remove(s);
QVERIFY(!fakeFolder.syncOnce()); // Should fail because we cancel the sync
QCOMPARE(aboutToRemoveAllFilesCalled, 1);
// Next sync should recover all files
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), initialState);
QCOMPARE(fakeFolder.currentRemoteState(), initialState);
// The selective sync blacklist should be not have been deleted.
bool ok = true;
QCOMPARE(fakeFolder.syncEngine().journal()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok),
selectiveSyncBlackList);
}
void testAllFilesDeletedDelete_data()
{
testAllFilesDeletedKeep_data();
}
/*
* This test is like the previous one but we simulate that the user presses "delete"
*/
void testAllFilesDeletedDelete()
{
QFETCH(bool, deleteOnRemote);
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
int aboutToRemoveAllFilesCalled = 0;
QObject::connect(&fakeFolder.syncEngine(), &SyncEngine::aboutToRemoveAllFiles,
[&](SyncFileItem::Direction dir, bool *cancel) {
QCOMPARE(aboutToRemoveAllFilesCalled, 0);
aboutToRemoveAllFilesCalled++;
QCOMPARE(dir, deleteOnRemote ? SyncFileItem::Down : SyncFileItem::Up);
*cancel = false;
});
auto &modifier = deleteOnRemote ? fakeFolder.remoteModifier() : fakeFolder.localModifier();
for (const auto &s : fakeFolder.currentRemoteState().children.keys())
modifier.remove(s);
QVERIFY(fakeFolder.syncOnce()); // Should succeed, and all files must then be deleted
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QCOMPARE(fakeFolder.currentLocalState().children.count(), 0);
// Try another sync to be sure.
QVERIFY(fakeFolder.syncOnce()); // Should succeed (doing nothing)
QCOMPARE(aboutToRemoveAllFilesCalled, 1); // should not have been called.
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QCOMPARE(fakeFolder.currentLocalState().children.count(), 0);
}
};
QTEST_GUILESS_MAIN(TestAllFilesDeleted)
#include "testallfilesdeleted.moc"
+8 -3
Ver Arquivo
@@ -55,7 +55,6 @@ using namespace OCC;
private slots:
void initTestCase() {
qDebug() << Q_FUNC_INFO;
_root = QDir::tempPath() + "/" + "test_" + QString::number(qrand());
QDir rootDir(_root);
@@ -65,7 +64,9 @@ using namespace OCC;
}
void testUploadChecksummingAdler() {
#ifndef ZLIB_FOUND
QSKIP("ZLIB not found.", SkipSingle);
#else
ComputeChecksum *vali = new ComputeChecksum(this);
_expectedType = "Adler32";
vali->setChecksumType(_expectedType);
@@ -81,6 +82,7 @@ using namespace OCC;
loop.exec();
delete vali;
#endif
}
void testUploadChecksummingMd5() {
@@ -119,7 +121,9 @@ using namespace OCC;
}
void testDownloadChecksummingAdler() {
#ifndef ZLIB_FOUND
QSKIP("ZLIB not found.", SkipSingle);
#else
QByteArray adler = checkSumAdlerC;
adler.append(":");
adler.append(FileSystem::calcAdler32( _testfile ));
@@ -143,6 +147,7 @@ using namespace OCC;
QTRY_VERIFY(_errorSeen);
delete vali;
#endif
}
+2 -6
Ver Arquivo
@@ -11,9 +11,7 @@
using namespace OCC;
#define STR_(X) #X
#define STR(X) STR_(X)
#define BIN_PATH STR(OWNCLOUD_BIN_PATH)
#define EXCLUDE_LIST_FILE SOURCEDIR"/../sync-exclude.lst"
class TestExcludedFiles: public QObject
{
@@ -31,9 +29,7 @@ private slots:
QVERIFY(!excluded.isExcluded("/a/.b", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden));
QString path(BIN_PATH);
path.append("/sync-exclude.lst");
excluded.addExcludeFilePath(path);
excluded.addExcludeFilePath(EXCLUDE_LIST_FILE);
excluded.reloadExcludes();
QVERIFY(!excluded.isExcluded("/a/b", "/a", keepHidden));
+23 -38
Ver Arquivo
@@ -17,7 +17,7 @@ class TestFileSystem : public QObject
{
Q_OBJECT
QString _root;
QTemporaryDir _root;
QByteArray shellSum( const QByteArray& cmd, const QString& file )
@@ -38,51 +38,36 @@ class TestFileSystem : public QObject
}
private slots:
void initTestCase() {
qsrand(QTime::currentTime().msec());
QString subdir("test_"+QString::number(qrand()));
_root = QDir::tempPath() + "/" + subdir;
QDir dir("/tmp");
dir.mkdir(subdir);
qDebug() << "creating test directory " << _root;
}
void cleanupTestCase()
{
if( !_root.isEmpty() )
system(QString("rm -rf "+_root).toUtf8());
}
void testMd5Calc()
{
QString file( _root+"/file_a.bin");
writeRandomFile(file);
QFileInfo fi(file);
QVERIFY(fi.exists());
QByteArray sum = calcMd5(file);
QString file( _root.path() + "/file_a.bin");
QVERIFY(writeRandomFile(file));
QFileInfo fi(file);
QVERIFY(fi.exists());
QByteArray sum = calcMd5(file);
QByteArray sSum = shellSum("/usr/bin/md5sum", file);
qDebug() << "calculated" << sum << "versus md5sum:"<< sSum;
QVERIFY(!sSum.isEmpty());
QVERIFY(!sum.isEmpty());
QVERIFY(sSum == sum );
QByteArray sSum = shellSum("md5sum", file);
if (sSum.isEmpty())
QSKIP("Couldn't execute md5sum to calculate checksum, executable missing?", SkipSingle);
QVERIFY(!sum.isEmpty());
QCOMPARE(sSum, sum);
}
void testSha1Calc()
{
QString file( _root+"/file_b.bin");
writeRandomFile(file);
QFileInfo fi(file);
QVERIFY(fi.exists());
QByteArray sum = calcSha1(file);
QString file( _root.path() + "/file_b.bin");
writeRandomFile(file);
QFileInfo fi(file);
QVERIFY(fi.exists());
QByteArray sum = calcSha1(file);
QByteArray sSum = shellSum("/usr/bin/sha1sum", file);
qDebug() << "calculated" << sum << "versus sha1sum:"<< sSum;
QVERIFY(!sSum.isEmpty());
QVERIFY(!sum.isEmpty());
QVERIFY(sSum == sum );
QByteArray sSum = shellSum("sha1sum", file);
if (sSum.isEmpty())
QSKIP("Couldn't execute sha1sum to calculate checksum, executable missing?", SkipSingle);
QVERIFY(!sum.isEmpty());
QCOMPARE(sSum, sum);
}
};
+33 -32
Ver Arquivo
@@ -63,6 +63,7 @@ private slots:
f.open(QFile::WriteOnly);
f.write("hello");
}
QString dirPath = dir2.canonicalPath();
AccountPtr account = Account::create();
QUrl url("http://example.de");
@@ -73,22 +74,22 @@ private slots:
AccountStatePtr newAccountState(new AccountState(account));
FolderMan *folderman = FolderMan::instance();
QCOMPARE(folderman, &_fm);
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dir.path() + "/sub/ownCloud1")));
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dir.path() + "/ownCloud2")));
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud1")));
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2")));
// those should be allowed
// QString FolderMan::checkPathValidityForNewFolder(const QString& path, const QUrl &serverUrl, bool forNewDirectory)
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/free"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/free2/"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/free"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/free2/"), QString());
// Not an existing directory -> Ok
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/bliblablu"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/free/bliblablu"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/bliblablu/some/more"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/bliblablu"), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/free/bliblablu"), QString());
// QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/bliblablu/some/more"), QString());
// A file -> Error
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/file.txt").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/file.txt").isNull());
// There are folders configured in those folders, url needs to be taken into account: -> ERROR
QUrl url2(url);
@@ -96,51 +97,51 @@ private slots:
url2.setUserName(user);
// The following both fail because they refer to the same account (user and url)
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1", url2).isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/ownCloud2/", url2).isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1", url2).isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/", url2).isNull());
// Now it will work because the account is different
QUrl url3("http://anotherexample.org");
url3.setUserName("dummy");
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1", url3), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/ownCloud2/", url3), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1", url3), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/", url3), QString());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path()).isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/folder").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/folder/f").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath).isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder/f").isNull());
// make a bunch of links
QVERIFY(QFile::link(dir.path() + "/sub/free", dir.path() + "/link1"));
QVERIFY(QFile::link(dir.path() + "/sub", dir.path() + "/link2"));
QVERIFY(QFile::link(dir.path() + "/sub/ownCloud1", dir.path() + "/link3"));
QVERIFY(QFile::link(dir.path() + "/sub/ownCloud1/folder", dir.path() + "/link4"));
QVERIFY(QFile::link(dirPath + "/sub/free", dirPath + "/link1"));
QVERIFY(QFile::link(dirPath + "/sub", dirPath + "/link2"));
QVERIFY(QFile::link(dirPath + "/sub/ownCloud1", dirPath + "/link3"));
QVERIFY(QFile::link(dirPath + "/sub/ownCloud1/folder", dirPath + "/link4"));
// Ok
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link1").isNull());
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link2/free").isNull());
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link1").isNull());
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link2/free").isNull());
// Not Ok
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link2").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link2").isNull());
// link 3 points to an existing sync folder. To make it fail, the account must be the same
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link3", url2).isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3", url2).isNull());
// while with a different account, this is fine
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/link3", url3), QString());
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/link3", url3), QString());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link4").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link3/folder").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link4").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3/folder").isNull());
// test some non existing sub path (error)
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/some/sub/path").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/ownCloud2/blublu").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/folder/g/h").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link3/folder/neu_folder").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/some/sub/path").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/blublu").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder/g/h").isNull());
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3/folder/neu_folder").isNull());
// Subfolder of links
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link1/subfolder").isNull());
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link2/free/subfolder").isNull());
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link1/subfolder").isNull());
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link2/free/subfolder").isNull());
// Invalid paths
QVERIFY(!folderman->checkPathValidityForNewFolder("").isNull());
+124 -117
Ver Arquivo
@@ -10,174 +10,181 @@
#include "folderwatcher.h"
#include "utility.h"
void touch(const QString &file)
{
#ifdef Q_OS_WIN
OCC::Utility::writeRandomFile(file);
#else
QString cmd;
cmd = QString("touch %1").arg(file);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
}
void mkdir(const QString &file)
{
#ifdef Q_OS_WIN
QDir dir;
dir.mkdir(file);
#else
QString cmd = QString("mkdir %1").arg(file);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
}
void rmdir(const QString &file)
{
#ifdef Q_OS_WIN
QDir dir;
dir.rmdir(file);
#else
QString cmd = QString("rmdir %1").arg(file);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
}
void rm(const QString &file)
{
#ifdef Q_OS_WIN
QFile::remove(file);
#else
QString cmd = QString("rm %1").arg(file);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
}
void mv(const QString &file1, const QString &file2)
{
#ifdef Q_OS_WIN
QFile::rename(file1, file2);
#else
QString cmd = QString("mv %1 %2").arg(file1, file2);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
}
using namespace OCC;
class TestFolderWatcher : public QObject
{
Q_OBJECT
public slots:
void slotFolderChanged( const QString& path ) {
if (_skipNotifications.contains(path)) {
return;
}
if (_requiredNotifications.contains(path)) {
_receivedNotifications.insert(path);
}
}
QTemporaryDir _root;
QString _rootPath;
QScopedPointer<FolderWatcher> _watcher;
QScopedPointer<QSignalSpy> _pathChangedSpy;
void slotEnd() { // in case something goes wrong...
_loop.quit();
QVERIFY2(1 == 0, "Loop hang!");
}
private:
QString _root;
FolderWatcher *_watcher;
QEventLoop _loop;
QTimer _timer;
QSet<QString> _requiredNotifications;
QSet<QString> _receivedNotifications;
QSet<QString> _skipNotifications;
void processAndWait()
bool waitForPathChanged(const QString &path)
{
_loop.processEvents();
Utility::usleep(200000);
_loop.processEvents();
QElapsedTimer t;
t.start();
while (t.elapsed() < 5000) {
// Check if it was already reported as changed by the watcher
for (int i = 0; i < _pathChangedSpy->size(); ++i) {
const auto &args = _pathChangedSpy->at(i);
if (args.first().toString() == path)
return true;
}
// Wait a bit and test again (don't bother checking if we timed out or not)
_pathChangedSpy->wait(200);
}
return false;
}
public:
TestFolderWatcher() {
qsrand(QTime::currentTime().msec());
QDir rootDir(_root.path());
_rootPath = rootDir.canonicalPath();
qDebug() << "creating test directory tree in " << _rootPath;
rootDir.mkpath("a1/b1/c1");
rootDir.mkpath("a1/b1/c2");
rootDir.mkpath("a1/b2/c1");
rootDir.mkpath("a1/b3/c3");
rootDir.mkpath("a2/b3/c3");
Utility::writeRandomFile( _rootPath+"/a1/random.bin");
Utility::writeRandomFile( _rootPath+"/a1/b2/todelete.bin");
Utility::writeRandomFile( _rootPath+"/a2/renamefile");
Utility::writeRandomFile( _rootPath+"/a1/movefile");
_watcher.reset(new FolderWatcher(_rootPath));
_pathChangedSpy.reset(new QSignalSpy(_watcher.data(), SIGNAL(pathChanged(QString))));
}
private slots:
void initTestCase() {
qsrand(QTime::currentTime().msec());
_root = QDir::tempPath() + "/" + "test_" + QString::number(qrand());
qDebug() << "creating test directory tree in " << _root;
QDir rootDir(_root);
rootDir.mkpath(_root + "/a1/b1/c1");
rootDir.mkpath(_root + "/a1/b1/c2");
rootDir.mkpath(_root + "/a1/b2/c1");
rootDir.mkpath(_root + "/a1/b3/c3");
rootDir.mkpath(_root + "/a2/b3/c3");
Utility::writeRandomFile( _root+"/a1/random.bin");
Utility::writeRandomFile( _root+"/a1/b2/todelete.bin");
Utility::writeRandomFile( _root+"/a2/renamefile");
Utility::writeRandomFile( _root+"/a1/movefile");
_watcher = new FolderWatcher(_root);
QObject::connect(_watcher, SIGNAL(pathChanged(QString)), this, SLOT(slotFolderChanged(QString)));
_timer.singleShot(5000, this, SLOT(slotEnd()));
}
void init()
{
_receivedNotifications.clear();
_requiredNotifications.clear();
_skipNotifications.clear();
}
void checkNotifications()
{
processAndWait();
QCOMPARE(_receivedNotifications, _requiredNotifications);
_pathChangedSpy->clear();
}
void testACreate() { // create a new file
QString file(_root + "/foo.txt");
QString file(_rootPath + "/foo.txt");
QString cmd;
_requiredNotifications.insert(file);
cmd = QString("echo \"xyz\" > %1").arg(file);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
checkNotifications();
QVERIFY(waitForPathChanged(file));
}
void testATouch() { // touch an existing file.
QString file(_root + "/a1/random.bin");
_requiredNotifications.insert(file);
#ifdef Q_OS_WIN
Utility::writeRandomFile(QString("%1/a1/random.bin").arg(_root));
#else
QString cmd;
cmd = QString("touch %1").arg(file);
qDebug() << "Command: " << cmd;
system(cmd.toLocal8Bit());
#endif
checkNotifications();
QString file(_rootPath + "/a1/random.bin");
touch(file);
QVERIFY(waitForPathChanged(file));
}
void testCreateADir() {
QString file(_root+"/a1/b1/new_dir");
_requiredNotifications.insert(file);
//_skipNotifications.insert(_root + "/a1/b1/new_dir");
QDir dir;
dir.mkdir(file);
QVERIFY(QFile::exists(file));
checkNotifications();
QString file(_rootPath+"/a1/b1/new_dir");
mkdir(file);
QVERIFY(waitForPathChanged(file));
}
void testRemoveADir() {
QString file(_root+"/a1/b3/c3");
_requiredNotifications.insert(file);
QDir dir;
QVERIFY(dir.rmdir(file));
checkNotifications();
QString file(_rootPath+"/a1/b3/c3");
rmdir(file);
QVERIFY(waitForPathChanged(file));
}
void testRemoveAFile() {
QString file(_root+"/a1/b2/todelete.bin");
_requiredNotifications.insert(file);
QString file(_rootPath+"/a1/b2/todelete.bin");
QVERIFY(QFile::exists(file));
QFile::remove(file);
rm(file);
QVERIFY(!QFile::exists(file));
checkNotifications();
QVERIFY(waitForPathChanged(file));
}
void testRenameAFile() {
QString file1(_root+"/a2/renamefile");
QString file2(_root+"/a2/renamefile.renamed");
_requiredNotifications.insert(file1);
_requiredNotifications.insert(file2);
QString file1(_rootPath+"/a2/renamefile");
QString file2(_rootPath+"/a2/renamefile.renamed");
QVERIFY(QFile::exists(file1));
QFile::rename(file1, file2);
mv(file1, file2);
QVERIFY(QFile::exists(file2));
checkNotifications();
QVERIFY(waitForPathChanged(file1));
QVERIFY(waitForPathChanged(file2));
}
void testMoveAFile() {
QString old_file(_root+"/a1/movefile");
QString new_file(_root+"/a2/movefile.renamed");
_requiredNotifications.insert(old_file);
_requiredNotifications.insert(new_file);
QString old_file(_rootPath+"/a1/movefile");
QString new_file(_rootPath+"/a2/movefile.renamed");
QVERIFY(QFile::exists(old_file));
QFile::rename(old_file, new_file);
mv(old_file, new_file);
QVERIFY(QFile::exists(new_file));
checkNotifications();
}
void cleanupTestCase() {
if( _root.startsWith(QDir::tempPath() )) {
system( QString("rm -rf %1").arg(_root).toLocal8Bit() );
}
delete _watcher;
QVERIFY(waitForPathChanged(old_file));
QVERIFY(waitForPathChanged(new_file));
}
};
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// Qt4 does not have QTEST_GUILESS_MAIN, so we simulate it.
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
TestFolderWatcher tc;
return QTest::qExec(&tc, argc, argv);
}
#ifdef Q_OS_MAC
QTEST_MAIN(TestFolderWatcher)
#else
QTEST_GUILESS_MAIN(TestFolderWatcher)
#endif
+1 -2
Ver Arquivo
@@ -169,7 +169,6 @@ private slots:
void testFileNamesEqual()
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
qDebug() << "*** checking fileNamesEqual function";
QTemporaryDir dir;
QVERIFY(dir.isValid());
QDir dir2(dir.path());
@@ -201,5 +200,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestUtility)
QTEST_GUILESS_MAIN(TestUtility)
#include "testutility.moc"
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff