Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
d778af3b
Commit
d778af3b
authored
Oct 05, 2010
by
Christian Kandeler
Browse files
SSH: Finish Implementing SFTP test.
parent
3d90463d
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/plugins/coreplugin/ssh/sshconnection.cpp
View file @
d778af3b
...
...
@@ -160,12 +160,16 @@ SshConnection::~SshConnection()
QSharedPointer
<
SshRemoteProcess
>
SshConnection
::
createRemoteProcess
(
const
QByteArray
&
command
)
{
// TODO: Is this conditonal return value really a good idea?
// Get rid of this IF we can prove that no harm is done by returning
// a non-working (but non-null) process pointer.
return
state
()
==
Connected
?
d
->
createRemoteProcess
(
command
)
:
QSharedPointer
<
SshRemoteProcess
>
();
}
QSharedPointer
<
SftpChannel
>
SshConnection
::
createSftpChannel
()
{
// TODO: See above
return
state
()
==
Connected
?
d
->
createSftpChannel
()
:
QSharedPointer
<
SftpChannel
>
();
}
...
...
tests/manual/ssh/main.cpp
deleted
100644 → 0
View file @
3d90463d
#include <coreplugin/ssh/sftpchannel.h>
#include <coreplugin/ssh/sshconnection.h>
#include <coreplugin/ssh/sshremoteprocess.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QPair>
#include <QtCore/QTimer>
using
namespace
Core
;
class
Test
:
public
QObject
{
Q_OBJECT
public:
Test
()
{
m_timeoutTimer
.
setSingleShot
(
true
);
m_connection
=
SshConnection
::
create
();
if
(
m_connection
->
state
()
!=
SshConnection
::
Unconnected
)
{
qDebug
(
"Error: Newly created SSH connection has state %d."
,
m_connection
->
state
());
}
if
(
m_connection
->
createRemoteProcess
(
""
))
qDebug
(
"Error: Unconnected SSH connection creates remote process."
);
if
(
m_connection
->
createSftpChannel
())
qDebug
(
"Error: Unconnected SSH connection creates SFTP channel."
);
SshConnectionParameters
noHost
;
noHost
.
host
=
QLatin1String
(
"hgdfxgfhgxfhxgfchxgcf"
);
noHost
.
port
=
12345
;
noHost
.
timeout
=
10
;
SshConnectionParameters
noUser
;
noUser
.
host
=
QLatin1String
(
"localhost"
);
noUser
.
port
=
22
;
noUser
.
timeout
=
30
;
noUser
.
authType
=
SshConnectionParameters
::
AuthByPwd
;
noUser
.
uname
=
QLatin1String
(
"dumdidumpuffpuff"
);
noUser
.
uname
=
QLatin1String
(
"whatever"
);
SshConnectionParameters
wrongPwd
;
wrongPwd
.
host
=
QLatin1String
(
"localhost"
);
wrongPwd
.
port
=
22
;
wrongPwd
.
timeout
=
30
;
wrongPwd
.
authType
=
SshConnectionParameters
::
AuthByPwd
;
wrongPwd
.
uname
=
QLatin1String
(
"root"
);
noUser
.
uname
=
QLatin1String
(
"thiscantpossiblybeapasswordcanit"
);
SshConnectionParameters
invalidKeyFile
;
invalidKeyFile
.
host
=
QLatin1String
(
"localhost"
);
invalidKeyFile
.
port
=
22
;
invalidKeyFile
.
timeout
=
30
;
invalidKeyFile
.
authType
=
SshConnectionParameters
::
AuthByKey
;
invalidKeyFile
.
uname
=
QLatin1String
(
"root"
);
invalidKeyFile
.
privateKeyFile
=
QLatin1String
(
"somefilenamethatwedontexpecttocontainavalidkey"
);
// TODO: Create a valid key file and check for authentication error.
m_testSet
<<
TestItem
(
"Behavior with non-existing host"
,
noHost
,
ErrorList
()
<<
SshSocketError
);
m_testSet
<<
TestItem
(
"Behavior with non-existing user"
,
noUser
,
ErrorList
()
<<
SshSocketError
<<
SshTimeoutError
<<
SshAuthenticationError
);
m_testSet
<<
TestItem
(
"Behavior with wrong password"
,
wrongPwd
,
ErrorList
()
<<
SshSocketError
<<
SshTimeoutError
<<
SshAuthenticationError
);
m_testSet
<<
TestItem
(
"Behavior with invalid key file"
,
invalidKeyFile
,
ErrorList
()
<<
SshSocketError
<<
SshTimeoutError
<<
SshKeyFileError
);
runNextTest
();
}
~
Test
();
private
slots
:
void
handleConnected
()
{
qDebug
(
"Error: Received unexpected connected() signal."
);
qApp
->
quit
();
}
void
handleDisconnected
()
{
qDebug
(
"Error: Received unexpected disconnected() signal."
);
qApp
->
quit
();
}
void
handleDataAvailable
(
const
QString
&
msg
)
{
qDebug
(
"Error: Received unexpected dataAvailable() signal. "
"Message was: '%s'."
,
qPrintable
(
msg
));
qApp
->
quit
();
}
void
handleError
(
SshError
error
)
{
if
(
m_testSet
.
isEmpty
())
{
qDebug
(
"Error: Received error %d, but no test was running."
,
error
);
qApp
->
quit
();
}
const
TestItem
testItem
=
m_testSet
.
takeFirst
();
if
(
testItem
.
allowedErrors
.
contains
(
error
))
{
qDebug
(
"Received error %d, as expected."
,
error
);
if
(
m_testSet
.
isEmpty
())
{
qDebug
(
"All tests finished successfully."
);
qApp
->
quit
();
}
else
{
runNextTest
();
}
}
else
{
qDebug
(
"Received unexpected error %d."
,
error
);
qApp
->
quit
();
}
}
void
handleTimeout
()
{
if
(
m_testSet
.
isEmpty
())
{
qDebug
(
"Error: timeout, but no test was running."
);
qApp
->
quit
();
}
const
TestItem
testItem
=
m_testSet
.
takeFirst
();
qDebug
(
"Error: The following test timed out: %s"
,
testItem
.
description
);
}
private:
void
runNextTest
()
{
if
(
m_connection
)
disconnect
(
m_connection
.
data
(),
0
,
this
,
0
);
m_connection
=
SshConnection
::
create
();
connect
(
m_connection
.
data
(),
SIGNAL
(
connected
()),
this
,
SLOT
(
handleConnected
()));
connect
(
m_connection
.
data
(),
SIGNAL
(
disconnected
()),
this
,
SLOT
(
handleDisconnected
()));
connect
(
m_connection
.
data
(),
SIGNAL
(
dataAvailable
(
QString
)),
this
,
SLOT
(
handleDataAvailable
(
QString
)));
connect
(
m_connection
.
data
(),
SIGNAL
(
error
(
SshError
)),
this
,
SLOT
(
handleError
(
SshError
)));
const
TestItem
&
nextItem
=
m_testSet
.
first
();
m_timeoutTimer
.
stop
();
m_timeoutTimer
.
setInterval
(
qMax
(
10000
,
nextItem
.
params
.
timeout
*
1000
));
qDebug
(
"Testing: %s"
,
nextItem
.
description
);
m_connection
->
connectToHost
(
m_testSet
.
first
().
params
);
}
SshConnection
::
Ptr
m_connection
;
typedef
QList
<
SshError
>
ErrorList
;
struct
TestItem
{
TestItem
(
const
char
*
d
,
const
SshConnectionParameters
&
p
,
const
ErrorList
&
e
)
:
description
(
d
),
params
(
p
),
allowedErrors
(
e
)
{}
const
char
*
description
;
SshConnectionParameters
params
;
ErrorList
allowedErrors
;
};
QList
<
TestItem
>
m_testSet
;
QTimer
m_timeoutTimer
;
};
Test
::~
Test
()
{}
int
main
(
int
argc
,
char
*
argv
[])
{
QCoreApplication
a
(
argc
,
argv
);
Test
t
;
return
a
.
exec
();
}
#include "main.moc"
tests/manual/ssh/sftp/sftptest.cpp
View file @
d778af3b
...
...
@@ -80,7 +80,7 @@ void SftpTest::handleDisconnected()
void
SftpTest
::
handleError
()
{
std
::
cerr
<<
"Encountered SSH error "
std
::
cerr
<<
"Encountered SSH error
:
"
<<
qPrintable
(
m_connection
->
errorString
())
<<
"."
<<
std
::
endl
;
qApp
->
quit
();
}
...
...
@@ -103,7 +103,7 @@ void SftpTest::handleChannelInitialized()
const
FilePtr
file
(
new
QFile
(
QDir
::
tempPath
()
+
QLatin1Char
(
'/'
)
+
fileName
));
bool
success
=
true
;
if
(
!
file
->
open
(
QIODevice
::
Read
Write
|
QIODevice
::
Truncate
))
if
(
!
file
->
open
(
QIODevice
::
Write
Only
|
QIODevice
::
Truncate
))
success
=
false
;
if
(
success
)
{
int
content
[
1024
/
sizeof
(
int
)];
...
...
@@ -153,16 +153,12 @@ void SftpTest::handleChannelClosed()
std
::
cerr
<<
"Unexpected state "
<<
m_state
<<
" in function "
<<
Q_FUNC_INFO
<<
"."
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"SFTP channel closed. Now disconnecting."
<<
std
::
endl
;
std
::
cout
<<
"SFTP channel closed. Now disconnecting.
..
"
<<
std
::
endl
;
}
m_state
=
Disconnecting
;
m_connection
->
disconnectFromHost
();
}
// compare the original to the downloaded files
// remove local files
// remove remote files
// then the same for a big N GB file
void
SftpTest
::
handleJobFinished
(
Core
::
SftpJobId
job
,
const
QString
&
error
)
{
switch
(
m_state
)
{
...
...
@@ -170,7 +166,7 @@ void SftpTest::handleJobFinished(Core::SftpJobId job, const QString &error)
if
(
!
handleJobFinished
(
job
,
m_smallFilesUploadJobs
,
error
,
"uploading"
))
return
;
if
(
m_smallFilesUploadJobs
.
isEmpty
())
{
std
::
cout
<<
"Uploading finished, now downloading for comparison."
std
::
cout
<<
"Uploading finished, now downloading for comparison.
..
"
<<
std
::
endl
;
foreach
(
const
FilePtr
&
file
,
m_localSmallFiles
)
{
const
QString
localFilePath
=
file
->
fileName
();
...
...
@@ -195,7 +191,7 @@ void SftpTest::handleJobFinished(Core::SftpJobId job, const QString &error)
if
(
!
handleJobFinished
(
job
,
m_smallFilesDownloadJobs
,
error
,
"downloading"
))
return
;
if
(
m_smallFilesDownloadJobs
.
isEmpty
())
{
std
::
cout
<<
"Downloading finished, now comparing."
<<
std
::
endl
;
std
::
cout
<<
"Downloading finished, now comparing.
..
"
<<
std
::
endl
;
foreach
(
const
FilePtr
&
ptr
,
m_localSmallFiles
)
{
if
(
!
ptr
->
open
(
QIODevice
::
ReadOnly
))
{
std
::
cerr
<<
"Error opening local file "
...
...
@@ -215,7 +211,7 @@ void SftpTest::handleJobFinished(Core::SftpJobId job, const QString &error)
return
;
}
std
::
cout
<<
"Comparisons successful, now removing files."
std
::
cout
<<
"Comparisons successful, now removing files.
..
"
<<
std
::
endl
;
QList
<
QString
>
remoteFilePaths
;
foreach
(
const
FilePtr
&
ptr
,
m_localSmallFiles
)
{
...
...
@@ -245,22 +241,135 @@ void SftpTest::handleJobFinished(Core::SftpJobId job, const QString &error)
if
(
!
handleJobFinished
(
job
,
m_smallFilesRemovalJobs
,
error
,
"removing"
))
return
;
if
(
m_smallFilesRemovalJobs
.
isEmpty
())
{
// TODO: create and upload big file
std
::
cout
<<
"Files successfully removed. "
<<
"Now closing the SFTP channel."
<<
std
::
endl
;
m_channel
->
closeChannel
();
m_state
=
ChannelClosing
;
std
::
cout
<<
"Small files successfully removed. "
<<
"Now creating big file..."
<<
std
::
endl
;
const
QLatin1String
bigFileName
(
"sftpbigfile"
);
m_localBigFile
=
FilePtr
(
new
QFile
(
QDir
::
tempPath
()
+
QLatin1Char
(
'/'
)
+
bigFileName
));
bool
success
=
m_localBigFile
->
open
(
QIODevice
::
WriteOnly
);
const
int
blockSize
=
8192
;
const
int
blockCount
=
m_parameters
.
bigFileSize
*
1024
*
1024
/
blockSize
;
for
(
int
block
=
0
;
block
<
blockCount
;
++
block
)
{
int
content
[
blockSize
/
sizeof
(
int
)];
for
(
size_t
j
=
0
;
j
<
sizeof
content
/
sizeof
content
[
0
];
++
j
)
content
[
j
]
=
qrand
();
m_localBigFile
->
write
(
reinterpret_cast
<
char
*>
(
content
),
sizeof
content
);
}
m_localBigFile
->
close
();
success
=
success
&&
m_localBigFile
->
error
()
==
QFile
::
NoError
;
if
(
!
success
)
{
std
::
cerr
<<
"Error trying to create big file '"
<<
qPrintable
(
m_localBigFile
->
fileName
())
<<
"'."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
std
::
cout
<<
"Big file created. Now uploading ..."
<<
std
::
endl
;
m_bigJobTimer
.
start
();
m_bigFileUploadJob
=
m_channel
->
uploadFile
(
m_localBigFile
->
fileName
(),
remoteFilePath
(
bigFileName
),
SftpOverwriteExisting
);
if
(
m_bigFileUploadJob
==
SftpInvalidJob
)
{
std
::
cerr
<<
"Error uploading file '"
<<
bigFileName
.
latin1
()
<<
"'."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
m_state
=
UploadingBig
;
}
break
;
case
UploadingBig
:
{
if
(
!
handleBigJobFinished
(
job
,
m_bigFileUploadJob
,
error
,
"uploading"
))
return
;
const
qint64
msecs
=
m_bigJobTimer
.
elapsed
();
std
::
cout
<<
"Successfully uploaded big file. Took "
<<
(
msecs
/
1000
)
<<
" seconds for "
<<
m_parameters
.
bigFileSize
<<
" MB."
<<
std
::
endl
;
const
QString
localFilePath
=
m_localBigFile
->
fileName
();
const
QString
downloadedFilePath
=
cmpFileName
(
localFilePath
);
const
QString
remoteFp
=
remoteFilePath
(
QFileInfo
(
localFilePath
).
fileName
());
std
::
cout
<<
"Now downloading big file for comparison..."
<<
std
::
endl
;
m_bigJobTimer
.
start
();
m_bigFileDownloadJob
=
m_channel
->
downloadFile
(
remoteFp
,
downloadedFilePath
,
SftpOverwriteExisting
);
if
(
m_bigFileDownloadJob
==
SftpInvalidJob
)
{
std
::
cerr
<<
"Error downloading remote file '"
<<
qPrintable
(
remoteFp
)
<<
"' to local file '"
<<
qPrintable
(
downloadedFilePath
)
<<
"'."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
m_state
=
DownloadingBig
;
break
;
}
case
DownloadingBig
:
{
if
(
!
handleBigJobFinished
(
job
,
m_bigFileDownloadJob
,
error
,
"downloading"
))
return
;
const
qint64
msecs
=
m_bigJobTimer
.
elapsed
();
std
::
cout
<<
"Successfully downloaded big file. Took "
<<
(
msecs
/
1000
)
<<
" seconds for "
<<
m_parameters
.
bigFileSize
<<
" MB."
<<
std
::
endl
;
std
::
cout
<<
"Now comparing big files..."
<<
std
::
endl
;
QFile
downloadedFile
(
cmpFileName
(
m_localBigFile
->
fileName
()));
if
(
!
downloadedFile
.
open
(
QIODevice
::
ReadOnly
))
{
std
::
cerr
<<
"Error opening downloaded file '"
<<
qPrintable
(
downloadedFile
.
fileName
())
<<
"': "
<<
qPrintable
(
downloadedFile
.
errorString
())
<<
"."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
if
(
!
m_localBigFile
->
open
(
QIODevice
::
ReadOnly
))
{
std
::
cerr
<<
"Error opening big file '"
<<
qPrintable
(
m_localBigFile
->
fileName
())
<<
"': "
<<
qPrintable
(
m_localBigFile
->
errorString
())
<<
"."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
if
(
!
compareFiles
(
m_localBigFile
.
data
(),
&
downloadedFile
))
return
;
std
::
cout
<<
"Comparison successful. Now removing big files..."
<<
std
::
endl
;
if
(
!
m_localBigFile
->
remove
())
{
std
::
cerr
<<
"Error: Could not remove file '"
<<
qPrintable
(
m_localBigFile
->
fileName
())
<<
"'."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
if
(
!
downloadedFile
.
remove
())
{
std
::
cerr
<<
"Error: Could not remove file '"
<<
qPrintable
(
downloadedFile
.
fileName
())
<<
"'."
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
;
}
const
QString
remoteFp
=
remoteFilePath
(
QFileInfo
(
m_localBigFile
->
fileName
()).
fileName
());
m_bigFileRemovalJob
=
m_channel
->
removeFile
(
remoteFp
);
m_state
=
RemovingBig
;
break
;
}
case
RemovingBig
:
{
if
(
!
handleBigJobFinished
(
job
,
m_bigFileRemovalJob
,
error
,
"removing"
))
return
;
const
QString
remoteFp
=
remoteFilePath
(
QFileInfo
(
m_localBigFile
->
fileName
()).
fileName
());
std
::
cout
<<
"Big files successfully removed. "
<<
"Now closing the SFTP channel..."
<<
std
::
endl
;
m_state
=
ChannelClosing
;
m_channel
->
closeChannel
();
break
;
}
case
Disconnecting
:
break
;
case
UploadingBig
:
case
DownloadingBig
:
case
RemovingBig
:
default:
std
::
cerr
<<
"Unexpected state "
<<
m_state
<<
" in function "
<<
Q_FUNC_INFO
<<
"."
<<
std
::
endl
;
earlyDisconnectFromHost
();
if
(
!
m_error
)
{
std
::
cerr
<<
"Unexpected state "
<<
m_state
<<
" in function "
<<
Q_FUNC_INFO
<<
"."
<<
std
::
endl
;
earlyDisconnectFromHost
();
}
}
}
...
...
@@ -324,13 +433,34 @@ bool SftpTest::handleJobFinished(SftpJobId job, JobMap &jobMap,
return
true
;
}
bool
SftpTest
::
handleBigJobFinished
(
SftpJobId
job
,
SftpJobId
expectedJob
,
const
QString
&
error
,
const
char
*
activity
)
{
if
(
job
!=
expectedJob
)
{
std
::
cerr
<<
"Error "
<<
activity
<<
" file '"
<<
qPrintable
(
m_localBigFile
->
fileName
())
<<
"': Expected job id "
<<
expectedJob
<<
", got job id "
<<
job
<<
'.'
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
false
;
}
if
(
!
error
.
isEmpty
())
{
std
::
cerr
<<
"Error "
<<
activity
<<
" file '"
<<
qPrintable
(
m_localBigFile
->
fileName
())
<<
"': "
<<
qPrintable
(
error
)
<<
std
::
endl
;
earlyDisconnectFromHost
();
return
false
;
}
return
true
;
}
bool
SftpTest
::
compareFiles
(
QFile
*
orig
,
QFile
*
copy
)
{
bool
success
=
orig
->
size
()
==
copy
->
size
();
qint64
bytesLeft
=
orig
->
size
();
orig
->
seek
(
0
);
while
(
success
&&
bytesLeft
>
0
)
{
const
qint64
bytesToRead
=
qMin
(
bytesLeft
,
Q_INT64_C
(
6
4
*
1024
));
const
qint64
bytesToRead
=
qMin
(
bytesLeft
,
Q_INT64_C
(
102
4
*
1024
));
const
QByteArray
origBlock
=
orig
->
read
(
bytesToRead
);
const
QByteArray
copyBlock
=
copy
->
read
(
bytesToRead
);
if
(
origBlock
.
size
()
!=
bytesToRead
||
origBlock
!=
copyBlock
)
...
...
tests/manual/ssh/sftp/sftptest.h
View file @
d778af3b
...
...
@@ -6,6 +6,7 @@
#include <coreplugin/ssh/sftpchannel.h>
#include <coreplugin/ssh/sshconnection.h>
#include <QtCore/QElapsedTimer>
#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QObject>
...
...
@@ -45,6 +46,8 @@ private:
void
earlyDisconnectFromHost
();
bool
handleJobFinished
(
Core
::
SftpJobId
job
,
JobMap
&
jobMap
,
const
QString
&
error
,
const
char
*
activity
);
bool
handleBigJobFinished
(
Core
::
SftpJobId
job
,
Core
::
SftpJobId
expectedJob
,
const
QString
&
error
,
const
char
*
activity
);
bool
compareFiles
(
QFile
*
orig
,
QFile
*
copy
);
const
Parameters
m_parameters
;
...
...
@@ -60,6 +63,7 @@ private:
Core
::
SftpJobId
m_bigFileUploadJob
;
Core
::
SftpJobId
m_bigFileDownloadJob
;
Core
::
SftpJobId
m_bigFileRemovalJob
;
QElapsedTimer
m_bigJobTimer
;
};
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment