summaryrefslogtreecommitdiffstats
path: root/tdeio/tests/jobtest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdeio/tests/jobtest.cpp')
-rw-r--r--tdeio/tests/jobtest.cpp613
1 files changed, 613 insertions, 0 deletions
diff --git a/tdeio/tests/jobtest.cpp b/tdeio/tests/jobtest.cpp
new file mode 100644
index 000000000..12f106cd2
--- /dev/null
+++ b/tdeio/tests/jobtest.cpp
@@ -0,0 +1,613 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004-2006 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "jobtest.h"
+
+#include <config.h>
+
+#include <kurl.h>
+#include <kapplication.h>
+#include <klargefile.h>
+#include <tdeio/netaccess.h>
+#include <kdebug.h>
+#include <kcmdlineargs.h>
+#include <kprotocolinfo.h>
+
+#include <tqfileinfo.h>
+#include <tqeventloop.h>
+#include <tqdir.h>
+#include <tqfileinfo.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <utime.h>
+
+// The code comes partly from tdebase/tdeioslave/trash/testtrash.cpp
+
+static bool check(const TQString& txt, TQString a, TQString b)
+{
+ if (a.isEmpty())
+ a = TQString::null;
+ if (b.isEmpty())
+ b = TQString::null;
+ if (a == b) {
+ kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl;
+ }
+ else {
+ kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl;
+ exit(1);
+ }
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ TDEApplication::disableAutoDcopRegistration();
+ TDECmdLineArgs::init(argc,argv,"jobtest", 0, 0, 0, 0);
+ TDEApplication app;
+
+ JobTest test;
+ test.setup();
+ test.runAll();
+ test.cleanup();
+ kdDebug() << "All tests OK." << endl;
+ return 0; // success. The exit(1) in check() is what happens in case of failure.
+}
+
+TQString JobTest::homeTmpDir() const
+{
+ return TQDir::homeDirPath() + "/.trinity/jobtest/";
+}
+
+TQString JobTest::otherTmpDir() const
+{
+ // This one needs to be on another partition
+ return "/tmp/jobtest/";
+}
+
+KURL JobTest::systemTmpDir() const
+{
+ return "system:/home/.trinity/jobtest-system/";
+}
+
+TQString JobTest::realSystemPath() const
+{
+ return TQDir::homeDirPath() + "/.trinity/jobtest-system/";
+}
+
+void JobTest::setup()
+{
+ // Start with a clean base dir
+ cleanup();
+ TQDir dir; // TT: why not a static method?
+ bool ok = dir.mkdir( homeTmpDir() );
+ if ( !ok )
+ kdFatal() << "Couldn't create " << homeTmpDir() << endl;
+ ok = dir.mkdir( otherTmpDir() );
+ if ( !ok )
+ kdFatal() << "Couldn't create " << otherTmpDir() << endl;
+ ok = dir.mkdir( realSystemPath() );
+ if ( !ok )
+ kdFatal() << "Couldn't create " << realSystemPath() << endl;
+}
+
+void JobTest::runAll()
+{
+ get();
+ copyFileToSamePartition();
+ copyDirectoryToSamePartition();
+ copyDirectoryToExistingDirectory();
+ copyFileToOtherPartition();
+ copyDirectoryToOtherPartition();
+ listRecursive();
+ moveFileToSamePartition();
+ moveDirectoryToSamePartition();
+ moveFileToOtherPartition();
+ moveSymlinkToOtherPartition();
+ moveDirectoryToOtherPartition();
+ moveFileNoPermissions();
+ moveDirectoryNoPermissions();
+
+ copyFileToSystem();
+}
+
+void JobTest::cleanup()
+{
+ TDEIO::NetAccess::del( homeTmpDir(), 0 );
+ TDEIO::NetAccess::del( otherTmpDir(), 0 );
+ TDEIO::NetAccess::del( systemTmpDir(), 0 );
+}
+
+static void setTimeStamp( const TQString& path )
+{
+#ifdef Q_OS_UNIX
+ // Put timestamp in the past so that we can check that the
+ // copy actually preserves it.
+ struct timeval tp;
+ gettimeofday( &tp, 0 );
+ struct utimbuf utbuf;
+ utbuf.actime = tp.tv_sec - 30; // 30 seconds ago
+ utbuf.modtime = tp.tv_sec - 60; // 60 second ago
+ utime( TQFile::encodeName( path ), &utbuf );
+ tqDebug( "Time changed for %s", path.latin1() );
+#endif
+}
+
+static void createTestFile( const TQString& path )
+{
+ TQFile f( path );
+ if ( !f.open( IO_WriteOnly ) )
+ kdFatal() << "Can't create " << path << endl;
+ f.tqwriteBlock( "Hello world", 11 );
+ f.close();
+ setTimeStamp( path );
+}
+
+static void createTestSymlink( const TQString& path )
+{
+ // Create symlink if it doesn't exist yet
+ KDE_struct_stat buf;
+ if ( KDE_lstat( TQFile::encodeName( path ), &buf ) != 0 ) {
+ bool ok = symlink( "/IDontExist", TQFile::encodeName( path ) ) == 0; // broken symlink
+ if ( !ok )
+ kdFatal() << "couldn't create symlink: " << strerror( errno ) << endl;
+ }
+}
+
+static void createTestDirectory( const TQString& path )
+{
+ TQDir dir;
+ bool ok = dir.mkdir( path );
+ if ( !ok && !dir.exists() )
+ kdFatal() << "couldn't create " << path << endl;
+ createTestFile( path + "/testfile" );
+ createTestSymlink( path + "/testlink" );
+ setTimeStamp( path );
+}
+
+void JobTest::get()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString filePath = homeTmpDir() + "fileFromHome";
+ createTestFile( filePath );
+ KURL u; u.setPath( filePath );
+ m_result = -1;
+ TDEIO::StoredTransferJob* job = TDEIO::storedGet( u );
+ connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
+ this, TQT_SLOT( slotGetResult( TDEIO::Job* ) ) );
+ kapp->eventLoop()->enterLoop();
+ assert( m_result == 0 ); // no error
+ assert( m_data.size() == 11 );
+ assert( TQCString( m_data ) == "Hello world" );
+}
+
+void JobTest::slotGetResult( TDEIO::Job* job )
+{
+ m_result = job->error();
+ m_data = static_cast<TDEIO::StoredTransferJob *>(job)->data();
+ kapp->eventLoop()->exitLoop();
+}
+
+////
+
+void JobTest::copyLocalFile( const TQString& src, const TQString& dest )
+{
+ KURL u;
+ u.setPath( src );
+ KURL d;
+ d.setPath( dest );
+
+ // copy the file with file_copy
+ bool ok = TDEIO::NetAccess::file_copy( u, d );
+ assert( ok );
+ assert( TQFile::exists( dest ) );
+ assert( TQFile::exists( src ) ); // still there
+
+ {
+ // check that the timestamp is the same (#24443)
+ // Note: this only works because of copy() in kio_file.
+ // The datapump solution ignores mtime, the app has to call FileCopyJob::setModificationTime()
+ TQFileInfo srcInfo( src );
+ TQFileInfo destInfo( dest );
+ assert( srcInfo.lastModified() == destInfo.lastModified() );
+ }
+
+ // cleanup and retry with TDEIO::copy()
+ TQFile::remove( dest );
+ ok = TDEIO::NetAccess::dircopy( u, d, 0 );
+ assert( ok );
+ assert( TQFile::exists( dest ) );
+ assert( TQFile::exists( src ) ); // still there
+ {
+ // check that the timestamp is the same (#24443)
+ TQFileInfo srcInfo( src );
+ TQFileInfo destInfo( dest );
+ assert( srcInfo.lastModified() == destInfo.lastModified() );
+ }
+}
+
+void JobTest::copyLocalDirectory( const TQString& src, const TQString& _dest, int flags )
+{
+ assert( TQFileInfo( src ).isDir() );
+ assert( TQFileInfo( src + "/testfile" ).isFile() );
+ KURL u;
+ u.setPath( src );
+ TQString dest( _dest );
+ KURL d;
+ d.setPath( dest );
+ if ( flags & AlreadyExists )
+ assert( TQFile::exists( dest ) );
+ else
+ assert( !TQFile::exists( dest ) );
+
+ bool ok = TDEIO::NetAccess::dircopy( u, d, 0 );
+ assert( ok );
+
+ if ( flags & AlreadyExists ) {
+ dest += "/" + u.fileName();
+ //kdDebug() << "Expecting dest=" << dest << endl;
+ }
+
+ assert( TQFile::exists( dest ) );
+ assert( TQFileInfo( dest ).isDir() );
+ assert( TQFileInfo( dest + "/testfile" ).isFile() );
+ assert( TQFile::exists( src ) ); // still there
+ {
+ // check that the timestamp is the same (#24443)
+ TQFileInfo srcInfo( src );
+ TQFileInfo destInfo( dest );
+ assert( srcInfo.lastModified() == destInfo.lastModified() );
+ }
+}
+
+void JobTest::copyFileToSamePartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString filePath = homeTmpDir() + "fileFromHome";
+ const TQString dest = homeTmpDir() + "fileFromHome_copied";
+ createTestFile( filePath );
+ copyLocalFile( filePath, dest );
+}
+
+void JobTest::copyDirectoryToSamePartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString src = homeTmpDir() + "dirFromHome";
+ const TQString dest = homeTmpDir() + "dirFromHome_copied";
+ createTestDirectory( src );
+ copyLocalDirectory( src, dest );
+}
+
+void JobTest::copyDirectoryToExistingDirectory()
+{
+ kdDebug() << k_funcinfo << endl;
+ // just the same as copyDirectoryToSamePartition, but it means that
+ // this time dest exists.
+ const TQString src = homeTmpDir() + "dirFromHome";
+ const TQString dest = homeTmpDir() + "dirFromHome_copied";
+ createTestDirectory( src );
+ copyLocalDirectory( src, dest, AlreadyExists );
+}
+
+void JobTest::copyFileToOtherPartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString filePath = homeTmpDir() + "fileFromHome";
+ const TQString dest = otherTmpDir() + "fileFromHome_copied";
+ createTestFile( filePath );
+ copyLocalFile( filePath, dest );
+}
+
+void JobTest::copyDirectoryToOtherPartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString src = homeTmpDir() + "dirFromHome";
+ const TQString dest = otherTmpDir() + "dirFromHome_copied";
+ // src is already created by copyDirectoryToSamePartition()
+ // so this is just in case someone calls this method only
+ if ( !TQFile::exists( src ) )
+ createTestDirectory( src );
+ copyLocalDirectory( src, dest );
+}
+
+void JobTest::moveLocalFile( const TQString& src, const TQString& dest )
+{
+ assert( TQFile::exists( src ) );
+ KURL u;
+ u.setPath( src );
+ KURL d;
+ d.setPath( dest );
+
+ // move the file with file_move
+ bool ok = TDEIO::NetAccess::file_move( u, d );
+ assert( ok );
+ assert( TQFile::exists( dest ) );
+ assert( !TQFile::exists( src ) ); // not there anymore
+
+ // move it back with TDEIO::move()
+ ok = TDEIO::NetAccess::move( d, u, 0 );
+ assert( ok );
+ assert( !TQFile::exists( dest ) );
+ assert( TQFile::exists( src ) ); // it's back
+}
+
+static void moveLocalSymlink( const TQString& src, const TQString& dest )
+{
+ KDE_struct_stat buf;
+ assert ( KDE_lstat( TQFile::encodeName( src ), &buf ) == 0 );
+ KURL u;
+ u.setPath( src );
+ KURL d;
+ d.setPath( dest );
+
+ // move the symlink with move, NOT with file_move
+ bool ok = TDEIO::NetAccess::move( u, d );
+ if ( !ok )
+ kdWarning() << TDEIO::NetAccess::lastError() << endl;
+ assert( ok );
+ assert ( KDE_lstat( TQFile::encodeName( dest ), &buf ) == 0 );
+ assert( !TQFile::exists( src ) ); // not there anymore
+
+ // move it back with TDEIO::move()
+ ok = TDEIO::NetAccess::move( d, u, 0 );
+ assert( ok );
+ assert ( KDE_lstat( TQFile::encodeName( dest ), &buf ) != 0 ); // doesn't exist anymore
+ assert ( KDE_lstat( TQFile::encodeName( src ), &buf ) == 0 ); // it's back
+}
+
+void JobTest::moveLocalDirectory( const TQString& src, const TQString& dest )
+{
+ assert( TQFile::exists( src ) );
+ assert( TQFileInfo( src ).isDir() );
+ assert( TQFileInfo( src + "/testfile" ).isFile() );
+ assert( TQFileInfo( src + "/testlink" ).isSymLink() );
+ KURL u;
+ u.setPath( src );
+ KURL d;
+ d.setPath( dest );
+
+ bool ok = TDEIO::NetAccess::move( u, d, 0 );
+ assert( ok );
+ assert( TQFile::exists( dest ) );
+ assert( TQFileInfo( dest ).isDir() );
+ assert( TQFileInfo( dest + "/testfile" ).isFile() );
+ assert( !TQFile::exists( src ) ); // not there anymore
+
+ assert( TQFileInfo( dest + "/testlink" ).isSymLink() );
+}
+
+void JobTest::moveFileToSamePartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString filePath = homeTmpDir() + "fileFromHome";
+ const TQString dest = homeTmpDir() + "fileFromHome_moved";
+ createTestFile( filePath );
+ moveLocalFile( filePath, dest );
+}
+
+void JobTest::moveDirectoryToSamePartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString src = homeTmpDir() + "dirFromHome";
+ const TQString dest = homeTmpDir() + "dirFromHome_moved";
+ createTestDirectory( src );
+ moveLocalDirectory( src, dest );
+}
+
+void JobTest::moveFileToOtherPartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString filePath = homeTmpDir() + "fileFromHome";
+ const TQString dest = otherTmpDir() + "fileFromHome_moved";
+ createTestFile( filePath );
+ moveLocalFile( filePath, dest );
+}
+
+void JobTest::moveSymlinkToOtherPartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString filePath = homeTmpDir() + "testlink";
+ const TQString dest = otherTmpDir() + "testlink_moved";
+ createTestSymlink( filePath );
+ moveLocalSymlink( filePath, dest );
+}
+
+void JobTest::moveDirectoryToOtherPartition()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString src = homeTmpDir() + "dirFromHome";
+ const TQString dest = otherTmpDir() + "dirFromHome_moved";
+ createTestDirectory( src );
+ moveLocalDirectory( src, dest );
+}
+
+void JobTest::moveFileNoPermissions()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString src = "/etc/passwd";
+ const TQString dest = homeTmpDir() + "passwd";
+ assert( TQFile::exists( src ) );
+ assert( TQFileInfo( src ).isFile() );
+ KURL u;
+ u.setPath( src );
+ KURL d;
+ d.setPath( dest );
+
+ TDEIO::CopyJob* job = TDEIO::move( u, d, 0 );
+ job->setInteractive( false ); // no skip dialog, thanks
+ TQMap<TQString, TQString> metaData;
+ bool ok = TDEIO::NetAccess::synchronousRun( job, 0, 0, 0, &metaData );
+ assert( !ok );
+ assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_ACCESS_DENIED );
+ // OK this is fishy. Just like mv(1), KIO's behavior depends on whether
+ // a direct rename(2) was used, or a full copy+del. In the first case
+ // there is no destination file created, but in the second case the
+ // destination file remains.
+ // In fact we assume /home is a separate partition, in this test, so:
+ assert( TQFile::exists( dest ) );
+ assert( TQFile::exists( src ) );
+}
+
+void JobTest::moveDirectoryNoPermissions()
+{
+ kdDebug() << k_funcinfo << endl;
+ const TQString src = "/etc/init.d";
+ const TQString dest = homeTmpDir() + "init.d";
+ assert( TQFile::exists( src ) );
+ assert( TQFileInfo( src ).isDir() );
+ KURL u;
+ u.setPath( src );
+ KURL d;
+ d.setPath( dest );
+
+ TDEIO::CopyJob* job = TDEIO::move( u, d, 0 );
+ job->setInteractive( false ); // no skip dialog, thanks
+ TQMap<TQString, TQString> metaData;
+ bool ok = TDEIO::NetAccess::synchronousRun( job, 0, 0, 0, &metaData );
+ assert( !ok );
+ assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_ACCESS_DENIED );
+ assert( TQFile::exists( dest ) ); // see moveFileNoPermissions
+ assert( TQFile::exists( src ) );
+}
+
+void JobTest::listRecursive()
+{
+ const TQString src = homeTmpDir();
+ KURL u;
+ u.setPath( src );
+ TDEIO::ListJob* job = TDEIO::listRecursive( u );
+ connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ),
+ TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) );
+ bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
+ assert( ok );
+ m_names.sort();
+ check( "listRecursive", m_names.join( "," ), ".,..,"
+ "dirFromHome,dirFromHome/testfile,dirFromHome/testlink,dirFromHome_copied,"
+ "dirFromHome_copied/dirFromHome,dirFromHome_copied/dirFromHome/testfile,dirFromHome_copied/dirFromHome/testlink,"
+ "dirFromHome_copied/testfile,dirFromHome_copied/testlink,"
+ "fileFromHome,fileFromHome_copied" );
+}
+
+void JobTest::slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& lst )
+{
+ for( TDEIO::UDSEntryList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
+ TDEIO::UDSEntry::ConstIterator it2 = (*it).begin();
+ TQString displayName;
+ KURL url;
+ for( ; it2 != (*it).end(); it2++ ) {
+ switch ((*it2).m_uds) {
+ case TDEIO::UDS_NAME:
+ displayName = (*it2).m_str;
+ break;
+ case TDEIO::UDS_URL:
+ url = (*it2).m_str;
+ break;
+ }
+ }
+ m_names.append( displayName );
+ }
+}
+
+void JobTest::copyFileToSystem()
+{
+ if ( !KProtocolInfo::isKnownProtocol( TQString::fromLatin1( "system" ) ) ) {
+ kdDebug() << k_funcinfo << "no kio_system, skipping test" << endl;
+ return;
+ }
+
+ // First test with support for UDS_LOCAL_PATH
+ copyFileToSystem( true );
+
+ TQString dest = realSystemPath() + "fileFromHome_copied";
+ TQFile::remove( dest );
+
+ // Then disable support for UDS_LOCAL_PATH, i.e. test what would
+ // happen for ftp, smb, http etc.
+ copyFileToSystem( false );
+}
+
+void JobTest::copyFileToSystem( bool resolve_local_urls )
+{
+ kdDebug() << k_funcinfo << resolve_local_urls << endl;
+ extern TDEIO_EXPORT bool kio_resolve_local_urls;
+ kio_resolve_local_urls = resolve_local_urls;
+
+ const TQString src = homeTmpDir() + "fileFromHome";
+ createTestFile( src );
+ KURL u;
+ u.setPath( src );
+ KURL d = systemTmpDir();
+ d.addPath( "fileFromHome_copied" );
+
+ kdDebug() << "copying " << u << " to " << d << endl;
+
+ // copy the file with file_copy
+ TDEIO::FileCopyJob* job = TDEIO::file_copy( u, d );
+ connect( job, TQT_SIGNAL(mimetype(TDEIO::Job*,const TQString&)),
+ this, TQT_SLOT(slotMimetype(TDEIO::Job*,const TQString&)) );
+ bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
+ assert( ok );
+
+ TQString dest = realSystemPath() + "fileFromHome_copied";
+
+ assert( TQFile::exists( dest ) );
+ assert( TQFile::exists( src ) ); // still there
+
+ {
+ // do NOT check that the timestamp is the same.
+ // It can't work with file_copy when it uses the datapump,
+ // unless we use setModificationTime in the app code.
+ }
+
+ // Check mimetype
+ kdDebug() << m_mimetype << endl;
+ // There's no mimemagic determination in kio_file in trinity. Fixing this for kde4...
+ assert( m_mimetype == "application/octet-stream" );
+ //assert( m_mimetype == "text/plain" );
+
+ // cleanup and retry with TDEIO::copy()
+ TQFile::remove( dest );
+ ok = TDEIO::NetAccess::dircopy( u, d, 0 );
+ assert( ok );
+ assert( TQFile::exists( dest ) );
+ assert( TQFile::exists( src ) ); // still there
+ {
+ // check that the timestamp is the same (#79937)
+ TQFileInfo srcInfo( src );
+ TQFileInfo destInfo( dest );
+ assert( srcInfo.lastModified() == destInfo.lastModified() );
+ }
+
+ // restore normal behavior
+ kio_resolve_local_urls = true;
+}
+
+void JobTest::slotMimetype(TDEIO::Job* job, const TQString& type)
+{
+ assert( job );
+ m_mimetype = type;
+}
+
+#include "jobtest.moc"