Add initial integration test famework and IMAP client session tests
This commit is contained in:
parent
3b3e0b03d1
commit
cddbb28a43
4 changed files with 283 additions and 3 deletions
53
test/README.md
Normal file
53
test/README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
Automated Test Infrastructure
|
||||
=============================
|
||||
|
||||
Geary currently supports three types of automated tests:
|
||||
|
||||
* Engine unit tests
|
||||
* Client (GTK and JavaScript) unit tests
|
||||
* Server integration tests
|
||||
|
||||
Unit tests
|
||||
----------
|
||||
|
||||
Unit tests test individual functions, in general avoid doing any I/O
|
||||
so they are fast, and can be run automatically.
|
||||
|
||||
The engine and client unit tests are hooked up to the Meson build, so
|
||||
you can use Meson's test infrastructure to build and run them. These
|
||||
are run automatically as part of the Gitlab CI process and if you use
|
||||
the development Makefile, you can execute them locally by simply
|
||||
calling:
|
||||
|
||||
make test
|
||||
|
||||
The engine tests can be run headless (i.e. without an X11 or Wayland
|
||||
session), but the client tests require a functioning display since
|
||||
they execute GTK code.
|
||||
|
||||
Integration tests
|
||||
-----------------
|
||||
|
||||
Integration tests run Geary's network code against actual servers, to
|
||||
ensure that the code also works in the real world.
|
||||
|
||||
The integration tests are built by default, but not currently hooked
|
||||
up to Meson and are not automatically run by Gitlab CI, since they
|
||||
require multiple working servers, network connection to the servers,
|
||||
and login credentials.
|
||||
|
||||
You can run them manually however against any server you have a test
|
||||
account on, using the following form:
|
||||
|
||||
build/test/test-integration PROTOCOL PROVIDER [HOSTNAME] LOGIN PASSWORD
|
||||
|
||||
For example, to test against GMail's IMAP service:
|
||||
|
||||
build/test/test-integration imap gmail test@gmail.com p455w04d
|
||||
|
||||
If `PROVIDER` is `other`, then `HOSTNAME` is required.
|
||||
|
||||
The easiest way to test against a number of different servers at the
|
||||
moment is to create a test account for each, then write a shell script
|
||||
or similar to execute the tests against each in turn.
|
||||
99
test/integration/imap/client-session.vala
Normal file
99
test/integration/imap/client-session.vala
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2019 Michael Gratton <mike@vee.net>
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
class Integration.Imap.ClientSession : TestCase {
|
||||
|
||||
|
||||
private Configuration config;
|
||||
private Geary.Imap.ClientSession? session;
|
||||
|
||||
|
||||
public ClientSession(Configuration config) {
|
||||
base("Integration.Imap.ClientSession");
|
||||
this.config = config;
|
||||
add_test("session_connect", session_connect);
|
||||
|
||||
add_test("login_password_invalid", login_password_invalid);
|
||||
if (config.provider == GMAIL ||
|
||||
config.provider == OUTLOOK) {
|
||||
add_test("login_oauth2_invalid", login_oauth2_invalid);
|
||||
}
|
||||
|
||||
add_test("initiate_session", initiate_session);
|
||||
}
|
||||
|
||||
public override void set_up() {
|
||||
this.session = new Geary.Imap.ClientSession(
|
||||
this.config.target
|
||||
);
|
||||
}
|
||||
|
||||
public override void tear_down() throws GLib.Error {
|
||||
if (this.session.get_protocol_state(null) != UNCONNECTED) {
|
||||
this.session.disconnect_async.begin(null, async_complete_full);
|
||||
this.session.disconnect_async.end(async_result());
|
||||
}
|
||||
this.session = null;
|
||||
}
|
||||
|
||||
public void session_connect() throws GLib.Error {
|
||||
this.session.connect_async.begin(null, async_complete_full);
|
||||
this.session.connect_async.end(async_result());
|
||||
|
||||
this.session.disconnect_async.begin(null, async_complete_full);
|
||||
this.session.disconnect_async.end(async_result());
|
||||
}
|
||||
|
||||
public void login_password_invalid() throws GLib.Error {
|
||||
do_connect();
|
||||
|
||||
Geary.Credentials password_creds = new Geary.Credentials(
|
||||
PASSWORD, "automated-integration-test", "password"
|
||||
);
|
||||
this.session.login_async.begin(
|
||||
password_creds, null, async_complete_full
|
||||
);
|
||||
try {
|
||||
this.session.login_async.end(async_result());
|
||||
assert_not_reached();
|
||||
} catch (Geary.ImapError.UNAUTHENTICATED err) {
|
||||
// All good
|
||||
}
|
||||
}
|
||||
|
||||
public void login_oauth2_invalid() throws GLib.Error {
|
||||
do_connect();
|
||||
|
||||
Geary.Credentials oauth2_creds = new Geary.Credentials(
|
||||
OAUTH2, "automated-integration-test", "password"
|
||||
);
|
||||
this.session.login_async.begin(
|
||||
oauth2_creds, null, async_complete_full
|
||||
);
|
||||
try {
|
||||
this.session.login_async.end(async_result());
|
||||
assert_not_reached();
|
||||
} catch (Geary.ImapError.UNAUTHENTICATED err) {
|
||||
// All good
|
||||
}
|
||||
}
|
||||
|
||||
public void initiate_session() throws GLib.Error {
|
||||
do_connect();
|
||||
|
||||
this.session.initiate_session_async.begin(
|
||||
this.config.credentials, null, async_complete_full
|
||||
);
|
||||
this.session.initiate_session_async.end(async_result());
|
||||
}
|
||||
|
||||
private void do_connect() throws GLib.Error {
|
||||
this.session.connect_async.begin(null, async_complete_full);
|
||||
this.session.connect_async.end(async_result());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -87,6 +87,12 @@ geary_test_client_sources = [
|
|||
geary_resources
|
||||
]
|
||||
|
||||
geary_test_integration_sources = [
|
||||
'test-integration.vala',
|
||||
|
||||
'integration/imap/client-session.vala',
|
||||
]
|
||||
|
||||
geary_test_lib_dependencies = [
|
||||
gee,
|
||||
gio,
|
||||
|
|
@ -103,7 +109,7 @@ geary_test_client_dependencies = [
|
|||
]
|
||||
geary_test_client_dependencies += geary_client_dependencies
|
||||
|
||||
geary_test_lib = static_library('geary-test-lib',
|
||||
geary_test_lib = static_library('test-lib',
|
||||
geary_test_lib_sources,
|
||||
dependencies: geary_test_lib_dependencies,
|
||||
include_directories: config_h_dir,
|
||||
|
|
@ -111,7 +117,7 @@ geary_test_lib = static_library('geary-test-lib',
|
|||
c_args: geary_c_options,
|
||||
)
|
||||
|
||||
geary_test_engine_bin = executable('geary-test-engine',
|
||||
geary_test_engine_bin = executable('test-engine',
|
||||
geary_test_engine_sources,
|
||||
link_with: geary_test_lib,
|
||||
dependencies: geary_test_engine_dependencies,
|
||||
|
|
@ -120,7 +126,7 @@ geary_test_engine_bin = executable('geary-test-engine',
|
|||
c_args: geary_c_options,
|
||||
)
|
||||
|
||||
geary_test_client_bin = executable('geary-test-client',
|
||||
geary_test_client_bin = executable('test-client',
|
||||
geary_test_client_sources,
|
||||
dependencies: geary_test_client_dependencies,
|
||||
link_with: geary_test_lib,
|
||||
|
|
@ -129,5 +135,20 @@ geary_test_client_bin = executable('geary-test-client',
|
|||
c_args: geary_c_options,
|
||||
)
|
||||
|
||||
geary_test_integration_bin = executable('test-integration',
|
||||
geary_test_integration_sources,
|
||||
dependencies: [
|
||||
geary_engine_dep,
|
||||
gee,
|
||||
gio,
|
||||
gmime,
|
||||
webkit2gtk,
|
||||
],
|
||||
link_with: geary_test_lib,
|
||||
include_directories: config_h_dir,
|
||||
vala_args: geary_vala_options,
|
||||
c_args: geary_c_options,
|
||||
)
|
||||
|
||||
test('engine-tests', geary_test_engine_bin)
|
||||
test('client-tests', geary_test_client_bin)
|
||||
|
|
|
|||
107
test/test-integration.vala
Normal file
107
test/test-integration.vala
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright 2019 Michael Gratton <mike@vee.net>
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
|
||||
private const int TIMEOUT = 5;
|
||||
|
||||
|
||||
public struct Integration.Configuration {
|
||||
|
||||
Geary.Protocol type;
|
||||
Geary.ServiceProvider provider;
|
||||
Geary.ServiceInformation service;
|
||||
Geary.Endpoint target;
|
||||
Geary.Credentials credentials;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(string[] args) {
|
||||
/*
|
||||
* Initialise all the things.
|
||||
*/
|
||||
|
||||
Test.init(ref args);
|
||||
|
||||
Geary.RFC822.init();
|
||||
Geary.HTML.init();
|
||||
Geary.Logging.init();
|
||||
Geary.Logging.log_to(stderr);
|
||||
GLib.Log.set_default_handler(Geary.Logging.default_handler);
|
||||
|
||||
Integration.Configuration config = load_config(args);
|
||||
|
||||
/*
|
||||
* Hook up all tests into appropriate suites
|
||||
*/
|
||||
|
||||
TestSuite integration = new TestSuite("integration");
|
||||
|
||||
switch (config.type) {
|
||||
case IMAP:
|
||||
integration.add_suite(
|
||||
new Integration.Imap.ClientSession(config).get_suite()
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the tests
|
||||
*/
|
||||
TestSuite root = TestSuite.get_root();
|
||||
root.add_suite(integration);
|
||||
|
||||
MainLoop loop = new MainLoop();
|
||||
|
||||
int ret = -1;
|
||||
Idle.add(() => {
|
||||
ret = Test.run();
|
||||
loop.quit();
|
||||
return false;
|
||||
});
|
||||
|
||||
loop.run();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Integration.Configuration load_config(string[] args) {
|
||||
int i = 1;
|
||||
try {
|
||||
Geary.Protocol type = Geary.Protocol.for_value(args[i++]);
|
||||
Geary.ServiceProvider provider = Geary.ServiceProvider.for_value(
|
||||
args[i++]
|
||||
);
|
||||
Geary.ServiceInformation service = new Geary.ServiceInformation(
|
||||
type, provider
|
||||
);
|
||||
|
||||
if (provider == OTHER) {
|
||||
service.host = args[i++];
|
||||
service.port = service.get_default_port();
|
||||
}
|
||||
|
||||
Geary.Credentials credentials = new Geary.Credentials(
|
||||
PASSWORD, args[i++], args[i++]
|
||||
);
|
||||
|
||||
provider.set_service_defaults(service);
|
||||
|
||||
Geary.Endpoint target = new Geary.Endpoint(
|
||||
new NetworkAddress(service.host, service.port),
|
||||
service.transport_security,
|
||||
TIMEOUT
|
||||
);
|
||||
|
||||
return { type, provider, service, target, credentials };
|
||||
} catch (GLib.Error err) {
|
||||
error(
|
||||
"Error loading config: %s",
|
||||
(new Geary.ErrorContext(err)).format_full_error()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue