diff options
Diffstat (limited to 'tests/unit/mongo')
87 files changed, 5165 insertions, 0 deletions
diff --git a/tests/unit/mongo/client/connect.c b/tests/unit/mongo/client/connect.c new file mode 100644 index 0000000..fc390ea --- /dev/null +++ b/tests/unit/mongo/client/connect.c @@ -0,0 +1,34 @@ +#include "test.h" +#include "tap.h" +#include "mongo-client.h" + +#include <errno.h> + +void +test_mongo_connect (void) +{ + mongo_connection *c; + + ok (mongo_connect (NULL, 27010) == NULL, + "mongo_connect() fails with a NULL host"); + ok (errno == EINVAL, + "mongo_connect() should fail with EINVAL if host is NULL"); + + begin_network_tests (4); + + ok (mongo_connect ("invalid.example.com", 27017) == NULL, + "Connecting to an invalid host fails"); + ok (mongo_connect ("example.com", 27017) == NULL, + "Connecting to an unavailable host/port fails"); + ok (mongo_connect ("/does/not/exist.sock", MONGO_CONN_LOCAL) == NULL, + "Connecting to an unavailable unix socket fails"); + + ok ((c = mongo_connect (config.primary_host, + config.primary_port)) != NULL, + "Connecting to the primary server works"); + mongo_disconnect (c); + + end_network_tests (); +} + +RUN_TEST (6, mongo_connect); diff --git a/tests/unit/mongo/client/connection_get_requestid.c b/tests/unit/mongo/client/connection_get_requestid.c new file mode 100644 index 0000000..9232689 --- /dev/null +++ b/tests/unit/mongo/client/connection_get_requestid.c @@ -0,0 +1,44 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_connection_get_requestid (void) +{ + mongo_connection c, *conn; + mongo_packet *p; + bson *b; + gint reqid; + + c.request_id = 42; + + ok (mongo_connection_get_requestid (NULL) == -1, + "mongo_connection_get_requestid() fails with a NULL connection"); + ok (mongo_connection_get_requestid (&c) == 42, + "mongo_connection_get_requestid() works"); + + begin_network_tests (2); + + b = bson_new (); + bson_append_int32 (b, "getnonce", 1); + bson_finish (b); + + p = mongo_wire_cmd_custom (42, config.db, 0, b); + bson_free (b); + + conn = mongo_connect (config.primary_host, config.primary_port); + cmp_ok ((reqid = mongo_connection_get_requestid (conn)), "==", 0, + "Initial request id is 0"); + mongo_packet_send (conn, p); + mongo_wire_packet_free (p); + + cmp_ok (reqid, "<", mongo_connection_get_requestid (conn), + "Old request ID is smaller than the new one"); + + mongo_disconnect (conn); + + end_network_tests (); +} + +RUN_TEST (4, mongo_connection_get_requestid); diff --git a/tests/unit/mongo/client/connection_set_timeout.c b/tests/unit/mongo/client/connection_set_timeout.c new file mode 100644 index 0000000..02468bf --- /dev/null +++ b/tests/unit/mongo/client/connection_set_timeout.c @@ -0,0 +1,33 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_connection_set_timeout (void) +{ + mongo_connection c, *conn; + + c.fd = -1; + + ok (mongo_connection_set_timeout (NULL, 100) == FALSE, + "mongo_connection_set_timeout() should fail with a NULL connection"); + ok (mongo_connection_set_timeout (&c, -1) == FALSE, + "mongo_connection_set_timeout() should fail with a negative timeout"); + ok (mongo_connection_set_timeout (&c, 100) == FALSE, + "mongo_connection_set_timeout() should fail with an invalid FD"); + + begin_network_tests (0); + + conn = mongo_connect (config.primary_host, config.primary_port); + + /* No verification here, as some systems may or may not support + this, thus, failing in a test is not fatal. */ + mongo_connection_set_timeout (conn, 100); + + mongo_disconnect (conn); + + end_network_tests (); +} + +RUN_TEST (3, mongo_connection_set_timeout); diff --git a/tests/unit/mongo/client/disconnect.c b/tests/unit/mongo/client/disconnect.c new file mode 100644 index 0000000..1b0be93 --- /dev/null +++ b/tests/unit/mongo/client/disconnect.c @@ -0,0 +1,32 @@ +#include "test.h" +#include "tap.h" +#include "mongo-client.h" + +#include "libmongo-private.h" +#include <errno.h> + +void +test_mongo_disconnect (void) +{ + mongo_connection *conn; + + conn = g_new0 (mongo_connection, 1); + conn->fd = -1; + + errno = 0; + mongo_disconnect (NULL); + ok (errno == ENOTCONN, + "mongo_disconnect() fails with ENOTCONN when passed a NULL connection"); + + mongo_disconnect (conn); + ok (errno == 0, + "mongo_disconnect() works"); + + conn = g_new0 (mongo_connection, 1); + conn->fd = 100; + mongo_disconnect (conn); + ok (errno == 0, + "mongo_disconnect() works, even with a bogus FD"); +} + +RUN_TEST (3, mongo_disconnect); diff --git a/tests/unit/mongo/client/packet_recv.c b/tests/unit/mongo/client/packet_recv.c new file mode 100644 index 0000000..51ccb3d --- /dev/null +++ b/tests/unit/mongo/client/packet_recv.c @@ -0,0 +1,56 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> +#include <sys/socket.h> + +#include "libmongo-private.h" + +void +test_mongo_packet_recv (void) +{ + mongo_connection c, *conn; + mongo_packet *p; + bson *b; + + c.fd = -1; + + ok (mongo_packet_recv (NULL) == NULL, + "mongo_packet_recv() fails with a NULL connection"); + ok (errno == ENOTCONN, + "mongo_packet_recv() sets errno to ENOTCONN if connection is NULL"); + + ok (mongo_packet_recv (&c) == NULL, + "mongo_packet_recv() fails if the FD is less than zero"); + ok (errno == EBADF, + "mongo_packet_recv() sets errno to EBADF is the FD is bad"); + + begin_network_tests (2); + + b = bson_new (); + bson_append_int32 (b, "getnonce", 1); + bson_finish (b); + + p = mongo_wire_cmd_custom (42, config.db, 0, b); + bson_free (b); + + conn = mongo_connect (config.primary_host, config.primary_port); + mongo_packet_send (conn, p); + mongo_wire_packet_free (p); + + ok ((p = mongo_packet_recv (conn)) != NULL, + "mongo_packet_recv() works"); + mongo_wire_packet_free (p); + + close (conn->fd); + sleep (3); + + ok (mongo_packet_recv (conn) == NULL, + "mongo_packet_recv() fails on a closed socket"); + + mongo_disconnect (conn); + + end_network_tests (); +} + +RUN_TEST (6, mongo_packet_recv); diff --git a/tests/unit/mongo/client/packet_send.c b/tests/unit/mongo/client/packet_send.c new file mode 100644 index 0000000..e501a3c --- /dev/null +++ b/tests/unit/mongo/client/packet_send.c @@ -0,0 +1,75 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" +#include "mongo-client.h" + +#include <errno.h> +#include <sys/socket.h> + +#include "libmongo-private.h" + +void +test_mongo_packet_send (void) +{ + mongo_packet *p; + mongo_connection c, *conn; + mongo_packet_header h; + bson *b; + + p = mongo_wire_cmd_kill_cursors (1, 2, (gint64)3, (gint64)4); + c.fd = -1; + + ok (mongo_packet_send (NULL, p) == FALSE, + "mongo_packet_send() fails with a NULL connection"); + ok (errno == ENOTCONN, + "mongo_packet_send() with a NULL connection sets errno to ENOTCONN"); + ok (mongo_packet_send (&c, NULL) == FALSE, + "mongo_packet_send() fails with a NULL packet"); + ok (errno == EINVAL, + "mongo_packet_send() with a NULL packet sets errno to EINVAL"); + ok (mongo_packet_send (&c, p) == FALSE, + "mongo_packet_send() fails if the FD is less than zero"); + ok (errno == EBADF, + "mongo_packet_send() sets errno to EBADF is the FD is bad"); + mongo_wire_packet_free (p); + + p = mongo_wire_packet_new (); + + h.id = 42; + h.resp_to = 0; + h.opcode = 1; + h.length = sizeof (mongo_packet_header); + mongo_wire_packet_set_header (p, &h); + + c.fd = 1; + ok (mongo_packet_send (&c, p) == FALSE, + "mongo_packet_send() fails with an unfinished packet"); + + mongo_wire_packet_free (p); + + begin_network_tests (2); + + b = bson_new (); + bson_append_int32 (b, "getnonce", 1); + bson_finish (b); + + p = mongo_wire_cmd_custom (42, config.db, 0, b); + bson_free (b); + + conn = mongo_connect (config.primary_host, config.primary_port); + ok (mongo_packet_send (conn, p), + "mongo_packet_send() works"); + + close (conn->fd); + sleep (3); + + ok (mongo_packet_send (conn, p) == FALSE, + "mongo_packet_send() fails on a closed socket"); + mongo_wire_packet_free (p); + + mongo_disconnect (conn); + + end_network_tests (); +} + +RUN_TEST (9, mongo_packet_send); diff --git a/tests/unit/mongo/sync-cursor/sync_cursor_free.c b/tests/unit/mongo/sync-cursor/sync_cursor_free.c new file mode 100644 index 0000000..bd01cb5 --- /dev/null +++ b/tests/unit/mongo/sync-cursor/sync_cursor_free.c @@ -0,0 +1,34 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include "libmongo-private.h" + +#include <errno.h> + +void +test_mongo_sync_cursor_free (void) +{ + mongo_sync_connection *conn; + mongo_packet *p; + mongo_sync_cursor *c; + + test_env_setup (); + + p = mongo_wire_packet_new (); + conn = test_make_fake_sync_conn (-1, FALSE); + + c = mongo_sync_cursor_new (conn, config.ns, p); + + errno = 0; + mongo_sync_cursor_free (NULL); + ok (errno == ENOTCONN, + "mongo_sync_cursor_free(NULL) sets errno to ENOTCONN"); + mongo_sync_cursor_free (c); + pass ("mongo_sync_cursor_free() works"); + + mongo_sync_disconnect (conn); + test_env_free (); +} + +RUN_TEST (2, mongo_sync_cursor_free); diff --git a/tests/unit/mongo/sync-cursor/sync_cursor_get_data.c b/tests/unit/mongo/sync-cursor/sync_cursor_get_data.c new file mode 100644 index 0000000..0dd391c --- /dev/null +++ b/tests/unit/mongo/sync-cursor/sync_cursor_get_data.c @@ -0,0 +1,51 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include "libmongo-private.h" + +#include <errno.h> + +void +test_mongo_sync_cursor_get_data (void) +{ + mongo_sync_connection *conn; + mongo_packet *p; + bson *b; + mongo_sync_cursor *c; + + test_env_setup (); + + p = test_mongo_wire_generate_reply (TRUE, 4, TRUE); + conn = test_make_fake_sync_conn (-1, FALSE); + + c = mongo_sync_cursor_new (conn, config.ns, p); + + errno = 0; + b = mongo_sync_cursor_get_data (NULL); + ok (b == NULL && errno == EINVAL, + "mongo_sync_cursor_get_data(NULL) should fail"); + + b = mongo_sync_cursor_get_data (c); + ok (b == NULL, + "mongo_sync_cursor_get_data() should fail without _cursor_next()"); + + mongo_sync_cursor_next (c); + b = mongo_sync_cursor_get_data (c); + ok (b != NULL, + "mongo_sync_cursor_get_data() works"); + + c->offset = 5; + + errno = 0; + b = mongo_sync_cursor_get_data (c); + ok (b == NULL && errno == ERANGE, + "mongo_sync_cursor_get_data() should fail if the cursor is " + "out of range"); + + mongo_sync_cursor_free (c); + mongo_sync_disconnect (conn); + test_env_free (); +} + +RUN_TEST (4, mongo_sync_cursor_get_data); diff --git a/tests/unit/mongo/sync-cursor/sync_cursor_new.c b/tests/unit/mongo/sync-cursor/sync_cursor_new.c new file mode 100644 index 0000000..642d826 --- /dev/null +++ b/tests/unit/mongo/sync-cursor/sync_cursor_new.c @@ -0,0 +1,40 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include "libmongo-private.h" + +#include <errno.h> + +void +test_mongo_sync_cursor_new (void) +{ + mongo_sync_connection *conn; + mongo_packet *p; + mongo_sync_cursor *c; + + test_env_setup (); + + p = mongo_wire_packet_new (); + conn = test_make_fake_sync_conn (-1, FALSE); + + c = mongo_sync_cursor_new (conn, config.ns, NULL); + ok (c == NULL, + "mongo_sync_cursor_new() fails with a NULL packet"); + c = mongo_sync_cursor_new (conn, NULL, p); + ok (c == NULL, + "mongo_sync_cursor_new() fails with a NULL namespace"); + c = mongo_sync_cursor_new (NULL, config.ns, p); + ok (c == NULL, + "mongo_sync_cursor_new() fails with a NULL connection"); + + c = mongo_sync_cursor_new (conn, config.ns, p); + ok (c != NULL, + "mongo_sync_cursor_new() works"); + + mongo_sync_cursor_free (c); + mongo_sync_disconnect (conn); + test_env_free (); +} + +RUN_TEST (4, mongo_sync_cursor_new); diff --git a/tests/unit/mongo/sync-cursor/sync_cursor_next.c b/tests/unit/mongo/sync-cursor/sync_cursor_next.c new file mode 100644 index 0000000..442df96 --- /dev/null +++ b/tests/unit/mongo/sync-cursor/sync_cursor_next.c @@ -0,0 +1,40 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include "libmongo-private.h" + +#include <errno.h> + +void +test_mongo_sync_cursor_next (void) +{ + mongo_sync_connection *conn; + mongo_packet *p; + mongo_sync_cursor *c; + gboolean r = TRUE; + gint i; + + test_env_setup (); + + p = test_mongo_wire_generate_reply (TRUE, 2, TRUE); + conn = test_make_fake_sync_conn (-1, FALSE); + + c = mongo_sync_cursor_new (conn, config.ns, p); + + ok (mongo_sync_cursor_next (NULL) == FALSE, + "mongo_sync_cursor_next() should fail with a NULL cursor"); + for (i = 0; i < 2; i++) + r &= mongo_sync_cursor_next (c); + + ok (r == TRUE, + "mongo_sync_cursor_next() works"); + ok (mongo_sync_cursor_next (c) == FALSE, + "mongo_sync_cursor_next() should fail past the end of the resultset"); + + mongo_sync_cursor_free (c); + mongo_sync_disconnect (conn); + test_env_free (); +} + +RUN_TEST (3, mongo_sync_cursor_next); diff --git a/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_cursor_get_chunk.c b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_cursor_get_chunk.c new file mode 100644 index 0000000..f16378a --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_cursor_get_chunk.c @@ -0,0 +1,15 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_gridfs_chunked_file_cursor_get_chunk (void) +{ + gint32 size; + + ok (mongo_sync_gridfs_chunked_file_cursor_get_chunk (NULL, &size) == NULL, + "mongo_sync_gridfs_file_cursor_get_chunk() fails with a NULL cursor"); +} + +RUN_TEST (1, mongo_sync_gridfs_chunked_file_cursor_get_chunk); diff --git a/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_cursor_new.c b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_cursor_new.c new file mode 100644 index 0000000..22210f8 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_cursor_new.c @@ -0,0 +1,19 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_gridfs_chunked_file_cursor_new (void) +{ + mongo_sync_gridfs_chunked_file f; + + ok (mongo_sync_gridfs_chunked_file_cursor_new (NULL, 0, 0) == NULL, + "mongo_sync_gridfs_file_cursor_new() fails with a NULL file"); + ok (mongo_sync_gridfs_chunked_file_cursor_new (&f, -1, 0) == NULL, + "mongo_sync_gridfs_file_cursor_new() fails with an invalid start position"); + ok (mongo_sync_gridfs_chunked_file_cursor_new (&f, 0, -1) == NULL, + "mongo_sync_gridfs_file_cursor_new() fails with an invalid max number"); +} + +RUN_TEST (3, mongo_sync_gridfs_chunked_file_cursor_new); diff --git a/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_free.c b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_free.c new file mode 100644 index 0000000..c9fddfa --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_free.c @@ -0,0 +1,16 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_gridfs_chunked_file_free (void) +{ + errno = 0; + mongo_sync_gridfs_chunked_file_free (NULL); + + cmp_ok (errno, "==", ENOTCONN, + "mongo_sync_gridfs_chunked_file_free() fails with a NULL file"); +} + +RUN_TEST (1, mongo_sync_gridfs_chunked_file_free); diff --git a/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_new_from_buffer.c b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_new_from_buffer.c new file mode 100644 index 0000000..ba3fa2e --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_file_new_from_buffer.c @@ -0,0 +1,71 @@ +#include "test.h" +#include "mongo.h" + +#define BUFFER_SIZE 256 * 1024 + 42 + +void +test_mongo_sync_gridfs_chunked_file_new_from_buffer (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + bson *metadata; + guint8 *buffer; + mongo_sync_gridfs_chunked_file *gfile; + + buffer = g_malloc (BUFFER_SIZE); + memset (buffer, 'a', BUFFER_SIZE); + + conn = test_make_fake_sync_conn (4, TRUE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + metadata = bson_build (BSON_TYPE_STRING, "filename", + "gridfs_file_new_from_buffer", -1, + BSON_TYPE_NONE); + bson_finish (metadata); + + ok (mongo_sync_gridfs_chunked_file_new_from_buffer (NULL, metadata, + buffer, BUFFER_SIZE) == FALSE, + "mongo_sync_gridfs_chunked_file_new_from_buffer() fails with a NULL GridFS"); + + mongo_sync_gridfs_free (gfs, TRUE); + + begin_network_tests (5); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + ok (mongo_sync_gridfs_chunked_file_new_from_buffer (gfs, metadata, + NULL, BUFFER_SIZE) == FALSE, + "mongo_sync_gridfs_chunked_file_new_from_buffer() fails with NULL data"); + + ok (mongo_sync_gridfs_chunked_file_new_from_buffer (gfs, metadata, + buffer, 0) == FALSE, + "mongo_sync_gridfs_chunked_file_new_from_buffer() fails with an invalid data size"); + + ok (mongo_sync_gridfs_chunked_file_new_from_buffer (gfs, metadata, buffer, + BUFFER_SIZE) == FALSE, + "mongo_sync_gridfs_chunked_file_new_from_buffer() fails with uninitialized OID"); + + mongo_util_oid_init (0); + + gfile = mongo_sync_gridfs_chunked_file_new_from_buffer (gfs, metadata, + buffer, BUFFER_SIZE); + ok (gfile != NULL, + "mongo_sync_gridfs_chunked_file_new_from_buffer() works with metadata"); + mongo_sync_gridfs_chunked_file_free (gfile); + + gfile = mongo_sync_gridfs_chunked_file_new_from_buffer (gfs, NULL, + buffer, BUFFER_SIZE); + ok (gfile != NULL, + "mongo_sync_gridfs_chunked_file_new_from_buffer() works without metadata"); + mongo_sync_gridfs_chunked_file_free (gfile); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (metadata); + g_free (buffer); +} + +RUN_TEST (6, mongo_sync_gridfs_chunked_file_new_from_buffer); diff --git a/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_find.c b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_find.c new file mode 100644 index 0000000..91514f9 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-chunk/sync_gridfs_chunked_find.c @@ -0,0 +1,38 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_gridfs_chunked_find (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + bson *query; + + query = bson_build (BSON_TYPE_STRING, "filename", "bogus-fn", -1, + BSON_TYPE_NONE); + bson_finish (query); + + ok (mongo_sync_gridfs_chunked_find (NULL, query) == NULL, + "mongo_sync_gridfs_chunked_find() fails with a NULL GridFS"); + + begin_network_tests (2); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + ok (mongo_sync_gridfs_chunked_find (gfs, NULL) == NULL, + "mongo_sync_gridfs_chunked_find() fails with a NULL query"); + + ok (mongo_sync_gridfs_chunked_find (gfs, query) == NULL, + "mongo_sync_gridfs_chunked_find() fails when the file is not found"); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (query); +} + +RUN_TEST (3, mongo_sync_gridfs_chunked_find); diff --git a/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_close.c b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_close.c new file mode 100644 index 0000000..3c8a7b3 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_close.c @@ -0,0 +1,41 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_gridfs_stream_close (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + mongo_sync_gridfs_stream *stream; + + mongo_util_oid_init (0); + + ok (mongo_sync_gridfs_stream_close (NULL) == FALSE, + "mongo_sync_gridfs_stream_close() fails with a NULL stream"); + + begin_network_tests (3); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + stream = mongo_sync_gridfs_stream_new (gfs, NULL); + ok (mongo_sync_gridfs_stream_close (stream) == TRUE, + "mongo_sync_gridfs_stream_close() works with a write stream"); + + stream = mongo_sync_gridfs_stream_new (gfs, NULL); + stream->file.type = LMC_GRIDFS_FILE_CHUNKED; + ok (mongo_sync_gridfs_stream_close (stream) == FALSE, + "mongo_sync_gridfs_stream_close() should fail with a chunked file"); + + stream->file.type = LMC_GRIDFS_FILE_STREAM_READER; + ok (mongo_sync_gridfs_stream_close (stream) == TRUE, + "mongo_sync_gridfs_stream_close() works with a read stream"); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); +} + +RUN_TEST (4, mongo_sync_gridfs_stream_close); diff --git a/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_find.c b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_find.c new file mode 100644 index 0000000..643a8b2 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_find.c @@ -0,0 +1,36 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_gridfs_stream_find (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + bson *query; + + query = bson_build (BSON_TYPE_STRING, "filename", "bogus-fn", -1, + BSON_TYPE_NONE); + bson_finish (query); + + ok (mongo_sync_gridfs_stream_find (NULL, query) == NULL, + "mongo_sync_gridfs_stream_find() should fail with a NULL connection"); + + begin_network_tests (2); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + ok (mongo_sync_gridfs_stream_find (gfs, NULL) == NULL, + "mongo_sync_gridfs_stream_find() fails with a NULL query"); + + ok (mongo_sync_gridfs_stream_find (gfs, query) == NULL, + "mongo_sync_gridfs_stream_find() fails if the file is not found"); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (query); +} + +RUN_TEST (3, mongo_sync_gridfs_stream_find); diff --git a/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_new.c b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_new.c new file mode 100644 index 0000000..75e4419 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_new.c @@ -0,0 +1,43 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_gridfs_stream_new (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + mongo_sync_gridfs_stream *stream; + bson *meta; + + mongo_util_oid_init (0); + + meta = bson_build (BSON_TYPE_STRING, "my-id", "sync_gridfs_stream_new", -1, + BSON_TYPE_NONE); + bson_finish (meta); + + ok (mongo_sync_gridfs_stream_new (NULL, meta) == FALSE, + "mongo_sync_gridfs_stream_new() should fail with a NULL connection"); + + begin_network_tests (2); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + stream = mongo_sync_gridfs_stream_new (gfs, NULL); + ok (stream != NULL, + "mongo_sync_gridfs_stream_new() works with NULL metadata"); + mongo_sync_gridfs_stream_close (stream); + + stream = mongo_sync_gridfs_stream_new (gfs, meta); + ok (stream != NULL, + "mongo_sync_gridfs_stream_new() works with metadata"); + mongo_sync_gridfs_stream_close (stream); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (meta); +} + +RUN_TEST (3, mongo_sync_gridfs_stream_new); diff --git a/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_read.c b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_read.c new file mode 100644 index 0000000..a53aa88 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_read.c @@ -0,0 +1,44 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_gridfs_stream_read (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + mongo_sync_gridfs_stream *stream; + guint8 buffer[4096]; + + mongo_util_oid_init (0); + + ok (mongo_sync_gridfs_stream_read (NULL, buffer, sizeof (buffer)) == -1, + "mongo_sync_gridfs_stream_read() should fail with a NULL connection"); + + begin_network_tests (3); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + stream = mongo_sync_gridfs_stream_new (gfs, NULL); + + ok (mongo_sync_gridfs_stream_read (stream, buffer, sizeof (buffer)) == -1, + "mongo-sync_gridfs_stream_read() should fail when the stream is " + "write-only"); + + stream->file.type = LMC_GRIDFS_FILE_STREAM_READER; + + ok (mongo_sync_gridfs_stream_read (stream, NULL, sizeof (buffer)) == -1, + "mongo_sync_gridfs_stream_read() should fail with a NULL buffer"); + ok (mongo_sync_gridfs_stream_read (stream, buffer, 0) == -1, + "mongo_sync_gridfs_stream_read() should fail with a 0 size"); + + mongo_sync_gridfs_stream_close (stream); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); +} + +RUN_TEST (4, mongo_sync_gridfs_stream_read); diff --git a/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_seek.c b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_seek.c new file mode 100644 index 0000000..49547bc --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_seek.c @@ -0,0 +1,65 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +#include <unistd.h> + +void +test_mongo_sync_gridfs_stream_seek (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + mongo_sync_gridfs_stream *stream; + + mongo_util_oid_init (0); + + ok (mongo_sync_gridfs_stream_seek (NULL, 0, SEEK_SET) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with a NULL stream"); + + begin_network_tests (8); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + stream = mongo_sync_gridfs_stream_new (gfs, NULL); + + ok (mongo_sync_gridfs_stream_seek (stream, 0, SEEK_SET) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with a write stream"); + + stream->file.type = LMC_GRIDFS_FILE_STREAM_READER; + + ok (mongo_sync_gridfs_stream_seek (stream, -1, SEEK_SET) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with SEEK_SET and a negative " + "position"); + + ok (mongo_sync_gridfs_stream_seek (stream, 10, SEEK_SET) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with SEEK_SET and a position " + "past EOF"); + + ok (mongo_sync_gridfs_stream_seek (stream, -1, SEEK_CUR) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with SEEK_CUR and a position " + "before the start"); + + ok (mongo_sync_gridfs_stream_seek (stream, 10, SEEK_CUR) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with SEEK_CUR and a position " + "past EOF"); + + ok (mongo_sync_gridfs_stream_seek (stream, 1, SEEK_END) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with SEEK_END and a position " + "past EOF"); + + ok (mongo_sync_gridfs_stream_seek (stream, -1, SEEK_END) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with SEEK_END and a position " + "before the start"); + + ok (mongo_sync_gridfs_stream_seek (stream, 0, 42) == FALSE, + "mongo_sync_gridfs_stream_seek() fails with an invalid whence"); + + mongo_sync_gridfs_stream_close (stream); + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); +} + +RUN_TEST (9, mongo_sync_gridfs_stream_seek); diff --git a/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_write.c b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_write.c new file mode 100644 index 0000000..562c7b4 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs-stream/sync_gridfs_stream_write.c @@ -0,0 +1,50 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_gridfs_stream_write (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + mongo_sync_gridfs_stream *stream; + bson *meta; + guint8 buffer[4096]; + + mongo_util_oid_init (0); + + meta = bson_build (BSON_TYPE_STRING, "my-id", "sync_gridfs_stream_write", -1, + BSON_TYPE_NONE); + bson_finish (meta); + + ok (mongo_sync_gridfs_stream_write (NULL, buffer, sizeof (buffer)) == FALSE, + "mongo_sync_gridfs_stream_write() should fail with a NULL connection"); + + begin_network_tests (4); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + stream = mongo_sync_gridfs_stream_new (gfs, meta); + + ok (mongo_sync_gridfs_stream_write (stream, NULL, sizeof (buffer)) == FALSE, + "mongo_sync_gridfs_stream_write() should fail with a NULL buffer"); + ok (mongo_sync_gridfs_stream_write (stream, buffer, 0) == FALSE, + "mongo_sync_gridfs_stream_write() should fail with 0 size"); + ok (mongo_sync_gridfs_stream_write (stream, buffer, sizeof (buffer)) == TRUE, + "mongo_sync_gridfs_stream_write() works"); + + stream->file.type = LMC_GRIDFS_FILE_STREAM_READER; + ok (mongo_sync_gridfs_stream_write (stream, buffer, sizeof (buffer)) == FALSE, + "mongo_sync_gridfs_stream_write() should fail with a read stream"); + + mongo_sync_gridfs_stream_close (stream); + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (meta); +} + +RUN_TEST (5, mongo_sync_gridfs_stream_write); diff --git a/tests/unit/mongo/sync-gridfs/sync_gridfs_file_get_metadata.c b/tests/unit/mongo/sync-gridfs/sync_gridfs_file_get_metadata.c new file mode 100644 index 0000000..2be34e5 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs/sync_gridfs_file_get_metadata.c @@ -0,0 +1,23 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_gridfs_file_get_metadata (void) +{ + ok (mongo_sync_gridfs_file_get_id (NULL) == NULL, + "mongo_sync_gridfs_file_get_id() fails with a NULL file"); + ok (mongo_sync_gridfs_file_get_length (NULL) == -1, + "mongo_sync_gridfs_file_get_length() fails with a NULL file"); + ok (mongo_sync_gridfs_file_get_chunk_size (NULL) == -1, + "mongo_sync_gridfs_file_get_chunk_size() fails with a NULL file"); + ok (mongo_sync_gridfs_file_get_md5 (NULL) == NULL, + "mongo_sync_gridfs_file_get_md5() fails with a NULL file"); + ok (mongo_sync_gridfs_file_get_date (NULL) == -1, + "mongo_sync_gridfs_file_get_date() fails with a NULL file"); + ok (mongo_sync_gridfs_file_get_metadata (NULL) == NULL, + "mongo_sync_gridfs_file_get_metadata() fails with a NULL file"); + ok (mongo_sync_gridfs_file_get_chunks (NULL) == -1, + "mongo_sync_gridfs_file_get_chunks() fails with a NULL file"); +} + +RUN_TEST (7, mongo_sync_gridfs_file_get_metadata); diff --git a/tests/unit/mongo/sync-gridfs/sync_gridfs_free.c b/tests/unit/mongo/sync-gridfs/sync_gridfs_free.c new file mode 100644 index 0000000..1c8c2d6 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs/sync_gridfs_free.c @@ -0,0 +1,35 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_gridfs_free (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + + errno = 0; + mongo_sync_gridfs_free (NULL, FALSE); + cmp_ok (errno, "==", ENOTCONN, + "mongo_sync_gridfs_free() with a NULL connection shall set errno"); + + begin_network_tests (2); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + + mongo_sync_gridfs_free (gfs, FALSE); + cmp_ok (errno, "==", 0, + "mongo_sync_gridfs_free() should clear errno on success"); + + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + mongo_sync_gridfs_free (gfs, TRUE); + cmp_ok (errno, "==", 0, + "mongo_sync_gridfs_free() works when asked to free the " + "connection too"); + + end_network_tests (); +} + +RUN_TEST (3, mongo_sync_gridfs_free); diff --git a/tests/unit/mongo/sync-gridfs/sync_gridfs_get_set_chunk_size.c b/tests/unit/mongo/sync-gridfs/sync_gridfs_get_set_chunk_size.c new file mode 100644 index 0000000..5d17986 --- /dev/null +++ b/tests/unit/mongo/sync-gridfs/sync_gridfs_get_set_chunk_size.c @@ -0,0 +1,33 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_gridfs_get_set_chunk_size (void) +{ + mongo_sync_gridfs *gfs; + + ok (mongo_sync_gridfs_get_chunk_size (NULL) == -1, + "mongo_sync_gridfs_get_chunk_size() fails with a NULL gfs"); + ok (mongo_sync_gridfs_set_chunk_size (NULL, 16 * 1024) == FALSE, + "mongo_sync_gridfs_set_chunk_size() fails with a NULL gfs"); + + begin_network_tests (3); + + gfs = mongo_sync_gridfs_new (mongo_sync_connect (config.primary_host, + config.primary_port, + FALSE), + config.gfs_prefix); + + ok (mongo_sync_gridfs_set_chunk_size (gfs, -1) == FALSE, + "mongo_sync_gridfs_set_chunk_size() fails if the size is invalid"); + ok (mongo_sync_gridfs_set_chunk_size (gfs, 12345), + "mongo_sync_gridfs_set_chunk_size() works"); + cmp_ok (mongo_sync_gridfs_get_chunk_size (gfs), "==", 12345, + "mongo_sync_gridfs_get_chunk_size() works"); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); +} + +RUN_TEST (5, mongo_sync_gridfs_get_set_chunk_size); diff --git a/tests/unit/mongo/sync-gridfs/sync_gridfs_list.c b/tests/unit/mongo/sync-gridfs/sync_gridfs_list.c new file mode 100644 index 0000000..e5857ea --- /dev/null +++ b/tests/unit/mongo/sync-gridfs/sync_gridfs_list.c @@ -0,0 +1,34 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_gridfs_list (void) +{ + mongo_sync_gridfs *gfs; + bson *query; + + query = bson_build (BSON_TYPE_STRING, "bogus-key", "bogus-value", -1, + BSON_TYPE_NONE); + bson_finish (query); + + ok (mongo_sync_gridfs_list (NULL, NULL) == NULL, + "mongo_sync_gridfs_list() fails with a NULL GridFS"); + + begin_network_tests (1); + + gfs = mongo_sync_gridfs_new + (mongo_sync_connect (config.primary_host, config.primary_port, FALSE), + config.gfs_prefix); + + ok (mongo_sync_gridfs_list (gfs, query) == NULL, + "mongo_sync_gridfs_list() fails with a query that does not match " + "anything"); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (query); +} + +RUN_TEST (2, mongo_sync_gridfs_list); diff --git a/tests/unit/mongo/sync-gridfs/sync_gridfs_new.c b/tests/unit/mongo/sync-gridfs/sync_gridfs_new.c new file mode 100644 index 0000000..20d6fea --- /dev/null +++ b/tests/unit/mongo/sync-gridfs/sync_gridfs_new.c @@ -0,0 +1,54 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_gridfs_new (void) +{ + mongo_sync_connection *conn; + mongo_sync_gridfs *gfs; + gchar *f, *c; + + conn = test_make_fake_sync_conn (4, TRUE); + + ok (mongo_sync_gridfs_new (NULL, "test.fs") == NULL, + "mongo_sync_gridfs_new() should fail with a NULL connection"); + + ok (mongo_sync_gridfs_new (conn, "test.fs") == NULL, + "mongo_sync_gridfs_new() should fail with a bogus connection"); + + ok (mongo_sync_gridfs_new (conn, NULL) == NULL, + "mongo_sync_gridfs_new() should fail with a NULL ns prefix"); + + ok (mongo_sync_gridfs_new (conn, "bogus") == NULL, + "mongo_sync_gridfs_new() should fail with a bogus ns prefix"); + + mongo_sync_disconnect (conn); + + begin_network_tests (4); + + f = g_strconcat (config.gfs_prefix, ".files", NULL); + c = g_strconcat (config.gfs_prefix, ".chunks", NULL); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + + gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix); + ok (gfs != NULL, + "mongo_sync_gridfs_new() works"); + is (gfs->ns.prefix, config.gfs_prefix, + "The namespace prefix is as specified"); + is (gfs->ns.files, f, + "The files namespace is correct"); + is (gfs->ns.chunks, c, + "The chunks namespace is correct"); + mongo_sync_gridfs_free (gfs, FALSE); + + mongo_sync_disconnect (conn); + + g_free (f); + g_free (c); + end_network_tests (); +} + +RUN_TEST (8, mongo_sync_gridfs_new); diff --git a/tests/unit/mongo/sync-gridfs/sync_gridfs_remove.c b/tests/unit/mongo/sync-gridfs/sync_gridfs_remove.c new file mode 100644 index 0000000..88eb40b --- /dev/null +++ b/tests/unit/mongo/sync-gridfs/sync_gridfs_remove.c @@ -0,0 +1,34 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_gridfs_remove (void) +{ + mongo_sync_gridfs *gfs; + bson *query; + + query = bson_build (BSON_TYPE_STRING, "bogus-key", "bogus-value", -1, + BSON_TYPE_NONE); + bson_finish (query); + + ok (mongo_sync_gridfs_remove (NULL, NULL) == FALSE, + "mongo_sync_gridfs_remove() fails with a NULL GridFS"); + + begin_network_tests (1); + + gfs = mongo_sync_gridfs_new + (mongo_sync_connect (config.primary_host, config.primary_port, FALSE), + config.gfs_prefix); + + ok (mongo_sync_gridfs_remove (gfs, query) == FALSE, + "mongo_sync_gridfs_remove() fails with a query that does not match " + "anything"); + + mongo_sync_gridfs_free (gfs, TRUE); + + end_network_tests (); + + bson_free (query); +} + +RUN_TEST (2, mongo_sync_gridfs_remove); diff --git a/tests/unit/mongo/sync-pool/sync_pool_free.c b/tests/unit/mongo/sync-pool/sync_pool_free.c new file mode 100644 index 0000000..5f64621 --- /dev/null +++ b/tests/unit/mongo/sync-pool/sync_pool_free.c @@ -0,0 +1,11 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_pool_free (void) +{ + mongo_sync_pool_free (NULL); + pass ("mongo_sync_pool_free(NULL) works"); +} + +RUN_TEST (1, mongo_sync_pool_free); diff --git a/tests/unit/mongo/sync-pool/sync_pool_new.c b/tests/unit/mongo/sync-pool/sync_pool_new.c new file mode 100644 index 0000000..b9758d2 --- /dev/null +++ b/tests/unit/mongo/sync-pool/sync_pool_new.c @@ -0,0 +1,19 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_pool_new (void) +{ + ok (mongo_sync_pool_new ("example.com", 27017, 0, 0) == NULL, + "mongo_sync_pool_new() needs at least one connection"); + ok (mongo_sync_pool_new (NULL, 27017, 1, 0) == NULL, + "mongo_sync_pool_new() should fail without a HOST"); + ok (mongo_sync_pool_new ("example.com", -1, 1, 0) == NULL, + "mongo_sync_pool_new() should fail with an invalid port"); + ok (mongo_sync_pool_new ("example.com", 27017, -1, 0) == NULL, + "mongo_sync_pool_new() should fail with an invalid number of masters"); + ok (mongo_sync_pool_new ("example.com", 27017, 10, -1) == NULL, + "mongo_sync_pool_new() should fail with an invalid number of slaves"); +} + +RUN_TEST (5, mongo_sync_pool_new); diff --git a/tests/unit/mongo/sync-pool/sync_pool_pick.c b/tests/unit/mongo/sync-pool/sync_pool_pick.c new file mode 100644 index 0000000..352ba04 --- /dev/null +++ b/tests/unit/mongo/sync-pool/sync_pool_pick.c @@ -0,0 +1,11 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_pool_pick (void) +{ + ok (mongo_sync_pool_pick (NULL, TRUE) == NULL, + "mongo_sync_pool_pick() should fail without a pool"); +} + +RUN_TEST (1, mongo_sync_pool_pick); diff --git a/tests/unit/mongo/sync-pool/sync_pool_return.c b/tests/unit/mongo/sync-pool/sync_pool_return.c new file mode 100644 index 0000000..d622ede --- /dev/null +++ b/tests/unit/mongo/sync-pool/sync_pool_return.c @@ -0,0 +1,22 @@ +#include "test.h" +#include "mongo.h" + +#include <string.h> +#include "libmongo-private.h" + +void +test_mongo_sync_pool_return (void) +{ + mongo_sync_pool_connection c; + void *pool; + + pool = g_malloc (1024); + + ok (mongo_sync_pool_return (NULL, &c) == FALSE, + "mongo_sync_pool_return() should fail without a pool"); + ok (mongo_sync_pool_return ((mongo_sync_pool *)pool, NULL) == FALSE, + "mongo_sync_pool_return() should fail without a connection"); + g_free (pool); +} + +RUN_TEST (2, mongo_sync_pool_return); diff --git a/tests/unit/mongo/sync/sync_cmd_authenticate.c b/tests/unit/mongo/sync/sync_cmd_authenticate.c new file mode 100644 index 0000000..a5c67cb --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_authenticate.c @@ -0,0 +1,112 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_authenticate_net_secondary (void) +{ + mongo_sync_connection *c; + + skip (!config.secondary_host, 4, + "Secondary server not configured"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + mongo_sync_cmd_is_master (c); + + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_authenticate() works"); + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "bad_pw") == FALSE, + "mongo_sync_cmd_authenticate() should fail with a bad password"); + ok (mongo_sync_cmd_authenticate (c, config.db, "xxx", "s3kr1+") == FALSE, + "mongo_sync_cmd_authenticate() should fail with a bad username"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_authenticate() automatically reconnects"); + + mongo_sync_disconnect (c); + + endskip; +} + +void +test_mongo_sync_cmd_authenticate_net (void) +{ + mongo_sync_connection *c; + + begin_network_tests (8); + + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+"); + + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_authenticate() works"); + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "bad_pw") == FALSE, + "mongo_sync_cmd_authenticate() should fail with a bad password"); + ok (mongo_sync_cmd_authenticate (c, config.db, "xxx", "s3kr1+") == FALSE, + "mongo_sync_cmd_authenticate() should fail with a bad username"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_authenticate() automatically reconnects"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_authenticate_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_authenticate (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_authenticate (NULL, "test", "test", + "s3kr1+") == FALSE, + "mongo_sync_cmd_authenticate() fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + errno = 0; + ok (mongo_sync_cmd_authenticate (c, NULL, "test", "s3kr1+") == FALSE, + "mongo_sync_cmd_authenticate() fails with a NULL db"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_authenticate (c, "test", NULL, "s3kr1+") == FALSE, + "mongo_sync_cmd_authenticate() fails with a NULL user"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_authenticate (c, "test", "test", NULL) == FALSE, + "mongo_sync_cmd_authenticate() fails with a NULL password"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + ok (mongo_sync_cmd_authenticate (c, "test", "test", + "s3kr1+") == FALSE, + "mongo_sync_cmd_authenticate() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_authenticate_net (); +} + +RUN_TEST (17, mongo_sync_cmd_authenticate); diff --git a/tests/unit/mongo/sync/sync_cmd_authenticate_cache.c b/tests/unit/mongo/sync/sync_cmd_authenticate_cache.c new file mode 100644 index 0000000..c0581b0 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_authenticate_cache.c @@ -0,0 +1,60 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_authenticate_cache (void) +{ + mongo_sync_conn_recovery_cache *cache; + mongo_sync_connection *c; + + begin_network_tests (8); + + cache = mongo_sync_conn_recovery_cache_new (); + mongo_sync_conn_recovery_cache_seed_add (cache, + config.primary_host, + config.primary_port); + + c = mongo_sync_connect_recovery_cache (cache, TRUE); + + mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+"); + + ok (mongo_sync_cmd_authenticate (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_authenticate() works"); + + mongo_sync_disconnect (c); + + ok ((cache->auth.db != NULL) && (strcmp (cache->auth.db, config.db) == 0), + "db is cached"); + + ok ((cache->auth.user != NULL) && (strcmp (cache->auth.user, "test") == 0), + "user is cached"); + + ok ((cache->auth.pw != NULL) && (strcmp (cache->auth.pw, "s3kr1+") == 0), + "pw is cached"); + + c = mongo_sync_connect_recovery_cache (cache, TRUE); + + ok (c->auth.db != NULL, "db is loaded from cache"); + + ok (c->auth.user != NULL, "username is loaded from cache"); + + ok (c->auth.pw != NULL, "password is loaded from cache"); + + ok (mongo_sync_cmd_authenticate (c, + c->auth.db, + c->auth.user, + c->auth.pw) == TRUE, + "mongo_sync_cmd_authenticate() works with cached auth. credentials"); + + mongo_sync_disconnect (c); + mongo_sync_conn_recovery_cache_free (cache); + + end_network_tests (); +} + +RUN_TEST (8, mongo_sync_cmd_authenticate_cache); diff --git a/tests/unit/mongo/sync/sync_cmd_count.c b/tests/unit/mongo/sync/sync_cmd_count.c new file mode 100644 index 0000000..2cb8645 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_count.c @@ -0,0 +1,119 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_count_net_secondary (void) +{ + mongo_sync_connection *conn; + bson *b; + gdouble d; + + skip (!config.secondary_host, 2, + "Secondary server not configured"); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_cmd_is_master (conn); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + b = bson_new (); + bson_append_string (b, "test-name", __FILE__, -1); + bson_finish (b); + + d = mongo_sync_cmd_count (conn, config.db, config.coll, b); + ok (d > 0, + "mongo_sync_cmd_count() works on the secondary too"); + + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + d = mongo_sync_cmd_count (conn, config.db, config.coll, b); + ok (d > 0, + "mongo_sync_cmd_count() automatically reconnects"); + + bson_free (b); + mongo_sync_disconnect (conn); + + endskip; +} + +void +test_mongo_sync_cmd_count_net (void) +{ + mongo_sync_connection *conn; + bson *b; + gdouble d; + gint i; + + begin_network_tests (4); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + b = bson_new (); + for (i = 0; i < 40; i++) + { + bson_reset (b); + bson_append_string (b, "test-name", __FILE__, -1); + bson_append_int32 (b, "seq", i); + bson_finish (b); + + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + } + bson_free (b); + + b = bson_new (); + bson_append_string (b, "test-name", __FILE__, -1); + bson_finish (b); + + d = mongo_sync_cmd_count (conn, config.db, config.coll, b); + ok (d > 0, + "mongo_sync_cmd_count() works"); + + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + d = mongo_sync_cmd_count (conn, config.db, config.coll, b); + ok (d > 0, + "mongo_sync_cmd_count() automatically reconnects"); + + bson_free (b); + mongo_sync_disconnect (conn); + + test_mongo_sync_cmd_count_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_count (void) +{ + mongo_sync_connection *c; + bson *b; + + c = test_make_fake_sync_conn (-1, FALSE); + b = test_bson_generate_full (); + + ok (mongo_sync_cmd_count (NULL, "test", "db", b) == -1, + "mongo_sync_cmd_count() fails with a NULL connection"); + ok (mongo_sync_cmd_count (c, NULL, "db", b) == -1, + "mongo_sync_cmd_count() fails with a NULL db"); + ok (mongo_sync_cmd_count (c, "test", NULL, b) == -1, + "mongo_sync_cmd_count() fails with a NULL collection"); + + ok (mongo_sync_cmd_count (c, "test", "db", b) == -1, + "mongo_sync_cmd_count() fails with a bogus FD"); + mongo_sync_conn_set_slaveok (c, TRUE); + ok (mongo_sync_cmd_count (c, "test", "db", b) == -1, + "mongo_sync_cmd_count() fails with a bogus FD"); + + bson_free (b); + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_count_net (); +} + +RUN_TEST (9, mongo_sync_cmd_count); diff --git a/tests/unit/mongo/sync/sync_cmd_create.c b/tests/unit/mongo/sync/sync_cmd_create.c new file mode 100644 index 0000000..c3334ea --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_create.c @@ -0,0 +1,78 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_create_net (void) +{ + mongo_sync_connection *conn; + gchar *cc; + + begin_network_tests (5); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + + cc = g_strconcat (config.coll, ".capped", NULL); + + mongo_sync_cmd_drop (conn, config.db, config.coll); + mongo_sync_cmd_drop (conn, config.db, cc); + + ok (mongo_sync_cmd_create (conn, config.db, config.coll, + MONGO_COLLECTION_DEFAULTS) == TRUE, + "mongo_sync_cmd_create() can create normal collections"); + mongo_sync_cmd_drop (conn, config.db, config.coll); + + ok (mongo_sync_cmd_create (conn, config.db, config.coll, + MONGO_COLLECTION_SIZED, + (gint64) 64 * 1024 * 10) == TRUE, + "mongo_sync_cmd_create() can create pre-allocated collections"); + + ok (mongo_sync_cmd_create (conn, config.db, cc, + MONGO_COLLECTION_CAPPED, (gint64) -1) == FALSE, + "mongo_sync_cmd_create() fails when trying to create a capped " + "collection with an invalid size"); + ok (mongo_sync_cmd_create (conn, config.db, cc, + MONGO_COLLECTION_CAPPED_MAX, + (gint64) (64 * 1024 * 10), (gint64) -1) == FALSE, + "mongo_sync_cmd_create() fails when trying to create a capped " + "collection with invalid max."); + ok (mongo_sync_cmd_create (conn, config.db, cc, + MONGO_COLLECTION_CAPPED_MAX | + MONGO_COLLECTION_AUTO_INDEX_ID, + (gint64)(64 * 1024 * 10), (gint64) 10) == TRUE, + "mongo_sync_cmd_create() can create capped collections"); + + mongo_sync_cmd_drop (conn, config.db, cc); + + g_free (cc); + mongo_sync_disconnect (conn); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_create (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + ok (mongo_sync_cmd_create (NULL, "test", "db", + MONGO_COLLECTION_DEFAULTS) == FALSE, + "mongo_sync_cmd_create() fails with a NULL connection"); + + ok (mongo_sync_cmd_create (c, NULL, "db", + MONGO_COLLECTION_DEFAULTS) == FALSE, + "mongo_sync_cmd_create() fails with a NULL db"); + ok (mongo_sync_cmd_create (c, "test", NULL, + MONGO_COLLECTION_DEFAULTS) == FALSE, + "mongo_sync_cmd_create() fails with a NULL collection"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_create_net (); +} + +RUN_TEST (8, mongo_sync_cmd_create); diff --git a/tests/unit/mongo/sync/sync_cmd_custom.c b/tests/unit/mongo/sync/sync_cmd_custom.c new file mode 100644 index 0000000..1bd3f01 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_custom.c @@ -0,0 +1,100 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_custom_net_secondary (void) +{ + mongo_sync_connection *conn; + bson *cmd; + mongo_packet *p; + + skip (!config.secondary_host, 1, + "Secondary server not configured"); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + cmd = bson_build (BSON_TYPE_INT32, "getnonce", 1, + BSON_TYPE_NONE); + bson_finish (cmd); + + p = mongo_sync_cmd_custom (conn, config.db, cmd); + ok (p != NULL, + "mongo_sync_cmd_custom() works on the secondary too"); + mongo_wire_packet_free (p); + + bson_free (cmd); + mongo_sync_disconnect (conn); + + endskip; +} + +void +test_mongo_sync_cmd_custom_net (void) +{ + mongo_sync_connection *conn; + bson *cmd; + mongo_packet *p; + + begin_network_tests (3); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_cmd_is_master (conn); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + cmd = bson_build (BSON_TYPE_INT32, "getnonce", 1, + BSON_TYPE_NONE); + bson_finish (cmd); + + p = mongo_sync_cmd_custom (conn, config.db, cmd); + ok (p != NULL, + "mongo_sync_cmd_custom() works"); + mongo_wire_packet_free (p); + + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + p = mongo_sync_cmd_custom (conn, config.db, cmd); + ok (p != NULL, + "mongo_sync_cmd_custom() automatically reconnects"); + mongo_wire_packet_free (p); + + bson_free (cmd); + mongo_sync_disconnect (conn); + + test_mongo_sync_cmd_custom_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_custom (void) +{ + mongo_sync_connection *c; + bson *cmd; + + c = test_make_fake_sync_conn (-1, FALSE); + cmd = bson_new (); + bson_append_int32 (cmd, "getnonce", 1); + bson_finish (cmd); + + ok (mongo_sync_cmd_custom (NULL, "test", cmd) == NULL, + "mongo_sync_cmd_custom() fails with a NULL connection"); + ok (mongo_sync_cmd_custom (c, NULL, cmd) == NULL, + "mongo_sync_cmd_custom() fails with a NULL namespace"); + + ok (mongo_sync_cmd_custom (c, "test", cmd) == NULL, + "mongo_sync_cmd_custom() fails with a bogus FD"); + mongo_sync_conn_set_slaveok (c, TRUE); + ok (mongo_sync_cmd_custom (c, "test", cmd) == NULL, + "mongo_sync_cmd_custom() fails with a bogus FD"); + + bson_free (cmd); + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_custom_net (); +} + +RUN_TEST (7, mongo_sync_cmd_custom); diff --git a/tests/unit/mongo/sync/sync_cmd_delete.c b/tests/unit/mongo/sync/sync_cmd_delete.c new file mode 100644 index 0000000..0c20ffe --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_delete.c @@ -0,0 +1,135 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_delete_net_secondary (void) +{ + mongo_sync_connection *conn; + bson *b; + GList *l; + + skip (!config.secondary_host, 2, + "Secondary server not configured"); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + + b = bson_new (); + bson_append_string (b, "unit-test", __FILE__, -1); + bson_append_boolean (b, "delete-me", TRUE); + bson_finish (b); + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + + mongo_sync_disconnect (conn); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + ok (mongo_sync_cmd_delete (conn, config.ns, 0, b) == TRUE, + "mongo_sync_cmd_delete() can reconnect to master"); + mongo_sync_disconnect (conn); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + mongo_sync_disconnect (conn); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + shutdown (conn->super.fd, SHUT_RDWR); + + l = conn->rs.hosts; + while (l) + { + g_free (l->data); + l = g_list_delete_link (l, l); + } + conn->rs.hosts = NULL; + + l = conn->rs.seeds; + while (l) + { + g_free (l->data); + l = g_list_delete_link (l, l); + } + conn->rs.seeds = NULL; + + sleep (3); + + ok (mongo_sync_cmd_delete (conn, config.ns, 0, b) == FALSE, + "mongo_sync_cmd_delete() fails if it can't reconnect to master"); + + mongo_sync_disconnect (conn); + bson_free (b); + + endskip; +} + +void +test_mongo_sync_cmd_delete_net (void) +{ + mongo_sync_connection *conn; + bson *b; + + begin_network_tests (4); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + b = bson_new (); + bson_append_string (b, "unit-test", __FILE__, -1); + bson_append_boolean (b, "delete-me", TRUE); + bson_finish (b); + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + + ok (mongo_sync_cmd_delete (conn, config.ns, 0, b) == TRUE, + "mongo_sync_cmd_delete() works"); + + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_delete (conn, config.ns, 0, b) == TRUE, + "mongo_sync_cmd_delete() automatically reconnects"); + + mongo_sync_disconnect (conn); + bson_free (b); + + test_mongo_sync_cmd_delete_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_delete (void) +{ + mongo_sync_connection *c; + bson *b; + + c = test_make_fake_sync_conn (-1, FALSE); + b = test_bson_generate_full (); + + ok (mongo_sync_cmd_delete (NULL, "test.ns", 0, b) == FALSE, + "mongo_sync_cmd_delete() fails with a NULL connection"); + ok (mongo_sync_cmd_delete (c, NULL, 0, b) == FALSE, + "mongo_sync_cmd_delete() fails with a NULL namespace"); + ok (mongo_sync_cmd_delete (c, "test.ns", 0, NULL) == FALSE, + "mongo_sync_cmd_delete() fails with a NULL selector"); + + ok (mongo_sync_cmd_delete (c, "test.ns", 0, b) == FALSE, + "mongo_sync_cmd_delete() fails with a bogus FD"); + + bson_free (b); + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_delete_net (); +} + +RUN_TEST (8, mongo_sync_cmd_delete); diff --git a/tests/unit/mongo/sync/sync_cmd_drop.c b/tests/unit/mongo/sync/sync_cmd_drop.c new file mode 100644 index 0000000..c7f9d9f --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_drop.c @@ -0,0 +1,93 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_drop_net_secondary (void) +{ + mongo_sync_connection *conn; + bson *b; + gboolean ret; + + skip (!config.secondary_host, 1, + "Secondary server not configured"); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + b = bson_build (BSON_TYPE_BOOLEAN, "filler", TRUE, + BSON_TYPE_NONE); + bson_finish (b); + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + bson_free (b); + mongo_sync_disconnect (conn); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_cmd_is_master (conn); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + ret = mongo_sync_cmd_drop (conn, config.db, config.coll); + ok (ret && mongo_sync_cmd_is_master (conn), + "mongo_sync_cmd_drop() can reconnect to master"); + mongo_sync_disconnect (conn); + + endskip; +} + +void +test_mongo_sync_cmd_drop_net (void) +{ + mongo_sync_connection *conn; + bson *b; + + begin_network_tests (3); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + b = bson_build (BSON_TYPE_BOOLEAN, "filler", TRUE, + BSON_TYPE_NONE); + bson_finish (b); + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + + ok (mongo_sync_cmd_drop (conn, config.db, config.coll) == TRUE, + "mongo_sync_cmd_drop() works"); + + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_drop (conn, config.db, config.coll) == TRUE, + "mongo_sync_cmd_drop() automatically reconnects"); + + bson_free (b); + mongo_sync_disconnect (conn); + + test_mongo_sync_cmd_drop_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_drop (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + ok (mongo_sync_cmd_drop (NULL, "test", "db") == FALSE, + "mongo_sync_cmd_drop() fails with a NULL connection"); + ok (mongo_sync_cmd_drop (c, NULL, "db") == FALSE, + "mongo_sync_cmd_drop() fails with a NULL db"); + + ok (mongo_sync_cmd_drop (c, "test", "db") == FALSE, + "mongo_sync_cmd_drop() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_drop_net (); +} + +RUN_TEST (6, mongo_sync_cmd_drop); diff --git a/tests/unit/mongo/sync/sync_cmd_exists.c b/tests/unit/mongo/sync/sync_cmd_exists.c new file mode 100644 index 0000000..f3c535f --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_exists.c @@ -0,0 +1,85 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_exists_net (void) +{ + mongo_sync_connection *conn; + gchar *cc, *ns; + + bson *r; + bson_cursor *c; + const gchar *str = NULL; + gboolean capped = FALSE; + + begin_network_tests (4); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); + + cc = g_strconcat (config.coll, ".capped", NULL); + + mongo_sync_cmd_drop (conn, config.db, config.coll); + mongo_sync_cmd_drop (conn, config.db, cc); + + mongo_sync_cmd_create (conn, config.db, config.coll, + MONGO_COLLECTION_DEFAULTS); + mongo_sync_cmd_create (conn, config.db, cc, + MONGO_COLLECTION_CAPPED, + (gint64) 64 * 1024 * 10); + + r = mongo_sync_cmd_exists (conn, config.db, config.coll); + c = bson_find (r, "name"); + bson_cursor_get_string (c, &str); + is (str, config.ns, + "mongo_sync_cmd_exists() works on normal collections"); + bson_cursor_find (c, "capped"); + bson_cursor_get_boolean (c, &capped); + cmp_ok (capped, "==", FALSE, + "mongo_sync_cmd_exists() returned correct info"); + bson_cursor_free (c); + bson_free (r); + + r = mongo_sync_cmd_exists (conn, config.db, cc); + ns = g_strconcat (config.db, ".", cc, NULL); + c = bson_find (r, "name"); + bson_cursor_get_string (c, &str); + is (str, ns, + "mongo_sync_cmd_exists() works on capped collections"); + bson_cursor_find (c, "capped"); + bson_cursor_get_boolean (c, &capped); + cmp_ok (capped, "==", FALSE, + "mongo_sync_cmd_exists() returned correct info"); + bson_cursor_free (c); + g_free (ns); + bson_free (r); + + mongo_sync_cmd_drop (conn, config.db, cc); + + g_free (cc); + mongo_sync_disconnect (conn); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_exists (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + ok (mongo_sync_cmd_exists (NULL, "test", "db") == NULL, + "mongo_sync_cmd_exists() fails with a NULL connection"); + ok (mongo_sync_cmd_exists (c, NULL, "db") == NULL, + "mongo_sync_cmd_exists() fails with a NULL db"); + ok (mongo_sync_cmd_exists (c, "test", NULL) == NULL, + "mongo_sync_cmd_exists() fails with a NULL collection"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_exists_net (); +} + +RUN_TEST (7, mongo_sync_cmd_exists); diff --git a/tests/unit/mongo/sync/sync_cmd_get_last_error.c b/tests/unit/mongo/sync/sync_cmd_get_last_error.c new file mode 100644 index 0000000..fef9f78 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_get_last_error.c @@ -0,0 +1,35 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_cmd_get_last_error (void) +{ + mongo_sync_connection *c; + gchar *error; + + test_env_setup (); + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_get_last_error (NULL, config.db, &error) == FALSE, + "mongo_sync_cmd_get_last_error() returns FALSE with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + ok (mongo_sync_cmd_get_last_error (c, NULL, &error) == FALSE, + "mongo_sync_cmd_get_last_error() fails with a NULL db"); + + errno = 0; + ok (mongo_sync_cmd_get_last_error (c, config.db, NULL) == FALSE, + "mongo_sync_cmd_get_last_error() fails with a NULL error destination"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + mongo_sync_disconnect (c); + test_env_free (); +} + +RUN_TEST (5, mongo_sync_cmd_get_last_error); diff --git a/tests/unit/mongo/sync/sync_cmd_get_last_error_full.c b/tests/unit/mongo/sync/sync_cmd_get_last_error_full.c new file mode 100644 index 0000000..505fd3d --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_get_last_error_full.c @@ -0,0 +1,35 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_cmd_get_last_error_full (void) +{ + mongo_sync_connection *c; + bson *error; + + test_env_setup (); + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_get_last_error_full (NULL, config.db, &error) == FALSE, + "mongo_sync_cmd_get_last_error_full() returns FALSE with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + ok (mongo_sync_cmd_get_last_error_full (c, NULL, &error) == FALSE, + "mongo_sync_cmd_get_last_error_full() fails with a NULL db"); + + errno = 0; + ok (mongo_sync_cmd_get_last_error_full (c, config.db, NULL) == FALSE, + "mongo_sync_cmd_get_last_error_full() fails with a NULL error destination"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + mongo_sync_disconnect (c); + test_env_free (); +} + +RUN_TEST (5, mongo_sync_cmd_get_last_error_full); diff --git a/tests/unit/mongo/sync/sync_cmd_get_more.c b/tests/unit/mongo/sync/sync_cmd_get_more.c new file mode 100644 index 0000000..18a2f97 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_get_more.c @@ -0,0 +1,135 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_get_more_net_secondary (void) +{ + mongo_packet *p; + mongo_sync_connection *conn; + bson *b; + + mongo_reply_packet_header rh; + gint64 cid; + + skip (!config.secondary_host, 2, + "Secondary server not configured"); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + b = bson_new (); + bson_append_string (b, "test-name", __FILE__, -1); + bson_finish (b); + + p = mongo_sync_cmd_query (conn, config.ns, + MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, + 0, 2, b, NULL); + bson_free (b); + mongo_wire_reply_packet_get_header (p, &rh); + cid = rh.cursor_id; + mongo_wire_packet_free (p); + + p = mongo_sync_cmd_get_more (conn, config.db, 3, cid); + ok (p != NULL, + "mongo_sync_cmd_get_more() works on secondary too"); + mongo_wire_packet_free (p); + + mongo_sync_reconnect (conn, TRUE); + + p = mongo_sync_cmd_get_more (conn, config.db, 10, cid); + ok (p == NULL && errno == EPROTO, + "mongo_sync_cmd_get_more() can't jump servers"); + mongo_wire_packet_free (p); + + mongo_sync_disconnect (conn); + + endskip; +} + +void +test_mongo_sync_cmd_get_more_net (void) +{ + mongo_packet *p; + mongo_sync_connection *conn; + bson *b; + gint i; + mongo_reply_packet_header rh; + gint64 cid; + + begin_network_tests (4); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + b = bson_new (); + for (i = 0; i < 40; i++) + { + bson_reset (b); + bson_append_string (b, "test-name", __FILE__, -1); + bson_append_int32 (b, "seq", i); + bson_finish (b); + + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + } + bson_free (b); + + b = bson_new (); + bson_append_string (b, "test-name", __FILE__, -1); + bson_finish (b); + + p = mongo_sync_cmd_query (conn, config.ns, + MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, + 0, 2, b, NULL); + bson_free (b); + mongo_wire_reply_packet_get_header (p, &rh); + cid = rh.cursor_id; + mongo_wire_packet_free (p); + + p = mongo_sync_cmd_get_more (conn, config.ns, 3, cid); + ok (p != NULL, + "mongo_sync_cmd_get_more() works"); + mongo_wire_packet_free (p); + + errno = 0; + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + p = mongo_sync_cmd_get_more (conn, config.ns, 10, cid); + ok (p != NULL, + "mongo_sync_cmd_get_more() automatically reconnects"); + mongo_wire_packet_free (p); + + mongo_sync_disconnect (conn); + + test_mongo_sync_cmd_get_more_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_get_more (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + ok (mongo_sync_cmd_get_more (NULL, "test.ns", 1, 1234) == NULL, + "mongo_sync_cmd_get_more() fails with a NULL connection"); + ok (mongo_sync_cmd_get_more (c, NULL, 1, 1234) == NULL, + "mongo_sync_cmd_get_more() fails with a NULL namespace"); + + ok (mongo_sync_cmd_get_more (c, "test.ns", 1, 1234) == NULL, + "mongo_sync_cmd_get_more() fails with a bogus FD"); + mongo_sync_conn_set_slaveok (c, TRUE); + ok (mongo_sync_cmd_get_more (c, "test.ns", 1, 1234) == NULL, + "mongo_sync_cmd_get_more() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_get_more_net (); +} + +RUN_TEST (8, mongo_sync_cmd_get_more); diff --git a/tests/unit/mongo/sync/sync_cmd_index_create.c b/tests/unit/mongo/sync/sync_cmd_index_create.c new file mode 100644 index 0000000..6603586 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_index_create.c @@ -0,0 +1,62 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_index_create (void) +{ + mongo_sync_connection *c; + bson *doc, *indexes, *bad_index; + + c = test_make_fake_sync_conn (-1, FALSE); + doc = test_bson_generate_full (); + indexes = bson_build (BSON_TYPE_INT32, "sex", 1, + BSON_TYPE_DOUBLE, "double", 1.0, + BSON_TYPE_BOOLEAN, "TRUE", TRUE, + BSON_TYPE_INT64, "print", (gint64)-1, + BSON_TYPE_INT32, "zero", 0, + BSON_TYPE_NONE); + bson_finish (indexes); + + bad_index = bson_build (BSON_TYPE_STRING, "str", "teapot", -1, + BSON_TYPE_NONE); + bson_finish (bad_index); + + ok (mongo_sync_cmd_index_create (NULL, "test.ns", indexes, 0) == FALSE, + "mongo_sync_cmd_index_create() fails with a NULL connection"); + ok (mongo_sync_cmd_index_create (c, NULL, indexes, 0) == FALSE, + "mongo_sync_cmd_index_create() fails with a NULL namespace"); + ok (mongo_sync_cmd_index_create (c, "test.ns", NULL, 0) == FALSE, + "mongo_sync_cmd_index_create() fails with NULL indexes"); + ok (mongo_sync_cmd_index_create (c, "bogus", indexes, 0) == FALSE, + "mongo_sync_cmd_index_create() fails with a bogus namespace"); + ok (mongo_sync_cmd_index_create (c, "test.ns", indexes, 0) == FALSE, + "mongo_sync_cmd_index_create() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + begin_network_tests (2); + + c = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + mongo_sync_cmd_insert (c, config.ns, doc, NULL); + + ok (mongo_sync_cmd_index_create(c, config.ns, indexes, + MONGO_INDEX_UNIQUE | MONGO_INDEX_DROP_DUPS | + MONGO_INDEX_BACKGROUND | MONGO_INDEX_SPARSE), + "mongo_sync_cmd_index_create() works"); + + ok (mongo_sync_cmd_index_create(c, config.ns, bad_index, 0) == FALSE, + "mongo_sync_cmd_index_create() should refuse to work with an invalid index spec"); + + mongo_sync_disconnect (c); + + bson_free (doc); + bson_free (indexes); + + end_network_tests (); +} + +RUN_TEST (7, mongo_sync_cmd_index_create); diff --git a/tests/unit/mongo/sync/sync_cmd_index_drop.c b/tests/unit/mongo/sync/sync_cmd_index_drop.c new file mode 100644 index 0000000..176de6d --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_index_drop.c @@ -0,0 +1,51 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_cmd_index_drop (void) +{ + mongo_sync_connection *c; + bson *doc, *indexes; + + c = test_make_fake_sync_conn (-1, FALSE); + doc = test_bson_generate_full (); + indexes = bson_build (BSON_TYPE_INT32, "sex", 1, + BSON_TYPE_DOUBLE, "double", 1.0, + BSON_TYPE_BOOLEAN, "TRUE", TRUE, + BSON_TYPE_INT64, "print", (gint64)-1, + BSON_TYPE_NONE); + bson_finish (indexes); + + ok (mongo_sync_cmd_index_drop (NULL, "test.ns", indexes) == FALSE, + "mongo_sync_cmd_index_drop() fails with a NULL connection"); + ok (mongo_sync_cmd_index_drop (c, NULL, indexes) == FALSE, + "mongo_sync_cmd_index_drop() fails with a NULL namespace"); + ok (mongo_sync_cmd_index_drop (c, "test.ns", NULL) == FALSE, + "mongo_sync_cmd_index_drop() fails with NULL indexes"); + ok (mongo_sync_cmd_index_drop (c, "bogus", indexes) == FALSE, + "mongo_sync_cmd_index_drop() fails with a bogus namespace"); + ok (mongo_sync_cmd_index_drop (c, "test.ns", indexes) == FALSE, + "mongo_sync_cmd_index_drop() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + begin_network_tests (1); + + c = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + mongo_sync_cmd_insert (c, config.ns, doc, NULL); + + mongo_sync_cmd_index_create (c, config.ns, indexes, 0); + + ok (mongo_sync_cmd_index_drop (c, config.ns, indexes) == TRUE, + "mongo_sync_cmd_index_drop() works"); + + mongo_sync_disconnect (c); + + bson_free (doc); + bson_free (indexes); + + end_network_tests (); +} + +RUN_TEST (6, mongo_sync_cmd_index_drop); diff --git a/tests/unit/mongo/sync/sync_cmd_index_drop_all.c b/tests/unit/mongo/sync/sync_cmd_index_drop_all.c new file mode 100644 index 0000000..782fd93 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_index_drop_all.c @@ -0,0 +1,49 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_cmd_index_drop_all (void) +{ + mongo_sync_connection *c; + bson *doc, *indexes; + + c = test_make_fake_sync_conn (-1, FALSE); + doc = test_bson_generate_full (); + indexes = bson_build (BSON_TYPE_INT32, "sex", 1, + BSON_TYPE_DOUBLE, "double", 1.0, + BSON_TYPE_BOOLEAN, "TRUE", TRUE, + BSON_TYPE_INT64, "print", (gint64)-1, + BSON_TYPE_NONE); + bson_finish (indexes); + + ok (mongo_sync_cmd_index_drop_all (NULL, "test.ns") == FALSE, + "mongo_sync_cmd_index_drop_all() fails with a NULL connection"); + ok (mongo_sync_cmd_index_drop_all (c, NULL) == FALSE, + "mongo_sync_cmd_index_drop_all() fails with a NULL namespace"); + ok (mongo_sync_cmd_index_drop_all (c, "bogus") == FALSE, + "mongo_sync_cmd_index_drop_all() fails with a bogus namespace"); + ok (mongo_sync_cmd_index_drop_all (c, "test.ns") == FALSE, + "mongo_sync_cmd_index_drop_all() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + begin_network_tests (1); + + c = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + mongo_sync_cmd_insert (c, config.ns, doc, NULL); + + mongo_sync_cmd_index_create (c, config.ns, indexes, 0); + + ok (mongo_sync_cmd_index_drop_all (c, config.ns) == TRUE, + "mongo_sync_cmd_index_drop_all() works"); + + mongo_sync_disconnect (c); + + bson_free (doc); + bson_free (indexes); + + end_network_tests (); +} + +RUN_TEST (5, mongo_sync_cmd_index_drop_all); diff --git a/tests/unit/mongo/sync/sync_cmd_insert.c b/tests/unit/mongo/sync/sync_cmd_insert.c new file mode 100644 index 0000000..f9a0f6b --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_insert.c @@ -0,0 +1,78 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_insert (void) +{ + mongo_sync_connection *c; + bson *b1, *b2; + + c = test_make_fake_sync_conn (-1, FALSE); + b1 = test_bson_generate_full (); + b2 = test_bson_generate_full (); + + ok (mongo_sync_cmd_insert (NULL, "test.ns", b1, b2, NULL) == FALSE, + "mongo_sync_cmd_insert() fails with a NULL connection"); + ok (mongo_sync_cmd_insert (c, NULL, b1, b2, NULL) == FALSE, + "mongo_sync_cmd_insert() fails with a NULL namespace"); + ok (mongo_sync_cmd_insert (c, "test.ns", NULL) == FALSE, + "mongo_sync_cmd_insert() fails with no documents to insert"); + ok (mongo_sync_cmd_insert (c, "test.ns", b1, b2, NULL) == FALSE, + "mongo_sync_cmd_insert() fails with a bogus FD"); + + mongo_sync_disconnect (c); + bson_free (b1); + bson_free (b2); + + begin_network_tests (4); + + b1 = bson_new (); + bson_append_string (b1, "sync_cmd_insert", "works", -1); + bson_finish (b1); + b2 = bson_new (); + bson_append_int32 (b2, "int32", 1984); + bson_finish (b2); + + c = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (mongo_sync_cmd_insert (c, config.ns, b1, b2, NULL) == TRUE, + "mongo_sync_cmd_insert() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_insert (c, config.ns, b1, b2, NULL) == TRUE, + "mongo_sync_cmd_insert() automatically reconnects"); + + mongo_sync_disconnect (c); + + /* + * Tests involving a secondary + */ + skip (!config.secondary_host, 2, "Secondary host not set up"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (c && mongo_sync_cmd_is_master (c) == FALSE, + "Connected to a secondary"); + + ok (mongo_sync_cmd_insert (c, config.ns, b1, b2, NULL) == TRUE, + "mongo_sync_cmd_insert() automatically reconnects to master"); + mongo_sync_disconnect (c); + + endskip; + + bson_free (b1); + bson_free (b2); + + end_network_tests (); +} + +RUN_TEST (8, mongo_sync_cmd_insert); diff --git a/tests/unit/mongo/sync/sync_cmd_insert_n.c b/tests/unit/mongo/sync/sync_cmd_insert_n.c new file mode 100644 index 0000000..9281c17 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_insert_n.c @@ -0,0 +1,100 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_insert_n (void) +{ + mongo_sync_connection *c; + bson *b1, *b2, *b3; + const bson *docs[10]; + + c = test_make_fake_sync_conn (-1, FALSE); + b1 = test_bson_generate_full (); + b2 = test_bson_generate_full (); + b3 = bson_new (); + + docs[0] = b1; + docs[1] = b2; + docs[2] = b3; + docs[3] = NULL; + docs[4] = b1; + + ok (mongo_sync_cmd_insert_n (NULL, "test.ns", 3, docs) == FALSE, + "mongo_sync_cmd_insert_n() fails with a NULL connection"); + ok (mongo_sync_cmd_insert_n (c, NULL, 3, docs) == FALSE, + "mongo_sync_cmd_insert_n() fails with a NULL namespace"); + ok (mongo_sync_cmd_insert_n (c, "test.ns", 0, docs) == FALSE, + "mongo_sync_cmd_insert_n() fails with no documents to insert"); + ok (mongo_sync_cmd_insert_n (c, "test.ns", 3, NULL) == FALSE, + "mongo_sync_cmd_insert_n() fails with no documents to insert"); + ok (mongo_sync_cmd_insert_n (c, "test.ns", 3, docs) == FALSE, + "mongo_sync_cmd_insert_n() fails when the array contains an " + "unfinished document"); + bson_finish (b3); + ok (mongo_sync_cmd_insert_n (c, "test.ns", 5, docs) == FALSE, + "mongo_sync_cmd_insert_n() fails when the array contains a " + "NULL document"); + ok (mongo_sync_cmd_insert_n (c, "test.ns", 3, docs) == FALSE, + "mongo_sync_cmd_insert_n() fails with a bogus FD"); + + mongo_sync_disconnect (c); + bson_free (b1); + bson_free (b2); + bson_free (b3); + + begin_network_tests (4); + + b1 = bson_new (); + bson_append_string (b2, "sync_cmd_insert_n", "works", -1); + bson_finish (b1); + + b2 = bson_new (); + bson_append_int32 (b2, "int32", 1984); + bson_finish (b2); + + docs[0] = b1; + docs[1] = b2; + + c = mongo_sync_connect (config.primary_host, config.primary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (mongo_sync_cmd_insert_n (c, config.ns, 2, docs) == TRUE, + "mongo_sync_cmd_insert_n() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_insert_n (c, config.ns, 2, docs) == TRUE, + "mongo_sync_cmd_insert_n() automatically reconnects"); + + mongo_sync_disconnect (c); + + /* + * Tests involving a secondary + */ + skip (!config.secondary_host, 2, "Secondary host not set up"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (c && mongo_sync_cmd_is_master (c) == FALSE, + "Connected to a secondary"); + + ok (mongo_sync_cmd_insert_n (c, config.ns, 2, docs) == TRUE, + "mongo_sync_cmd_insert_n() automatically reconnects to master"); + mongo_sync_disconnect (c); + + endskip; + + bson_free (b1); + bson_free (b2); + + end_network_tests (); +} + +RUN_TEST (11, mongo_sync_cmd_insert_n); diff --git a/tests/unit/mongo/sync/sync_cmd_is_master.c b/tests/unit/mongo/sync/sync_cmd_is_master.c new file mode 100644 index 0000000..6fa8bb4 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_is_master.c @@ -0,0 +1,65 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_cmd_is_master_net_secondary (void) +{ + mongo_sync_connection *conn; + + skip (!config.secondary_host, 1, + "Secondary server not configured"); + + errno = 0; + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + ok (mongo_sync_cmd_is_master (conn) == FALSE && errno == 0, + "mongo_sync_cmd_is_master() works correctly on a secondary"); + mongo_sync_disconnect (conn); + + endskip; +} + +void +test_mongo_sync_cmd_is_master_net (void) +{ + mongo_sync_connection *conn; + + begin_network_tests (2); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + ok (mongo_sync_cmd_is_master (conn) == TRUE, + "mongo_sync_cmd_is_master() works"); + mongo_sync_disconnect (conn); + + test_mongo_sync_cmd_is_master_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_is_master (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_is_master (NULL) == FALSE, + "mongo_sync_cmd_is_master fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + errno = 0; + ok (mongo_sync_cmd_is_master (c) == FALSE, + "mongo_sync_cmd_is_master() works"); + cmp_ok (errno, "!=", 0, + "errno is not 0"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_is_master_net (); +} + +RUN_TEST (6, mongo_sync_cmd_is_master); diff --git a/tests/unit/mongo/sync/sync_cmd_kill_cursors.c b/tests/unit/mongo/sync/sync_cmd_kill_cursors.c new file mode 100644 index 0000000..c23a5d8 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_kill_cursors.c @@ -0,0 +1,123 @@ +#include "test.h" +#include "mongo.h" + +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_kill_cursors_net_secondary (void) +{ + mongo_packet *p; + mongo_sync_connection *conn; + bson *b; + + mongo_reply_packet_header rh; + gint64 cid; + + skip (!config.secondary_host, 1, + "Secondary server not configured"); + + conn = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + b = bson_new (); + bson_append_string (b, "test-name", __FILE__, -1); + bson_finish (b); + + p = mongo_sync_cmd_query (conn, config.ns, + MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, + 0, 2, b, NULL); + bson_free (b); + mongo_wire_reply_packet_get_header (p, &rh); + cid = rh.cursor_id; + mongo_wire_packet_free (p); + + ok (mongo_sync_cmd_kill_cursors (conn, 1, cid) == TRUE, + "mongo_sync_cmd_kill_cursors() works on secondary too"); + + mongo_sync_disconnect (conn); + + endskip; +} + +void +test_mongo_sync_cmd_kill_cursors_net (void) +{ + mongo_packet *p; + mongo_sync_connection *conn; + bson *b; + gint i; + mongo_reply_packet_header rh; + gint64 cid; + + begin_network_tests (3); + + conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (conn, TRUE); + + b = bson_new (); + for (i = 0; i < 40; i++) + { + bson_reset (b); + bson_append_string (b, "test-name", __FILE__, -1); + bson_append_int32 (b, "seq", i); + bson_finish (b); + + mongo_sync_cmd_insert (conn, config.ns, b, NULL); + } + bson_free (b); + + b = bson_new (); + bson_append_string (b, "test-name", __FILE__, -1); + bson_finish (b); + + p = mongo_sync_cmd_query (conn, config.ns, + MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, + 0, 2, b, NULL); + mongo_wire_reply_packet_get_header (p, &rh); + cid = rh.cursor_id; + mongo_wire_packet_free (p); + + ok (mongo_sync_cmd_kill_cursors (conn, 1, cid) == TRUE, + "mongo_sync_kill_cursors() works"); + + p = mongo_sync_cmd_query (conn, config.ns, + MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, + 0, 2, b, NULL); + bson_free (b); + mongo_wire_reply_packet_get_header (p, &rh); + cid = rh.cursor_id; + mongo_wire_packet_free (p); + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_kill_cursors (conn, 1, cid) == TRUE, + "mongo_sync_cmd_kill_cursors() automatically reconnects"); + + mongo_sync_disconnect (conn); + + test_mongo_sync_cmd_kill_cursors_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_kill_cursors (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + ok (mongo_sync_cmd_kill_cursors (NULL, 1, (gint64)1234) == FALSE, + "mongo_sync_cmd_kill_cursors() fails with a NULL connection"); + ok (mongo_sync_cmd_kill_cursors (c, 0, (gint64)1234) == FALSE, + "mongo_sync_cmd_kill_cursors() fails with a negative number of cursors"); + + ok (mongo_sync_cmd_kill_cursors (c, 1, (gint64)1234) == FALSE, + "mongo_sync_cmd_kill_cursors() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_kill_cursors_net (); +} + +RUN_TEST (6, mongo_sync_cmd_kill_cursors); diff --git a/tests/unit/mongo/sync/sync_cmd_ping.c b/tests/unit/mongo/sync/sync_cmd_ping.c new file mode 100644 index 0000000..51a8aaf --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_ping.c @@ -0,0 +1,81 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_ping_net_secondary (void) +{ + mongo_sync_connection *c; + + skip (!config.secondary_host, 2, + "Secondary server not configured"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); + + ok (mongo_sync_cmd_ping (c) == TRUE, + "mongo_sync_cmd_ping() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_ping (c) == FALSE, + "mongo_sync_cmd_ping() returns FALSE when not connected"); + + mongo_sync_disconnect (c); + + endskip; +} + +void +test_mongo_sync_cmd_ping_net (void) +{ + mongo_sync_connection *c; + + begin_network_tests (4); + + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + + ok (mongo_sync_cmd_ping (c) == TRUE, + "mongo_sync_cmd_ping() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_ping (c) == FALSE, + "mongo_sync_cmd_ping() returns FALSE when not connected"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_ping_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_ping (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_ping (NULL) == FALSE, + "mongo_sync_cmd_ping(NULL) returns FALSE"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + errno = 0; + ok (mongo_sync_cmd_ping (c) == FALSE, + "Pinging a bogus connection fails"); + cmp_ok (errno, "!=", 0, + "errno is not 0"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_ping_net (); +} + +RUN_TEST (8, mongo_sync_cmd_ping); diff --git a/tests/unit/mongo/sync/sync_cmd_query.c b/tests/unit/mongo/sync/sync_cmd_query.c new file mode 100644 index 0000000..da7c693 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_query.c @@ -0,0 +1,125 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_query (void) +{ + mongo_packet *p; + mongo_sync_connection *c; + bson *q, *s; + + c = test_make_fake_sync_conn (-1, FALSE); + q = test_bson_generate_full (); + s = test_bson_generate_full (); + + ok (mongo_sync_cmd_query (NULL, "test.ns", 0, 0, 1, q, s) == NULL, + "mongo_sync_cmd_query() fails with a NULL connection"); + ok (mongo_sync_cmd_query (c, NULL, 0, 0, 1, q, s) == NULL, + "mongo_sync_cmd_query() fails with a NULL namespace"); + ok (mongo_sync_cmd_query (c, "test.ns", 0, 0, 1, NULL, s) == NULL, + "mongo_sync_cmd_query() fails with a NULL query"); + + ok (mongo_sync_cmd_query (c, "test.ns", 0, 0, 1, q, s) == NULL, + "mongo_sync_cmd_query() fails with a bogus FD"); + mongo_sync_conn_set_slaveok (c, TRUE); + ok (mongo_sync_cmd_query (c, "test.ns", 0, 0, 1, q, s) == NULL, + "mongo_sync_cmd_query() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + bson_free (q); + bson_free (s); + + begin_network_tests (7); + + q = bson_new (); + bson_append_boolean (q, "sync_cmd_query_test", TRUE); + bson_finish (q); + + s = bson_new (); + bson_append_boolean (s, "sync_cmd_query_test", FALSE); + bson_finish (s); + + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + mongo_sync_cmd_insert (c, config.ns, q, NULL); + + p = mongo_sync_cmd_query (c, config.ns, 0, 0, 1, q, NULL); + ok (p != NULL, + "mongo_sync_cmd_query() works"); + mongo_wire_packet_free (p); + + errno = 0; + p = mongo_sync_cmd_query (c, config.ns, 0, 0, 1, s, NULL); + ok (p == NULL && errno == ENOENT, + "mongo_sync_cmd_query() sets errno to ENOENT when there's " + "nothing to return"); + mongo_wire_packet_free (p); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + p = mongo_sync_cmd_query (c, config.ns, 0, 0, 1, q, NULL); + ok (p != NULL, + "mongo_sync_cmd_query() automatically reconnects"); + mongo_wire_packet_free (p); + + mongo_sync_disconnect (c); + + /* + * Test request/response pairing, by sending a crafted query first, + * and another, without reading the response for the first before + * that. + */ + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + p = mongo_wire_cmd_query (12345, config.ns, MONGO_WIRE_FLAG_QUERY_SLAVE_OK, + 0, 1, s, NULL); + mongo_packet_send ((mongo_connection *)c, p); + mongo_wire_packet_free (p); + + errno = 0; + p = mongo_sync_cmd_query (c, config.ns, 0, 0, 1, s, NULL); + ok (p == NULL && errno == EPROTO, + "mongo_sync_cmd_query() fails if the reply is not a response to " + "the current query"); + mongo_wire_packet_free (p); + + mongo_sync_disconnect (c); + + /* + * Tests involving a secondary + */ + skip (!config.secondary_host, 3, "Secondary host not set up"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (c && mongo_sync_cmd_is_master (c) == FALSE, + "Connected to a secondary"); + p = mongo_sync_cmd_query (c, config.ns, 0, 0, 1, q, NULL); + ok (p != NULL, + "mongo_sync_cmd_query() works on secondary"); + mongo_wire_packet_free (p); + + mongo_sync_conn_set_slaveok (c, FALSE); + + p = mongo_sync_cmd_query (c, config.ns, 0, 0, 1, q, NULL); + ok (p != NULL && mongo_sync_cmd_is_master (c) == TRUE, + "mongo_sync_cmd_query() can resync to master"); + mongo_wire_packet_free (p); + + mongo_sync_disconnect (c); + + endskip; + + bson_free (q); + bson_free (s); + + end_network_tests (); +} + +RUN_TEST (12, mongo_sync_cmd_query); diff --git a/tests/unit/mongo/sync/sync_cmd_reset_error.c b/tests/unit/mongo/sync/sync_cmd_reset_error.c new file mode 100644 index 0000000..8f92fcf --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_reset_error.c @@ -0,0 +1,31 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_cmd_reset_error (void) +{ + mongo_sync_connection *c; + + test_env_setup (); + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_reset_error (NULL, config.db) == FALSE, + "mongo_sync_cmd_reset_error() fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + ok (mongo_sync_cmd_reset_error (c, NULL) == FALSE, + "mongo_sync_cmd_reset_error() fails with a NULL db"); + + ok (mongo_sync_cmd_reset_error (c, config.db) == FALSE, + "mongo_sync_cmd_reset_error() fails with a bogus FD"); + + mongo_sync_disconnect (c); + test_env_free (); +} + +RUN_TEST (4, mongo_sync_cmd_reset_error); diff --git a/tests/unit/mongo/sync/sync_cmd_update.c b/tests/unit/mongo/sync/sync_cmd_update.c new file mode 100644 index 0000000..21b981f --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_update.c @@ -0,0 +1,97 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +#include <sys/socket.h> + +void +test_mongo_sync_cmd_update (void) +{ + mongo_sync_connection *c; + bson *sel, *upd; + guint8 *oid; + + mongo_util_oid_init (0); + + sel = bson_new (); + oid = mongo_util_oid_new (0); + bson_append_oid (sel, "_id", oid); + g_free (oid); + bson_finish (sel); + + upd = test_bson_generate_full (); + c = test_make_fake_sync_conn (-1, FALSE); + + ok (mongo_sync_cmd_update (NULL, "test.ns", 0, sel, upd) == FALSE, + "mongo_sync_cmd_update() fails with a NULL connection"); + ok (mongo_sync_cmd_update (c, NULL, 0, sel, upd) == FALSE, + "mongo_sync_cmd_update() fails with a NULL namespace"); + ok (mongo_sync_cmd_update (c, "test.ns", 0, NULL, upd) == FALSE, + "mongo_sync_cmd_update() fails with a NULL selector"); + ok (mongo_sync_cmd_update (c, "test.ns", 0, sel, NULL) == FALSE, + "mongo_sync_cmd_update() fails with a NULL update"); + + ok (mongo_sync_cmd_update (c, "test.ns", 0, sel, upd) == FALSE, + "mongo_sync_cmd_update() fails with a bogus FD"); + + mongo_sync_disconnect (c); + bson_free (sel); + bson_free (upd); + + begin_network_tests (4); + + sel = bson_new (); + oid = mongo_util_oid_new (1); + bson_append_oid (sel, "_id", oid); + g_free (oid); + bson_finish (sel); + + upd = bson_new (); + oid = mongo_util_oid_new (1); + bson_append_oid (upd, "_id", oid); + g_free (oid); + bson_finish (upd); + + c = mongo_sync_connect (config.primary_host, config.primary_port, + FALSE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (mongo_sync_cmd_update (c, config.ns, + MONGO_WIRE_FLAG_UPDATE_UPSERT, sel, upd) == TRUE, + "mongo_sync_cmd_update() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_update (c, config.ns, + MONGO_WIRE_FLAG_UPDATE_UPSERT, sel, upd) == TRUE, + "mongo_sync_cmd_update() automatically reconnects"); + + mongo_sync_disconnect (c); + + /* + * Tests involving a secondary + */ + skip (!config.secondary_host, 2, + "Secondary host not set up"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, + TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (mongo_sync_cmd_is_master (c) == FALSE, + "Connected to a secondary"); + + ok (mongo_sync_cmd_update (c, config.ns, + MONGO_WIRE_FLAG_UPDATE_UPSERT, sel, upd) == TRUE, + "mongo_sync_cmd_update() automatically reconnects to master"); + mongo_sync_disconnect (c); + endskip; + + bson_free (sel); + bson_free (upd); + end_network_tests (); +} + +RUN_TEST (9, mongo_sync_cmd_update); diff --git a/tests/unit/mongo/sync/sync_cmd_user_add.c b/tests/unit/mongo/sync/sync_cmd_user_add.c new file mode 100644 index 0000000..9cdc542 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_user_add.c @@ -0,0 +1,95 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_user_add_net_secondary (void) +{ + mongo_sync_connection *c; + gboolean ret; + + skip (!config.secondary_host, 1, + "Secondary server not configured"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ret = mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+"); + ok (ret && mongo_sync_cmd_is_master (c), + "mongo_sync_cmd_user_add() automatically reconnects to master"); + + mongo_sync_disconnect (c); + + endskip; +} + +void +test_mongo_sync_cmd_user_add_net (void) +{ + mongo_sync_connection *c; + + begin_network_tests (3); + + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_user_add() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+") == TRUE, + "mongo_sync_cmd_user_add() automatically reconnects"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_user_add_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_user_add (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_user_add (NULL, "test", "test", "s3kr1+") == FALSE, + "mongo_sync_cmd_user_add() fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + errno = 0; + ok (mongo_sync_cmd_user_add (c, NULL, "test", "s3kr1+") == FALSE, + "mongo_sync_cmd_user_add() fails with a NULL db"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_user_add (c, "test", NULL, "s3kr1+") == FALSE, + "mongo_sync_cmd_user_add() fails with a NULL user"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_user_add (c, "test", "test", NULL) == FALSE, + "mongo_sync_cmd_user_add() fails with a NULL password"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + ok (mongo_sync_cmd_user_add (c, "test", "test", "s3kr1+") == FALSE, + "mongo_sync_cmd_user_add() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_user_add_net (); +} + +RUN_TEST (12, mongo_sync_cmd_user_add); diff --git a/tests/unit/mongo/sync/sync_cmd_user_add_with_roles.c b/tests/unit/mongo/sync/sync_cmd_user_add_with_roles.c new file mode 100644 index 0000000..04bb842 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_user_add_with_roles.c @@ -0,0 +1,89 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_user_add_with_roles_net (const bson *roles) +{ + mongo_sync_connection *c; + + begin_network_tests (2); + + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + ok (mongo_sync_cmd_user_add_with_roles (c, config.db, + "test", "s3kr1+", roles) == TRUE, + "mongo_sync_cmd_user_add_with_roles() works"); + + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_user_add_with_roles (c, config.db, + "test", "s3kr1+", roles) == TRUE, + "mongo_sync_cmd_user_add_with_roles() automatically reconnects"); + + mongo_sync_disconnect (c); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_user_add_with_roles (void) +{ + mongo_sync_connection *c; + bson *roles = bson_build (BSON_TYPE_STRING, "0", "readWrite", -1, + BSON_TYPE_NONE); + + bson_finish (roles); + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_user_add_with_roles (NULL, "test", + "test", "s3kr1+", roles) == FALSE, + "mongo_sync_cmd_user_add_with_roles() fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + errno = 0; + ok (mongo_sync_cmd_user_add_with_roles (c, NULL, + "test", "s3kr1+", roles) == FALSE, + "mongo_sync_cmd_user_add_with_roles() fails with a NULL db"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_user_add_with_roles (c, "test", + NULL, "s3kr1+", roles) == FALSE, + "mongo_sync_cmd_user_add_with_roles() fails with a NULL user"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_user_add_with_roles (c, "test", + "test", NULL, roles) == FALSE, + "mongo_sync_cmd_user_add_with_roles() fails with a NULL password"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + ok (mongo_sync_cmd_user_add_with_roles (c, "test", + "test", "s3kr1+", NULL) == FALSE, + "mongo_sync_cmd_user_add() fails with a bogus FD and empty roles"); + + ok (mongo_sync_cmd_user_add_with_roles (c, "test", + "test", "s3kr1+", roles) == FALSE, + "mongo_sync_cmd_user_add() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_user_add_with_roles_net (roles); + + bson_free (roles); +} + +RUN_TEST (12, mongo_sync_cmd_user_add_with_roles); diff --git a/tests/unit/mongo/sync/sync_cmd_user_remove.c b/tests/unit/mongo/sync/sync_cmd_user_remove.c new file mode 100644 index 0000000..dc66063 --- /dev/null +++ b/tests/unit/mongo/sync/sync_cmd_user_remove.c @@ -0,0 +1,92 @@ +#include "test.h" +#include "mongo.h" +#include "config.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_cmd_user_remove_net_secondary (void) +{ + mongo_sync_connection *c; + gboolean ret; + + skip (!config.secondary_host, 1, + "Secondary server not configured"); + + c = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+"); + ret = mongo_sync_cmd_user_remove (c, config.db, "test"); + ok (ret && mongo_sync_cmd_is_master (c), + "mongo_sync_cmd_user_remove() automatically reconnects to master"); + + mongo_sync_disconnect (c); + + endskip; +} + +void +test_mongo_sync_cmd_user_remove_net (void) +{ + mongo_sync_connection *c; + + begin_network_tests (3); + + c = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); + mongo_sync_conn_set_auto_reconnect (c, TRUE); + + mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+"); + ok (mongo_sync_cmd_user_remove (c, config.db, "test") == TRUE, + "mongo_sync_cmd_user_remove() works"); + + mongo_sync_cmd_user_add (c, config.db, "test", "s3kr1+"); + shutdown (c->super.fd, SHUT_RDWR); + sleep (3); + + ok (mongo_sync_cmd_user_remove (c, config.db, "test") == TRUE, + "mongo_sync_cmd_user_remove() automatically reconnects"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_user_remove_net_secondary (); + + end_network_tests (); +} + +void +test_mongo_sync_cmd_user_remove (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_cmd_user_remove (NULL, "test", "test") == FALSE, + "mongo_sync_cmd_user_remove() fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN"); + + errno = 0; + ok (mongo_sync_cmd_user_remove (c, NULL, "test") == FALSE, + "mongo_sync_cmd_user_remove() fails with a NULL db"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + errno = 0; + ok (mongo_sync_cmd_user_remove (c, "test", NULL) == FALSE, + "mongo_sync_cmd_user_remove() fails with a NULL user"); + cmp_ok (errno, "==", EINVAL, + "errno is set to EINVAL"); + + ok (mongo_sync_cmd_user_remove (c, "test", "test") == FALSE, + "mongo_sync_cmd_user_remove() fails with a bogus FD"); + + mongo_sync_disconnect (c); + + test_mongo_sync_cmd_user_remove_net (); +} + +RUN_TEST (10, mongo_sync_cmd_user_remove); diff --git a/tests/unit/mongo/sync/sync_conn_seed_add.c b/tests/unit/mongo/sync/sync_conn_seed_add.c new file mode 100644 index 0000000..fb9f10a --- /dev/null +++ b/tests/unit/mongo/sync/sync_conn_seed_add.c @@ -0,0 +1,24 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_conn_seed_add (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (42, TRUE); + + ok (mongo_sync_conn_seed_add (NULL, "localhost", 27017) == FALSE, + "mongo_sync_conn_seed_add() should fail with a NULL connection"); + ok (mongo_sync_conn_seed_add (c, NULL, 27017) == FALSE, + "mongo_sync_conn_seed_add() should fail with a NULL host"); + ok (mongo_sync_conn_seed_add (c, "localhost", -1) == FALSE, + "mongo_sync_conn_seed_add() should fail with an invalid port"); + + ok (mongo_sync_conn_seed_add (c, "localhost", 27017), + "mongo_sync_conn_seed_add() works"); + + mongo_sync_disconnect (c); +} + +RUN_TEST (4, mongo_sync_conn_seed_add); diff --git a/tests/unit/mongo/sync/sync_conn_seed_add_cache.c b/tests/unit/mongo/sync/sync_conn_seed_add_cache.c new file mode 100644 index 0000000..e049691 --- /dev/null +++ b/tests/unit/mongo/sync/sync_conn_seed_add_cache.c @@ -0,0 +1,31 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_connection_cache_seed_add (void) +{ + mongo_sync_conn_recovery_cache *cache; + + cache = mongo_sync_conn_recovery_cache_new (); + + ok (mongo_sync_conn_recovery_cache_seed_add (cache, + "localhost", + 27017) == TRUE, + "mongo_sync_connection_cache_seed_add() works"); + + ok (mongo_sync_conn_recovery_cache_seed_add (cache, + NULL, + 27017) == FALSE, + "mongo_sync_connection_cache_seed_add() should fail with a NULL host"); + + mongo_sync_conn_recovery_cache_discard (cache); + + ok (mongo_sync_conn_recovery_cache_seed_add (cache, + "localhost", + 27017) == TRUE, + "mongo_sync_connection_cache_seed_add() works"); + + mongo_sync_conn_recovery_cache_free (cache); +} + +RUN_TEST (3, mongo_sync_connection_cache_seed_add); diff --git a/tests/unit/mongo/sync/sync_connect.c b/tests/unit/mongo/sync/sync_connect.c new file mode 100644 index 0000000..418c2bf --- /dev/null +++ b/tests/unit/mongo/sync/sync_connect.c @@ -0,0 +1,22 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_connect (void) +{ + mongo_sync_connection *c; + + ok (mongo_sync_connect (NULL, 27017, FALSE) == NULL, + "mongo_sync_connect() fails with a NULL host"); + + begin_network_tests (1); + + ok ((c = mongo_sync_connect (config.primary_host, + config.primary_port, FALSE)) != NULL, + "mongo_sync_connect() works"); + mongo_sync_disconnect (c); + + end_network_tests (); +} + +RUN_TEST (2, mongo_sync_connect); diff --git a/tests/unit/mongo/sync/sync_connect_cache.c b/tests/unit/mongo/sync/sync_connect_cache.c new file mode 100644 index 0000000..1618899 --- /dev/null +++ b/tests/unit/mongo/sync/sync_connect_cache.c @@ -0,0 +1,42 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_sync_conn_recovery_cache_connection (void) +{ + mongo_sync_conn_recovery_cache *cache; + mongo_sync_connection *c = NULL; + + cache = mongo_sync_conn_recovery_cache_new (); + + ok (mongo_sync_connect_recovery_cache (cache, FALSE) == NULL, + "mongo_sync_connect_recovery_cache() should fail when cache is empty"); + + begin_network_tests (4); + + ok (mongo_sync_conn_recovery_cache_seed_add (cache, + config.primary_host, + config.primary_port) == TRUE, + "mongo_sync_conn_recovery_cache_seed_add() works"); + + ok ((c = mongo_sync_connect_recovery_cache (cache, FALSE)) != NULL, + "mongo_sync_connect_recovery_cache() works"); + + mongo_sync_disconnect (c); + + ok ((c = mongo_sync_connect_recovery_cache (cache, FALSE)) != NULL, + "mongo_sync_connect_recovery_cache() works after disconnect"); + + mongo_sync_disconnect (c); + + mongo_sync_conn_recovery_cache_discard (cache); + + ok (mongo_sync_connect_recovery_cache (cache, TRUE) == NULL, + "mongo_sync_connect_recovery_cache() should fail when cache is discarded"); + + mongo_sync_conn_recovery_cache_free (cache); + + end_network_tests (); +} + +RUN_TEST (5, mongo_sync_conn_recovery_cache_connection); diff --git a/tests/unit/mongo/sync/sync_connect_from_cache_enforce_primary.c b/tests/unit/mongo/sync/sync_connect_from_cache_enforce_primary.c new file mode 100644 index 0000000..5c48ae9 --- /dev/null +++ b/tests/unit/mongo/sync/sync_connect_from_cache_enforce_primary.c @@ -0,0 +1,47 @@ +#include "test.h" +#include "mongo.h" + +#define NETWORK_TESTS_NUM 5 + +void +test_mongo_sync_connect_from_cache_enforce_primary (void) +{ + mongo_sync_conn_recovery_cache *cache; + mongo_sync_connection *c; + + begin_network_tests (NETWORK_TESTS_NUM); + + cache = mongo_sync_conn_recovery_cache_new (); + + skip (!config.secondary_host, + NETWORK_TESTS_NUM, + "Secondary server not configured"); + + ok (mongo_sync_conn_recovery_cache_seed_add (cache, config.secondary_host, + config.secondary_port) == TRUE, + "mongo_sync_conn_recovery_seed_add() works"); + + ok ((c = mongo_sync_connect_recovery_cache (cache, TRUE)) != NULL, + "mongo_sync_connect_recovery_cache() works"); + + ok (mongo_sync_cmd_is_master(c) == FALSE, + "Secondary server should not be The Master."); + + mongo_sync_disconnect (c); + + ok ((c = mongo_sync_connect_recovery_cache (cache, FALSE)) != NULL, + "mongo_sync_connect_recovery_cache() works"); + + ok (mongo_sync_cmd_is_master (c) == TRUE,\ + "Retrieved connection should be The Master when it is forced to be."); + + mongo_sync_disconnect (c); + + endskip; + + mongo_sync_conn_recovery_cache_free (cache); + + end_network_tests (); +} + +RUN_TEST (NETWORK_TESTS_NUM, mongo_sync_connect_from_cache_enforce_primary); diff --git a/tests/unit/mongo/sync/sync_disconnect.c b/tests/unit/mongo/sync/sync_disconnect.c new file mode 100644 index 0000000..f7783e7 --- /dev/null +++ b/tests/unit/mongo/sync/sync_disconnect.c @@ -0,0 +1,22 @@ +#include "test.h" +#include "mongo.h" + +#include "libmongo-private.h" + +void +test_mongo_sync_disconnect (void) +{ + mongo_sync_connection *conn; + + mongo_sync_disconnect (NULL); + pass ("mongo_sync_disconnect(NULL) does not crash"); + + conn = test_make_fake_sync_conn (-1, FALSE); + conn->rs.hosts = g_list_append (conn->rs.hosts, + g_strdup ("invalid.example.com:-42")); + + mongo_sync_disconnect (conn); + pass ("mongo_sync_disconnect() works"); +} + +RUN_TEST (2, mongo_sync_disconnect); diff --git a/tests/unit/mongo/sync/sync_get_set_auto_reconnect.c b/tests/unit/mongo/sync/sync_get_set_auto_reconnect.c new file mode 100644 index 0000000..bfe2719 --- /dev/null +++ b/tests/unit/mongo/sync/sync_get_set_auto_reconnect.c @@ -0,0 +1,39 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_get_set_auto_reconnect (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_conn_get_auto_reconnect (NULL) == FALSE, + "mongo_sync_conn_get_auto_reconnect() returns FALSE with a " + "NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is now set to ENOTCONN"); + + ok (mongo_sync_conn_get_auto_reconnect (c) == FALSE, + "mongo_sync_get_auto_reconnect() works"); + cmp_ok (errno, "==", 0, + "errno is now cleared"); + + errno = 0; + mongo_sync_conn_set_auto_reconnect (NULL, TRUE); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN after " + "mongo_sync_conn_set_auto_reconnect(NULL)"); + + ok (mongo_sync_conn_set_auto_reconnect (c, TRUE), + "mongo_sync_auto_reconnect() works"); + ok (mongo_sync_conn_get_auto_reconnect (c) == TRUE, + "mongo_sync_set_auto_reconnect() worked"); + + mongo_sync_disconnect (c); +} + +RUN_TEST (7, mongo_sync_get_set_auto_reconnect); diff --git a/tests/unit/mongo/sync/sync_get_set_max_insert_size.c b/tests/unit/mongo/sync/sync_get_set_max_insert_size.c new file mode 100644 index 0000000..51970a3 --- /dev/null +++ b/tests/unit/mongo/sync/sync_get_set_max_insert_size.c @@ -0,0 +1,44 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_get_set_max_insert_size (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_conn_get_max_insert_size (NULL) == -1, + "mongo_sync_conn_get_max_insert_size() returns -1 with " + "a NULL connection"); + + cmp_ok (mongo_sync_conn_get_max_insert_size (c), "==", + MONGO_SYNC_DEFAULT_MAX_INSERT_SIZE, + "mongo_sync_get_max_insert_size() works"); + + errno = 0; + mongo_sync_conn_set_max_insert_size (NULL, 1024); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN after " + "mongo_sync_conn_set_max_insert_size(NULL)"); + + mongo_sync_conn_set_max_insert_size (c, 1024); + cmp_ok (errno, "==", 0, + "errno is cleared"); + ok (mongo_sync_conn_get_max_insert_size (c) == 1024, + "mongo_sync_set_max_insert_size() worked"); + + mongo_sync_conn_set_max_insert_size (c, -1); + cmp_ok (errno, "==", ERANGE, + "errno is set to ERANGE"); + ok (mongo_sync_conn_get_max_insert_size (c) == 1024, + "mongo_sync_set_max_insert_size() with a negative value should " + "not work"); + + mongo_sync_disconnect (c); +} + +RUN_TEST (7, mongo_sync_get_set_max_insert_size); diff --git a/tests/unit/mongo/sync/sync_get_set_safe_mode.c b/tests/unit/mongo/sync/sync_get_set_safe_mode.c new file mode 100644 index 0000000..b444105 --- /dev/null +++ b/tests/unit/mongo/sync/sync_get_set_safe_mode.c @@ -0,0 +1,38 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_get_set_safe_mode (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_conn_get_safe_mode (NULL) == FALSE, + "mongo_sync_conn_get_safe_mode() returns FALSE with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is now set to ENOTCONN"); + + ok (mongo_sync_conn_get_safe_mode (c) == FALSE, + "mongo_sync_get_safe_mode() works"); + cmp_ok (errno, "==", 0, + "errno is now cleared"); + + errno = 0; + mongo_sync_conn_set_safe_mode (NULL, TRUE); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN after mongo_sync_conn_get_safe_mode(NULL)"); + + mongo_sync_conn_set_safe_mode (c, TRUE); + cmp_ok (errno, "==", 0, + "errno is cleared"); + ok (mongo_sync_conn_get_safe_mode (c) == TRUE, + "mongo_sync_set_safe_mode() worked"); + + mongo_sync_disconnect (c); +} + +RUN_TEST (7, mongo_sync_get_set_safe_mode); diff --git a/tests/unit/mongo/sync/sync_get_set_slaveok.c b/tests/unit/mongo/sync/sync_get_set_slaveok.c new file mode 100644 index 0000000..7a43979 --- /dev/null +++ b/tests/unit/mongo/sync/sync_get_set_slaveok.c @@ -0,0 +1,38 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> + +void +test_mongo_sync_get_set_slaveok (void) +{ + mongo_sync_connection *c; + + c = test_make_fake_sync_conn (-1, FALSE); + + errno = 0; + ok (mongo_sync_conn_get_slaveok (NULL) == FALSE, + "mongo_sync_conn_get_slaveok() returns FALSE with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is now set to ENOTCONN"); + + ok (mongo_sync_conn_get_slaveok (c) == FALSE, + "mongo_sync_get_slaveok() works"); + cmp_ok (errno, "==", 0, + "errno is now cleared"); + + errno = 0; + mongo_sync_conn_set_slaveok (NULL, TRUE); + cmp_ok (errno, "==", ENOTCONN, + "errno is set to ENOTCONN after mongo_sync_conn_get_slaveok(NULL)"); + + mongo_sync_conn_set_slaveok (c, TRUE); + cmp_ok (errno, "==", 0, + "errno is cleared"); + ok (mongo_sync_conn_get_slaveok (c) == TRUE, + "mongo_sync_set_slaveok() worked"); + + mongo_sync_disconnect (c); +} + +RUN_TEST (7, mongo_sync_get_set_slaveok); diff --git a/tests/unit/mongo/sync/sync_reconnect.c b/tests/unit/mongo/sync/sync_reconnect.c new file mode 100644 index 0000000..a81e4da --- /dev/null +++ b/tests/unit/mongo/sync/sync_reconnect.c @@ -0,0 +1,143 @@ +#include "test.h" +#include "mongo.h" + +#include <errno.h> +#include <sys/socket.h> +#include "libmongo-private.h" + +void +test_mongo_sync_reconnect (void) +{ + mongo_sync_connection *conn, *o; + GList *l; + + ok (mongo_sync_reconnect (NULL, FALSE) == NULL, + "mongo_sync_reconnect() fails with a NULL connection"); + cmp_ok (errno, "==", ENOTCONN, + "errno is ENOTCONN"); + + conn = test_make_fake_sync_conn (-1, FALSE); + ok (mongo_sync_reconnect (conn, FALSE) == NULL, + "mongo_sync_reconnect() fails with a bogus FD"); + cmp_ok (errno, "==", EHOSTUNREACH, + "errno is EHOSTUNREACH"); + + mongo_sync_disconnect (conn); + + begin_network_tests (15); + + /* Connect & reconnect to master */ + o = conn = mongo_sync_connect (config.primary_host, + config.primary_port, TRUE); + ok ((conn = mongo_sync_reconnect (conn, TRUE)) != NULL, + "mongo_sync_reconnect() works when reconnecting to self"); + ok (o == conn, + "Reconnect to an existing master results in the same object"); + mongo_sync_disconnect (conn); + + /* Connect to master, kill FD, reconnect */ + conn = mongo_sync_connect (config.primary_host, + config.primary_port, TRUE); + mongo_sync_cmd_is_master (conn); + + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + + ok ((conn = mongo_sync_reconnect (conn, TRUE)) != NULL, + "mongo_sync_reconnect() succeed when the connection drops"); + mongo_sync_disconnect (conn); + + /* Connect, kill, reconnect; w/o knowing other hosts */ + o = conn = mongo_sync_connect (config.primary_host, + config.primary_port, TRUE); + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + l = conn->rs.hosts; + while (l) + { + g_free (l->data); + l = g_list_delete_link (l, l); + } + conn->rs.hosts = NULL; + + l = conn->rs.seeds; + while (l) + { + g_free (l->data); + l = g_list_delete_link (l, l); + } + conn->rs.seeds = NULL; + + conn = mongo_sync_reconnect (conn, FALSE); + + ok (conn != o && conn == NULL, + "mongo_sync_reconnect() fails if it can't reconnect anywhere"); + mongo_sync_disconnect (o); + + /* Gracefully ignore unparsable hosts during reconnect */ + o = conn = mongo_sync_connect (config.primary_host, + config.primary_port, TRUE); + mongo_sync_cmd_is_master (conn); + conn->rs.hosts = g_list_prepend (conn->rs.hosts, + g_strdup ("invalid:-42")); + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + conn = mongo_sync_reconnect (conn, TRUE); + + ok (conn == o, + "mongo_sync_reconnect() gracefully ignores unparsable hosts " + "during reconnect"); + mongo_sync_disconnect (conn); + + /* Ignore unreachable hosts during reconnect */ + o = conn = mongo_sync_connect (config.primary_host, + config.primary_port, TRUE); + mongo_sync_cmd_is_master (conn); + conn->rs.hosts = g_list_prepend (conn->rs.hosts, + g_strdup ("example.com:27017")); + shutdown (conn->super.fd, SHUT_RDWR); + sleep (3); + conn = mongo_sync_reconnect (conn, TRUE); + + ok (conn == o, + "mongo_sync_reconnect() gracefully ignores unparsable hosts " + "during reconnect"); + mongo_sync_disconnect (conn); + + /* + * Tests involving a secondary + */ + + skip (!config.secondary_host, 9, + "Secondary host not set up"); + + /* Connect to secondary & reconnect to master */ + o = conn = mongo_sync_connect (config.secondary_host, + config.secondary_port, TRUE); + ok (conn != NULL, "Connecting to secondary"); + ok (mongo_sync_cmd_is_master (conn) == FALSE, + "Connected to a secondary"); + ok ((conn = mongo_sync_reconnect (conn, TRUE)) != NULL, + "Reconnecting from slave to master succeeds"); + ok (conn == o, "Connection object updated in-place"); + ok (mongo_sync_cmd_is_master (conn), + "Correctly reconnected to master"); + mongo_sync_disconnect (conn); + + /* Connect to secondary & reconnect to self */ + o = conn = mongo_sync_connect (config.secondary_host, + config.secondary_port, TRUE); + ok (conn != NULL, "Connecting to secondary"); + ok ((conn = mongo_sync_reconnect (conn, FALSE)) != NULL, + "Reconnecting from slave to self succeeds"); + ok (conn == o, "Connection object updated in-place"); + ok (mongo_sync_cmd_is_master (conn) == FALSE, + "Correctly reconnected to self"); + mongo_sync_disconnect (conn); + + endskip; + + end_network_tests (); +} + +RUN_TEST (19, mongo_sync_reconnect); diff --git a/tests/unit/mongo/utils/oid_as_string.c b/tests/unit/mongo/utils/oid_as_string.c new file mode 100644 index 0000000..9cf740c --- /dev/null +++ b/tests/unit/mongo/utils/oid_as_string.c @@ -0,0 +1,26 @@ +#include "test.h" +#include "mongo.h" + +void +test_mongo_utils_oid_as_string (void) +{ + guint8 *oid; + gchar *oid_str; + + mongo_util_oid_init (0); + + oid = mongo_util_oid_new (1); + + ok (mongo_util_oid_as_string (NULL) == NULL, + "mongo_util_oid_as_string() should fail with a NULL oid"); + + oid_str = mongo_util_oid_as_string (oid); + + ok (oid_str != NULL, + "mongo_util_oid_as_string() works"); + + g_free (oid_str); + g_free (oid); +} + +RUN_TEST (2, mongo_utils_oid_as_string); diff --git a/tests/unit/mongo/utils/oid_init.c b/tests/unit/mongo/utils/oid_init.c new file mode 100644 index 0000000..42d0db1 --- /dev/null +++ b/tests/unit/mongo/utils/oid_init.c @@ -0,0 +1,19 @@ +#include "tap.h" +#include "test.h" +#include "mongo-utils.h" + +void +test_mongo_utils_oid_init (void) +{ + mongo_util_oid_init (0); + mongo_util_oid_init (1234); + + /* We don't do any real testing here, only check if it does not + crash. To verify that it works, we need to create a new OID, and + that will be tested by other unit tests. + */ + ok (TRUE, + "mongo_util_oid_init() does not crash."); +} + +RUN_TEST (1, mongo_utils_oid_init); diff --git a/tests/unit/mongo/utils/oid_new.c b/tests/unit/mongo/utils/oid_new.c new file mode 100644 index 0000000..b8f7f0a --- /dev/null +++ b/tests/unit/mongo/utils/oid_new.c @@ -0,0 +1,49 @@ +#include "tap.h" +#include "test.h" +#include "mongo-utils.h" + +#include <string.h> +#include <unistd.h> + +void +test_mongo_utils_oid_new (void) +{ + guint8 *oid1, *oid2, *oid3; + gchar *oid1_s, *oid2_s; + + ok (mongo_util_oid_new (0) == NULL, + "mongo_util_oid_new() should fail before mongo_util_oid_init()"); + + mongo_util_oid_init (0); + ok ((oid1 = mongo_util_oid_new (1)) != NULL, + "mongo_util_oid_new() works"); + cmp_ok (oid1[11], "==", 1, + "mongo_util_oid_new() returns an OID with the currect seq ID"); + + oid2 = mongo_util_oid_new (2); + oid3 = mongo_util_oid_new (2); + + ok (memcmp (oid2, oid1, 12) > 0, + "OIDs with higher sequence ID sort higher"); + ok (memcmp (oid2, oid3, 12) == 0, + "OIDs with the same sequence ID are equal (within a second)"); + g_free (oid2); + g_free (oid3); + + sleep (2); + oid2 = mongo_util_oid_new (0); + + oid1_s = mongo_util_oid_as_string (oid1); + oid2_s = mongo_util_oid_as_string (oid2); + + ok (memcmp (oid2, oid1, 12) > 0, + "OIDs with the same sequence ID, a few seconds later sort higher; " + "oid1=%s; oid2=%s", oid1_s, oid2_s); + + g_free (oid2_s); + g_free (oid1_s); + g_free (oid2); + g_free (oid1); +} + +RUN_TEST (6, mongo_utils_oid_new); diff --git a/tests/unit/mongo/utils/oid_new_with_time.c b/tests/unit/mongo/utils/oid_new_with_time.c new file mode 100644 index 0000000..290fdab --- /dev/null +++ b/tests/unit/mongo/utils/oid_new_with_time.c @@ -0,0 +1,46 @@ +#include "tap.h" +#include "test.h" +#include "mongo-utils.h" + +#include <string.h> + +void +test_mongo_utils_oid_new_with_time (void) +{ + guint8 *oid1, *oid2, *oid3; + gchar *oid1_s, *oid2_s; + + ok (mongo_util_oid_new_with_time (0, 0) == NULL, + "mongo_util_oid_new_with_time() should fail before mongo_util_oid_init()"); + + mongo_util_oid_init (0); + ok ((oid1 = mongo_util_oid_new_with_time (0, 1)) != NULL, + "mongo_util_oid_new_with_time() works"); + cmp_ok (oid1[11], "==", 1, + "mongo_util_oid_new_with_time() returns an OID with the currect seq ID"); + + oid2 = mongo_util_oid_new_with_time (0, 2); + oid3 = mongo_util_oid_new_with_time (0, 2); + + ok (memcmp (oid2, oid1, 12) > 0, + "OIDs with higher sequence ID sort higher"); + ok (memcmp (oid2, oid3, 12) == 0, + "OIDs with the same sequence ID are equal (within a second)"); + g_free (oid2); + g_free (oid3); + + oid2 = mongo_util_oid_new_with_time (1, 0); + + oid1_s = mongo_util_oid_as_string (oid1); + oid2_s = mongo_util_oid_as_string (oid2); + + ok (memcmp (oid2, oid1, 12) > 0, + "OIDs with the same sequence ID, a few seconds later sort higher; " + "oid1=%s; oid2=%s", oid1_s, oid2_s); + g_free (oid2_s); + g_free (oid1_s); + g_free (oid2); + g_free (oid1); +} + +RUN_TEST (6, mongo_utils_oid_new_with_time); diff --git a/tests/unit/mongo/utils/parse_addr.c b/tests/unit/mongo/utils/parse_addr.c new file mode 100644 index 0000000..13b16d1 --- /dev/null +++ b/tests/unit/mongo/utils/parse_addr.c @@ -0,0 +1,244 @@ +#include "tap.h" +#include "test.h" +#include "mongo-utils.h" + +#include <string.h> + +void +test_mongo_utils_parse_addr (void) +{ + gchar *host = "deadbeef"; + gint port = 42; + + ok (mongo_util_parse_addr (NULL, &host, &port) == FALSE, + "mongo_util_parse_addr() fails with a NULL address"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("127.0.0.1:27017", &host, NULL) == FALSE, + "mongo_util_parse_addr() fails when port is NULL"); + is (host, NULL, + "Failed parsing sets host to NULL"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("127.0.0.1:27017", NULL, &port) == FALSE, + "mongo_util_parse_addr() fails when host is NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("127.0.0.1:27017", &host, &port), + "mongo_util_parse_addr() can parse HOST:PORT pairs"); + is (host, "127.0.0.1", + "Host parsed successfully"); + cmp_ok (port, "==", 27017, + "Port parsed successfully"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr (":27017", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail when no host is specified"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("localhost:27017garbage", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if there is garbage after " + "the port"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("localhost:garbage", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is not a number"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("localhost:-10", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is out of bounds"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("localhost:9999999999999999999", + &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is out of bounds"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("localhost:9999999999", + &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is out of bounds"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + /* IPv6 */ + ok (mongo_util_parse_addr ("::1:27017", &host, &port), + "mongo_util_parse_addr() can deal with IPv6 addresses"); + is (host, "::1", + "Host parsed successfully"); + cmp_ok (port, "==", 27017, + "Port parsed successfully"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("::1", &host, &port), + "mongo_util_parse_addr() should silently misparse ambigous " + "IPv6 addresses"); + isnt (host, "::1", + "Host is misparsed, as expected"); + cmp_ok (port, "==", 1, + "Port is misparsed, as expected"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail on invalid IPv6 literals"); + is (host, NULL, + "Host should be NULL"); + cmp_ok (port, "==", -1, + "Port should be -1"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:1", &host, &port), + "mongo_util_parse_addr() works with IPv6 literal + port"); + is (host, "::1", + "Host should be ::1"); + cmp_ok (port, "==", 1, + "Port should be 1"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:27017", &host, &port), + "mongo_util_parse_addr() works with IPv6 literal + port"); + is (host, "::1", + "Host should be ::1"); + cmp_ok (port, "==", 27017, + "Port should be 27017"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[]:27017", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail when no host is specified"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:27017garbage", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if there is garbage after " + "the port"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:garbage", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is not a number"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:-10", &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is out of bounds"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:9999999999999999999", + &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is out of bounds"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]:9999999999", + &host, &port) == FALSE, + "mongo_util_parse_addr() should fail if the port is out of bounds"); + is (host, NULL, + "Failed parsing sets host to NULL"); + cmp_ok (port, "==", -1, + "Failed parsing sets port to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("/var/run/mongodb/mongodb.socket", + &host, &port) == TRUE, + "mongo_util_parse_addr() works with unix domain sockets"); + is (host, "/var/run/mongodb/mongodb.socket", + "Parsing a Unix domain socket sets host to the socket name"); + cmp_ok (port, "==", -1, + "Port is set to -1"); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("[::1]", &host, &port), + "mongo_util_parse_addr() can handle IPv6 literals without port set"); + is (host, "::1", + "Host parsed successfully"); + cmp_ok (port, "==", -1, + "Port is set to -1"); + g_free (host); + host = "deadbeef"; + port = 42; + + ok (mongo_util_parse_addr ("/var/run/mongodb/mongodb.socket:-1", + &host, &port) == TRUE, + "mongo_util_parse_addr() can parse unix domain sockets with -1 port"); + is (host, "/var/run/mongodb/mongodb.socket", + "Parsing a unix domain socket sets host to the socket name"); + cmp_ok (port, "==", -1, + "Parsing a unix domain socket with a port set to -1, works"); + g_free (host); + host = "deadbeef"; + port = 42; +} + +RUN_TEST (70, mongo_utils_parse_addr); diff --git a/tests/unit/mongo/wire/cmd_custom.c b/tests/unit/mongo/wire/cmd_custom.c new file mode 100644 index 0000000..7970aaa --- /dev/null +++ b/tests/unit/mongo/wire/cmd_custom.c @@ -0,0 +1,67 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_custom (void) +{ + bson *cmd; + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + bson_cursor *c; + gint32 pos; + + cmd = bson_new (); + bson_append_int32 (cmd, "getnonce", 1); + + ok (mongo_wire_cmd_custom (1, "test", 0, NULL) == NULL, + "mongo_wire_cmd_custom() fails with a NULL command"); + ok (mongo_wire_cmd_custom (1, "test", 0, cmd) == NULL, + "mongo_wire_cmd_custom() fails with an unfinished command"); + bson_finish (cmd); + ok (mongo_wire_cmd_custom (1, NULL, 0, cmd) == NULL, + "mongo_wire_cmd_custom() fails with a NULL db"); + + ok ((p = mongo_wire_cmd_custom (1, "test", 0, cmd)) != NULL, + "mongo_wire_cmd_custom() works"); + bson_free (cmd); + + /* Verify the header */ + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size looks fine"); + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is OK"); + cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); + + /* + * Test the created request + */ + + /* pos = zero + collection_name + NULL + skip + ret */ + pos = sizeof (gint32) + strlen ("test.$cmd") + 1 + sizeof (gint32) * 2; + ok ((cmd = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Packet contains a BSON document"); + bson_finish (cmd); + + ok ((c = bson_find (cmd, "getnonce")) != NULL, + "BSON object contains a 'getnonce' key"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, + "'getnonce' key has the correct type"); + ok (bson_cursor_next (c) == FALSE, + "'getnonce' key is the last in the object"); + + bson_cursor_free (c); + bson_free (cmd); + mongo_wire_packet_free (p); +} + +RUN_TEST (12, mongo_wire_cmd_custom); diff --git a/tests/unit/mongo/wire/cmd_delete.c b/tests/unit/mongo/wire/cmd_delete.c new file mode 100644 index 0000000..9399046 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_delete.c @@ -0,0 +1,73 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_delete (void) +{ + mongo_packet *p; + bson *s, *tmp; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + gint32 pos; + bson_cursor *c; + + s = test_bson_generate_full (); + tmp = bson_new (); + + ok (mongo_wire_cmd_delete (1, NULL, 0, s) == NULL, + "mongo_wire_cmd_delete() fails with a NULL namespace"); + ok (mongo_wire_cmd_delete (1, "test.ns", 0, NULL) == NULL, + "mongo_wire_cmd_delete() fails with a NULL selector"); + ok (mongo_wire_cmd_delete (1, "test.ns", 0, tmp) == NULL, + "mongo_wire_cmd_delete() fails with an unfinished selector"); + bson_free (tmp); + + ok ((p = mongo_wire_cmd_delete (1, "test.ns", 0, s)) != NULL, + "mongo_wire_cmd_delete() works"); + bson_free (s); + + /* Test basic header data */ + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size appears fine"); + + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is correct"); + cmp_ok (hdr.id, "==", 1, "Header ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Response ID is ok"); + + /* + * Test the constructed request + */ + + /* pos = zero + ns + NULL + flags */ + pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32); + + ok ((s = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Packet contains a valid BSON update document"); + bson_finish (s); + + ok ((c = bson_find (s, "int32")) != NULL, + "BSON contains 'int32'"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, + "int32 has correct type"); + bson_cursor_next (c); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, + "next element has correct type too"); + ok (bson_cursor_next (c) == FALSE, + "No more data after the update BSON object"); + + bson_cursor_free (c); + bson_free (s); + + mongo_wire_packet_free (p); +} + +RUN_TEST (13, mongo_wire_cmd_delete); diff --git a/tests/unit/mongo/wire/cmd_get_more.c b/tests/unit/mongo/wire/cmd_get_more.c new file mode 100644 index 0000000..5f56821 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_get_more.c @@ -0,0 +1,50 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_get_more (void) +{ + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + gint32 pos; + gint64 cid = 9876543210; + + ok (mongo_wire_cmd_get_more (1, NULL, 1, cid) == NULL, + "mongo_wire_cmd_get_more() fails with a NULL namespace"); + ok ((p = mongo_wire_cmd_get_more (1, "test.ns", 1, cid)) != NULL, + "mongo_wire_cmd_get_more() works"); + + /* Test basic header data */ + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size appears fine"); + + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is correct"); + cmp_ok (hdr.id, "==", 1, "Header ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Response ID is ok"); + + /* + * Test the request itself. + */ + + /* pos = zero + ns + NULL + ret */ + pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32); + cid = 0; + memcpy (&cid, data + pos, sizeof (cid)); + cid = GINT64_FROM_LE (cid); + + ok (cid == 9876543210, + "Included CID is correct"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (7, mongo_wire_cmd_get_more); diff --git a/tests/unit/mongo/wire/cmd_insert.c b/tests/unit/mongo/wire/cmd_insert.c new file mode 100644 index 0000000..3e84847 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_insert.c @@ -0,0 +1,83 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_insert (void) +{ + bson *ins, *tmp; + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + bson_cursor *c; + gint32 pos; + + ins = test_bson_generate_full (); + tmp = bson_new (); + + ok (mongo_wire_cmd_insert (1, NULL, ins, NULL) == NULL, + "mongo_wire_cmd_insert() fails with a NULL namespace"); + ok (mongo_wire_cmd_insert (1, "test.ns", NULL) == NULL, + "mongo_wire_cmd_insert() fails with no documents"); + ok (mongo_wire_cmd_insert (1, "test.ns", tmp, NULL) == NULL, + "mongo_wire_cmd_insert() with an unfinished document"); + bson_finish (tmp); + ok ((p = mongo_wire_cmd_insert (1, "test.ns", ins, tmp, NULL)) != NULL, + "mongo_wire_cmd_insert() works"); + bson_free (ins); + bson_free (tmp); + + /* Test basic header data */ + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size appears fine"); + + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is correct"); + cmp_ok (hdr.id, "==", 1, "Header ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Response ID is ok"); + + /* + * Test the first document + */ + + /* pos = zero + collection_name + NULL */ + pos = sizeof (gint32) + strlen ("test.ns") + 1; + ok ((ins = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "First document is included"); + bson_finish (ins); + + ok ((c = bson_find (ins, "int32")) != NULL, + "BSON contains 'int32'"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, + "int32 has correct type"); + bson_cursor_next (c); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, + "next element has correct type too"); + ok (bson_cursor_next (c) == FALSE, + "No more data after the update BSON object"); + bson_cursor_free (c); + + /* + * Test the second document + */ + pos += bson_size (ins); + ok ((tmp = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Second document is included"); + bson_finish (tmp); + cmp_ok (bson_size (tmp), "==", 5, + "Second document is empty"); + + bson_free (ins); + bson_free (tmp); + mongo_wire_packet_free (p); +} + +RUN_TEST (15, mongo_wire_cmd_insert); diff --git a/tests/unit/mongo/wire/cmd_insert_n.c b/tests/unit/mongo/wire/cmd_insert_n.c new file mode 100644 index 0000000..1c00193 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_insert_n.c @@ -0,0 +1,95 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_insert_n (void) +{ + bson *ins, *tmp; + const bson *docs[10]; + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + bson_cursor *c; + gint32 pos; + + ins = test_bson_generate_full (); + tmp = bson_new (); + + docs[0] = ins; + docs[1] = tmp; + docs[2] = ins; + docs[3] = ins; + docs[4] = NULL; + docs[5] = ins; + + ok (mongo_wire_cmd_insert_n (1, NULL, 1, docs) == NULL, + "mongo_wire_cmd_insert_n() fails with a NULL namespace"); + ok (mongo_wire_cmd_insert_n (1, "test.ns", 1, NULL) == NULL, + "mongo_wire_cmd_insert_n() fails with no documents"); + ok (mongo_wire_cmd_insert_n (1, "test.ns", 0, docs) == NULL, + "mongo_wire_cmd_insert_n() fails with no documents"); + ok (mongo_wire_cmd_insert_n (1, "test.ns", 2, docs) == NULL, + "mongo_wire_cmd_insert_n() fails with an unfinished document"); + bson_finish (tmp); + ok (mongo_wire_cmd_insert_n (1, "test.ns", 5, docs) == NULL, + "mongo_wire_cmd_insert_n() fails with a NULL document in the array"); + ok ((p = mongo_wire_cmd_insert_n (1, "test.ns", 3, docs)) != NULL, + "mongo_wire_cmd_insert() works"); + bson_free (ins); + bson_free (tmp); + + /* Test basic header data */ + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size appears fine"); + + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is correct"); + cmp_ok (hdr.id, "==", 1, "Header ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Response ID is ok"); + + /* + * Test the first document + */ + + /* pos = zero + collection_name + NULL */ + pos = sizeof (gint32) + strlen ("test.ns") + 1; + ok ((ins = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "First document is included"); + bson_finish (ins); + + ok ((c = bson_find (ins, "int32")) != NULL, + "BSON contains 'int32'"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, + "int32 has correct type"); + bson_cursor_next (c); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, + "next element has correct type too"); + ok (bson_cursor_next (c) == FALSE, + "No more data after the update BSON object"); + bson_cursor_free (c); + + /* + * Test the second document + */ + pos += bson_size (ins); + ok ((tmp = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Second document is included"); + bson_finish (tmp); + cmp_ok (bson_size (tmp), "==", 5, + "Second document is empty"); + + bson_free (ins); + bson_free (tmp); + mongo_wire_packet_free (p); +} + +RUN_TEST (17, mongo_wire_cmd_insert_n); diff --git a/tests/unit/mongo/wire/cmd_kill_cursors.c b/tests/unit/mongo/wire/cmd_kill_cursors.c new file mode 100644 index 0000000..a8a8fd9 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_kill_cursors.c @@ -0,0 +1,58 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_kill_cursors (void) +{ + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + gint32 pos, n = 0; + gint64 c1 = 9876543210, c2 = 1234567890; + + ok (mongo_wire_cmd_kill_cursors (1, 0) == NULL, + "mongo_wire_cmd_kill_cursors() should fail with zero cursors"); + ok (mongo_wire_cmd_kill_cursors (1, -1) == NULL, + "mongo_wire_cmd_kill_cursors() should fail with negative amount of " + "cursors"); + ok ((p = mongo_wire_cmd_kill_cursors (1, 2, c1, c2)) != NULL, + "mongo_wire_cmd_kill_cursors() works"); + + /* Verify the header */ + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size looks fine"); + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is OK"); + cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); + + /* + * Test the request contents + */ + c1 = c2 = 0; + /* pos = zero + n */ + pos = sizeof (gint32) + sizeof (n); + + memcpy (&n, data + sizeof (gint32), sizeof (gint32)); + memcpy (&c1, data + pos, sizeof (c1)); + memcpy (&c2, data + pos + sizeof (c1), sizeof (c2)); + + n = GINT32_FROM_LE (n); + c1 = GINT64_FROM_LE (c1); + c2 = GINT64_FROM_LE (c2); + + ok (n == 2, "Number of cursors are OK"); + ok (c1 == 9876543210, "First cursor is OK"); + ok (c2 == 1234567890, "Second cursor is OK"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (10, mongo_wire_cmd_kill_cursors); diff --git a/tests/unit/mongo/wire/cmd_query.c b/tests/unit/mongo/wire/cmd_query.c new file mode 100644 index 0000000..58eb960 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_query.c @@ -0,0 +1,117 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_query (void) +{ + bson *q, *s, *tmp; + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + bson_cursor *c; + gint32 pos; + + q = test_bson_generate_full (); + s = bson_new (); + bson_append_boolean (s, "_id", TRUE); + bson_append_boolean (s, "double", TRUE); + bson_finish (s); + + tmp = bson_new (); + + ok (mongo_wire_cmd_query (1, NULL, 0, 0, 0, q, s) == NULL, + "mongo_wire_cmd_query() fails whith a NULL namespace"); + ok (mongo_wire_cmd_query (1, "test.ns", 0, 0, 0, NULL, s) == NULL, + "mongo_wire_cmd_query() fails with a NULL query"); + ok (mongo_wire_cmd_query (1, "test.ns", 0, 0, 0, tmp, s) == NULL, + "mongo_wire_cmd_query() fails with an unfinished query"); + ok (mongo_wire_cmd_query (1, "test.ns", 0, 0, 0, q, tmp) == NULL, + "mongo_wire_cmd_query() fails with an unfinished selector"); + bson_free (tmp); + + ok ((p = mongo_wire_cmd_query (1, "test.ns", 0, 0, 10, q, NULL)) != NULL, + "mongo_wire_cmd_query() works with a NULL selector"); + + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size looks fine"); + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is OK"); + cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); + + /* pos = zero + collection_name + NULL + skip + ret */ + pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32) * 2; + ok ((tmp = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Packet contains a valid BSON query document"); + bson_finish (tmp); + + ok ((c = bson_find (tmp, "int32")) != NULL, + "BSON contains 'int32'"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, + "int32 has correct type"); + bson_cursor_next (c); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, + "next element has correct type too"); + ok (bson_cursor_next (c) == FALSE, + "No more data after the update BSON object"); + bson_cursor_free (c); + + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + pos + + bson_size (q), + "Packet header lenght is correct"); + bson_free (tmp); + mongo_wire_packet_free (p); + + /* + * Test again with a selector document + */ + + ok ((p = mongo_wire_cmd_query (1, "test.ns", 0, 0, 10, q, s)) != NULL, + "mongo_wire_cmd_query() works with a NULL selector"); + + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size looks fine"); + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is OK"); + cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); + + /* pos = zero + collection_name + NULL + skip + ret */ + pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32) * 2; + ok ((tmp = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Packet contains a valid BSON query document"); + bson_finish (tmp); + pos += bson_size (tmp); + bson_free (tmp); + bson_free (q); + bson_free (s); + + ok ((s = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Packet contains a valid BSON selector document"); + bson_finish (s); + + ok ((c = bson_find (s, "_id")) != NULL, + "BSON contains '_id'"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_BOOLEAN, + "_id has correct type"); + bson_cursor_next (c); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_BOOLEAN, + "next element has correct type too"); + + bson_cursor_free (c); + bson_free (s); + mongo_wire_packet_free (p); +} + +RUN_TEST (25, mongo_wire_cmd_query); diff --git a/tests/unit/mongo/wire/cmd_update.c b/tests/unit/mongo/wire/cmd_update.c new file mode 100644 index 0000000..95a2a50 --- /dev/null +++ b/tests/unit/mongo/wire/cmd_update.c @@ -0,0 +1,97 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_cmd_update (void) +{ + bson *sel, *upd, *tmp; + mongo_packet *p; + + mongo_packet_header hdr; + const guint8 *data; + gint32 data_size; + + bson_cursor *c; + gint32 pos; + + sel = bson_new (); + bson_append_null (sel, "_id"); + bson_finish (sel); + + upd = test_bson_generate_full (); + + ok (mongo_wire_cmd_update (1, NULL, 0, sel, upd) == NULL, + "mongo_wire_cmd_update() with a NULL namespace should fail"); + ok (mongo_wire_cmd_update (1, "test.ns", 0, NULL, upd) == NULL, + "mongo_wire_cmd_update() with a NULL selector should fail"); + ok (mongo_wire_cmd_update (1, "test.ns", 0, sel, NULL) == NULL, + "mongo_wire_cmd_update() with a NULL update should fail"); + + tmp = bson_new (); + ok (mongo_wire_cmd_update (1, "test.ns", 0, tmp, upd) == NULL, + "mongo_wire_cmd_update() fails with an unfinished selector"); + ok (mongo_wire_cmd_update (1, "test.ns", 0, sel, tmp) == NULL, + "mongo_wire_cmd_update() fails with an unfinished update"); + bson_free (tmp); + + ok ((p = mongo_wire_cmd_update (1, "test.ns", 0, sel, upd)) != NULL, + "mongo_wire_cmd_update() works"); + + bson_free (sel); + + mongo_wire_packet_get_header (p, &hdr); + cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, + "Packet data size looks fine"); + cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, + "Packet header length is OK"); + cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); + cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); + + /* + * Verify the selector object. + */ + + /* pos = zero + collection_name + NULL + flags */ + pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32); + ok ((sel = bson_new_from_data (data + pos, (gint32)data[pos] - 1)) != NULL, + "Packet contains a valid BSON selector document"); + bson_finish (sel); + + ok ((c = bson_find (sel, "_id")) != NULL, + "BSON contains an _id"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_NULL, + "_id has correct type"); + bson_cursor_free (c); + bson_free (sel); + + /* + * Verify the update object + */ + pos += (gint32)data[pos]; + ok ((tmp = bson_new_from_data (data + pos, + bson_stream_doc_size (data, pos) - 1)) != NULL, + "Packet contains a valid BSON update document"); + bson_finish (tmp); + cmp_ok (bson_size (upd), "==", bson_size (tmp), + "Packet's update document has the correct size"); + + ok ((c = bson_find (tmp, "int32")) != NULL, + "BSON contains 'int32'"); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, + "int32 has correct type"); + bson_cursor_next (c); + cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, + "next element has correct type too"); + ok (bson_cursor_next (c) == FALSE, + "No more data after the update BSON object"); + + bson_cursor_free (c); + bson_free (tmp); + bson_free (upd); + mongo_wire_packet_free (p); +} + +RUN_TEST (19, mongo_wire_cmd_update); diff --git a/tests/unit/mongo/wire/packet_get_set_data.c b/tests/unit/mongo/wire/packet_get_set_data.c new file mode 100644 index 0000000..2f06b8f --- /dev/null +++ b/tests/unit/mongo/wire/packet_get_set_data.c @@ -0,0 +1,65 @@ +#include "tap.h" +#include "test.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_packet_get_set_data (void) +{ + mongo_packet *p; + mongo_packet_header h; + guint8 data[32768]; + const guint8 *idata; + + p = mongo_wire_packet_new (); + memset (data, 'x', sizeof (data)); + + ok (mongo_wire_packet_get_data (NULL, &idata) == -1, + "mongo_wire_packet_get_data() with a NULL packet should fail"); + ok (mongo_wire_packet_get_data (p, NULL) == -1, + "mongo_wire_packet_get_data() with NULL destination should fail"); + ok (mongo_wire_packet_get_data (p, &idata) == -1, + "mongo_wire_packet_get_data() with an empty packet should fail"); + ok (mongo_wire_packet_set_data (NULL, (const guint8 *)&data, + sizeof (data)) == FALSE, + "mongo_wire_packet_set_data() with a NULL packet should fail"); + ok (mongo_wire_packet_set_data (p, NULL, sizeof (data)) == FALSE, + "mongo_wire_packet_set_data() with NULL data should fail"); + ok (mongo_wire_packet_set_data (p, (const guint8 *)&data, 0) == FALSE, + "mongo_wire_packet_set_data() with zero size should fail"); + ok (mongo_wire_packet_set_data (p, (const guint8 *)&data, -1) == FALSE, + "mongo_wire_packet_set_data() with negative size should fail"); + + ok (mongo_wire_packet_set_data (p, (const guint8 *)&data, + sizeof (data)), + "mongo_wire_packet_set_data() works"); + cmp_ok (mongo_wire_packet_get_data (p, &idata), "==", sizeof (data), + "mongo_wire_packet_get_data() works"); + + mongo_wire_packet_get_header (p, &h); + + cmp_ok (h.length, "==", sizeof (data) + sizeof (mongo_packet_header), + "Packet length is updated properly"); + ok (memcmp (data, idata, sizeof (data)) == 0, + "Setting & retrieving data works"); + + memset (data, 'a', sizeof (data)); + + ok (mongo_wire_packet_set_data (p, (const guint8 *)&data, + sizeof (data) / 2), + "Re-setting the data works"); + cmp_ok (mongo_wire_packet_get_data (p, &idata), "==", sizeof (data) / 2, + "Retrieving the data works still"); + + mongo_wire_packet_get_header (p, &h); + + cmp_ok (h.length, "==", sizeof (data) / 2 + sizeof (mongo_packet_header), + "Packet length is updated properly"); + ok (memcmp (data, idata, sizeof (data) / 2) == 0, + "Setting & retrieving data works"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (15, mongo_wire_packet_get_set_data); diff --git a/tests/unit/mongo/wire/packet_get_set_header.c b/tests/unit/mongo/wire/packet_get_set_header.c new file mode 100644 index 0000000..38e0ea7 --- /dev/null +++ b/tests/unit/mongo/wire/packet_get_set_header.c @@ -0,0 +1,58 @@ +#include "tap.h" +#include "test.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_packet_get_set_header (void) +{ + mongo_packet *p; + mongo_packet_header ph1, ph2; + + p = mongo_wire_packet_new (); + + ok (mongo_wire_packet_get_header (NULL, &ph2) == FALSE, + "mongo_wire_packet_get_header() should fail with a NULL packet"); + ok (mongo_wire_packet_get_header (p, NULL) == FALSE, + "mongo_wire_packet_get_header() should fail with a NULL header"); + ok (mongo_wire_packet_set_header (NULL, &ph1) == FALSE, + "mongo_wire_packet_set_header() should fail with a NULL packet"); + ok (mongo_wire_packet_set_header (p, NULL) == FALSE, + "mongo_wire_packet_set_header() should fail with a NULL header"); + + ok (mongo_wire_packet_get_header (p, &ph2), + "mongo_wire_packet_get_header() works on a fresh packet"); + cmp_ok (ph2.length, "==", sizeof (mongo_packet_header), + "Initial packet length is the length of the header"); + + ph1.length = sizeof (mongo_packet_header); + ph1.id = 1; + ph1.resp_to = 0; + ph1.opcode = 1000; + + memset (&ph2, 0, sizeof (mongo_packet_header)); + + ok (mongo_wire_packet_set_header (p, &ph1), + "mongo_wire_packet_set_header() works"); + ok (mongo_wire_packet_get_header (p, &ph2), + "mongo_wire_packet_get_header() works"); + + cmp_ok (ph1.length, "==", ph2.length, + "Packet lengths match"); + cmp_ok (ph1.id, "==", ph2.id, + "Sequence IDs match"); + cmp_ok (ph1.resp_to, "==", ph2.resp_to, + "Response IDs match"); + cmp_ok (ph1.opcode, "==", ph2.opcode, + "OPCodes match"); + + ph1.length = GINT32_TO_LE (1); + ok (mongo_wire_packet_set_header (p, &ph1) == FALSE, + "Setting a packet with length shorter than the header " + "returns an error"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (13, mongo_wire_packet_get_set_header); diff --git a/tests/unit/mongo/wire/packet_get_set_header_raw.c b/tests/unit/mongo/wire/packet_get_set_header_raw.c new file mode 100644 index 0000000..d97a8b3 --- /dev/null +++ b/tests/unit/mongo/wire/packet_get_set_header_raw.c @@ -0,0 +1,56 @@ +#include "tap.h" +#include "test.h" +#include "mongo-wire.h" + +#include "libmongo-private.h" + +#include <string.h> + +void +test_mongo_wire_packet_get_set_header_raw (void) +{ + mongo_packet *p; + mongo_packet_header ph1, ph2; + + p = mongo_wire_packet_new (); + + ok (mongo_wire_packet_get_header_raw (NULL, &ph2) == FALSE, + "mongo_wire_packet_get_header_raw() should fail with a NULL packet"); + ok (mongo_wire_packet_get_header_raw (p, NULL) == FALSE, + "mongo_wire_packet_get_header_raw() should fail with a NULL header"); + ok (mongo_wire_packet_set_header_raw (NULL, &ph1) == FALSE, + "mongo_wire_packet_set_header_raw() should fail with a NULL packet"); + ok (mongo_wire_packet_set_header_raw (p, NULL) == FALSE, + "mongo_wire_packet_set_header_raw() should fail with a NULL header"); + + ok (mongo_wire_packet_get_header_raw (p, &ph2), + "mongo_wire_packet_get_header_raw() works on a fresh packet"); + /* Need to convert from LE, because _new() sets the length to LE. */ + cmp_ok (GINT32_FROM_LE (ph2.length), "==", sizeof (mongo_packet_header), + "Initial packet length is the length of the header"); + + ph1.length = sizeof (mongo_packet_header); + ph1.id = 1; + ph1.resp_to = 0; + ph1.opcode = 1000; + + memset (&ph2, 0, sizeof (mongo_packet_header)); + + ok (mongo_wire_packet_set_header_raw (p, &ph1), + "mongo_wire_packet_set_header_raw() works"); + ok (mongo_wire_packet_get_header_raw (p, &ph2), + "mongo_wire_packet_get_header_raw() works"); + + cmp_ok (ph1.length, "==", ph2.length, + "Packet lengths match"); + cmp_ok (ph1.id, "==", ph2.id, + "Sequence IDs match"); + cmp_ok (ph1.resp_to, "==", ph2.resp_to, + "Response IDs match"); + cmp_ok (ph1.opcode, "==", ph2.opcode, + "OPCodes match"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (12, mongo_wire_packet_get_set_header_raw); diff --git a/tests/unit/mongo/wire/packet_new.c b/tests/unit/mongo/wire/packet_new.c new file mode 100644 index 0000000..4940542 --- /dev/null +++ b/tests/unit/mongo/wire/packet_new.c @@ -0,0 +1,20 @@ +#include "tap.h" +#include "test.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_packet_new (void) +{ + mongo_packet *p; + + ok ((p = mongo_wire_packet_new ()) != NULL, + "mongo_wire_packet_new() works"); + mongo_wire_packet_free (NULL); + pass ("mongo_wire_packet_free(NULL) works"); + mongo_wire_packet_free (p); + pass ("mongo_wire_packet_free() works"); +} + +RUN_TEST (3, mongo_wire_packet_new); diff --git a/tests/unit/mongo/wire/reply_packet_get_data.c b/tests/unit/mongo/wire/reply_packet_get_data.c new file mode 100644 index 0000000..e22f142 --- /dev/null +++ b/tests/unit/mongo/wire/reply_packet_get_data.c @@ -0,0 +1,52 @@ +#include "test.h" +#include "tap.h" +#include "bson.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_reply_packet_get_data (void) +{ + mongo_packet *p; + mongo_packet_header h; + const guint8 *data; + bson *b; + + p = mongo_wire_packet_new (); + memset (&h, 0, sizeof (mongo_packet_header)); + h.opcode = 0; + h.length = sizeof (mongo_packet_header); + mongo_wire_packet_set_header (p, &h); + + ok (mongo_wire_reply_packet_get_data (NULL, &data) == FALSE, + "mongo_wire_reply_packet_get_data() fails with a NULL packet"); + ok (mongo_wire_reply_packet_get_data (p, NULL) == FALSE, + "mongo_wire_reply_packet_get_data() fails with a NULL destination"); + ok (mongo_wire_reply_packet_get_data (p, &data) == FALSE, + "mongo_wire_reply_packet_get_data() fails with a non-reply packet"); + + h.opcode = 1; + mongo_wire_packet_set_header (p, &h); + + ok (mongo_wire_reply_packet_get_data (p, &data) == FALSE, + "mongo_wire_reply_packet_get_data() fails if the packet has " + "no data"); + + mongo_wire_packet_free (p); + + p = test_mongo_wire_generate_reply (TRUE, 2, TRUE); + + ok (mongo_wire_reply_packet_get_data (p, &data), + "mongo_wire_reply_packet_get_data() works"); + + b = test_bson_generate_full (); + + ok (memcmp (data, bson_data (b), bson_size (b)) == 0, + "The returned data is correct"); + + bson_free (b); + mongo_wire_packet_free (p); +} + +RUN_TEST (6, mongo_wire_reply_packet_get_data); diff --git a/tests/unit/mongo/wire/reply_packet_get_header.c b/tests/unit/mongo/wire/reply_packet_get_header.c new file mode 100644 index 0000000..36b548c --- /dev/null +++ b/tests/unit/mongo/wire/reply_packet_get_header.c @@ -0,0 +1,54 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" + +#include <string.h> + +void +test_mongo_wire_reply_packet_get_header (void) +{ + mongo_packet *p; + mongo_packet_header h; + mongo_reply_packet_header rh; + + p = mongo_wire_packet_new (); + memset (&h, 0, sizeof (mongo_packet_header)); + h.opcode = 1; + h.length = sizeof (mongo_packet_header); + + mongo_wire_packet_set_header (p, &h); + + ok (mongo_wire_reply_packet_get_header (NULL, &rh) == FALSE, + "mongo_wire_reply_packet_get_header() fails with a NULL packet"); + ok (mongo_wire_reply_packet_get_header (p, NULL) == FALSE, + "mongo_wire_reply_packet_get_header() fails with a NULL header"); + + ok (mongo_wire_reply_packet_get_header (p, &rh) == FALSE, + "mongo_wire_reply_packet_get_header() fails if the packet has " + "no reply header"); + + h.opcode = 2; + mongo_wire_packet_set_header (p, &h); + ok (mongo_wire_reply_packet_get_header (p, &rh) == FALSE, + "mongo_wire_reply_packet_get_header() fails if the packet is " + "not a reply packet"); + + mongo_wire_packet_free (p); + + p = test_mongo_wire_generate_reply (TRUE, 0, FALSE); + + ok (mongo_wire_reply_packet_get_header (p, &rh), + "mongo_wire_reply_packet_get_header() works"); + cmp_ok (rh.flags, "==", 0, + "Reply flags are correct"); + ok (rh.cursor_id == (gint64)12345, + "Cursor ID is correct"); + cmp_ok (rh.start, "==", 0, + "Reply start document is OK"); + cmp_ok (rh.returned, "==", 0, + "Number of documents returned is OK"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (9, mongo_wire_reply_packet_get_header); diff --git a/tests/unit/mongo/wire/reply_packet_get_nth_document.c b/tests/unit/mongo/wire/reply_packet_get_nth_document.c new file mode 100644 index 0000000..68d9fed --- /dev/null +++ b/tests/unit/mongo/wire/reply_packet_get_nth_document.c @@ -0,0 +1,68 @@ +#include "test.h" +#include "tap.h" +#include "mongo-wire.h" +#include "bson.h" + +#include <string.h> + +void +test_mongo_wire_reply_packet_get_nth_document (void) +{ + mongo_packet *p; + bson *b, *doc; + mongo_packet_header h; + + p = mongo_wire_packet_new (); + memset (&h, 0, sizeof (mongo_packet_header)); + h.opcode = 2; + h.length = sizeof (mongo_packet_header); + mongo_wire_packet_set_header (p, &h); + + ok (mongo_wire_reply_packet_get_nth_document (NULL, 1, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails with a NULL packet"); + ok (mongo_wire_reply_packet_get_nth_document (p, 0, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails with n = 0"); + ok (mongo_wire_reply_packet_get_nth_document (p, -42, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails with n < 0"); + ok (mongo_wire_reply_packet_get_nth_document (p, 1, NULL) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails with a NULL " + "destination"); + + ok (mongo_wire_reply_packet_get_nth_document (p, 1, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails with a " + "non-reply packet"); + + h.opcode = 1; + mongo_wire_packet_set_header (p, &h); + + ok (mongo_wire_reply_packet_get_nth_document (p, 1, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails with an " + "incomplete reply packet"); + + mongo_wire_packet_free (p); + + p = test_mongo_wire_generate_reply (TRUE, 0, FALSE); + ok (mongo_wire_reply_packet_get_nth_document (p, 1, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails if there are " + "no documents to return"); + mongo_wire_packet_free (p); + + p = test_mongo_wire_generate_reply (TRUE, 2, TRUE); + ok (mongo_wire_reply_packet_get_nth_document (p, 2, &doc), + "mongo_wire_reply_packet_get_nth_document() works"); + b = test_bson_generate_full (); + bson_finish (doc); + + ok (memcmp (bson_data (b), bson_data (doc), bson_size (doc)) == 0, + "Returned document is correct"); + bson_free (doc); + bson_free (b); + + ok (mongo_wire_reply_packet_get_nth_document (p, 3, &doc) == FALSE, + "mongo_wire_reply_packet_get_nth_document() fails if the requested " + "document does not exist"); + + mongo_wire_packet_free (p); +} + +RUN_TEST (10, mongo_wire_reply_packet_get_nth_document); |