summaryrefslogtreecommitdiff
path: root/tests/func/mongo/sync-gridfs-stream/f_sync_gridfs_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/func/mongo/sync-gridfs-stream/f_sync_gridfs_stream.c')
-rw-r--r--tests/func/mongo/sync-gridfs-stream/f_sync_gridfs_stream.c501
1 files changed, 501 insertions, 0 deletions
diff --git a/tests/func/mongo/sync-gridfs-stream/f_sync_gridfs_stream.c b/tests/func/mongo/sync-gridfs-stream/f_sync_gridfs_stream.c
new file mode 100644
index 0000000..a2c3690
--- /dev/null
+++ b/tests/func/mongo/sync-gridfs-stream/f_sync_gridfs_stream.c
@@ -0,0 +1,501 @@
+#include "test.h"
+#include "mongo.h"
+#include "compat.h"
+
+#define FILE_SIZE 1024 * 1024 + 12345
+#define BUFFER_SIZE 64 * 1024
+
+gchar *write_md5 = NULL;
+static gint seq = 1;
+
+void
+test_func_sync_gridfs_stream_without_oid_init (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+
+ 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() fails without mongo_util_oid_init()");
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_write (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ bson *meta;
+ guint8 *data, *oid;
+ gint pos = 0;
+ gint filler = 0;
+ gboolean write_ok = TRUE;
+ GChecksum *chk;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+
+ oid = mongo_util_oid_new (seq++);
+ meta = bson_build (BSON_TYPE_STRING, "filename", "libmongo-test-stream", -1,
+ BSON_TYPE_OID, "_id", oid,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+ g_free (oid);
+
+ stream = mongo_sync_gridfs_stream_new (gfs, meta);
+ ok (stream != NULL,
+ "mongo_sync_gridfs_stream_new() works");
+ bson_free (meta);
+
+ data = g_malloc (BUFFER_SIZE);
+
+ chk = g_checksum_new (G_CHECKSUM_MD5);
+
+ while (pos < FILE_SIZE)
+ {
+ gint csize = BUFFER_SIZE;
+
+ if (csize + pos > FILE_SIZE)
+ csize = FILE_SIZE - pos;
+
+ memset (data, filler++, BUFFER_SIZE);
+
+ g_checksum_update (chk, data, csize);
+
+ write_ok &= mongo_sync_gridfs_stream_write (stream, data, csize);
+ pos += csize;
+ }
+ ok (write_ok == TRUE,
+ "All stream_write()s succeeded");
+
+ write_md5 = g_strdup (g_checksum_get_string (chk));
+ g_checksum_free (chk);
+
+ note ("File MD5: %s\n", write_md5);
+
+ g_free (data);
+ ok (mongo_sync_gridfs_stream_close (stream) == TRUE,
+ "mongo_sync_gridfs_stream_close() works");
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_write_binary_subtype (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ bson *meta, *update;
+ guint8 *data, *oid;
+ gboolean write_ok = TRUE;
+ guint32 size = GINT32_TO_LE(BUFFER_SIZE);
+ gchar *ns;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+
+ oid = mongo_util_oid_new (seq++);
+ meta = bson_build (BSON_TYPE_STRING, "filename", "libmongo-test-stream-bintype", -1,
+ BSON_TYPE_OID, "_id", oid,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+
+ stream = mongo_sync_gridfs_stream_new (gfs, meta);
+ ok (stream != NULL,
+ "mongo_sync_gridfs_stream_new() works");
+ bson_free (meta);
+
+ data = g_malloc (BUFFER_SIZE + 4);
+ memcpy (data, &size, 4);
+ memset (data + 4, 'x', BUFFER_SIZE);
+ write_ok = mongo_sync_gridfs_stream_write (stream, data + 4, BUFFER_SIZE);
+ ok (write_ok == TRUE,
+ "All stream_write()s succeeded");
+
+ ok (mongo_sync_gridfs_stream_close (stream) == TRUE,
+ "mongo_sync_gridfs_stream_close() works");
+
+ meta = bson_build (BSON_TYPE_OID, "files_id", oid,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ update = bson_build_full (BSON_TYPE_DOCUMENT, "$set", TRUE,
+ bson_build (BSON_TYPE_BINARY, "data",
+ BSON_BINARY_SUBTYPE_BINARY,
+ data, BUFFER_SIZE + 4,
+ BSON_TYPE_NONE),
+ BSON_TYPE_NONE);
+ bson_finish (update);
+ g_free (data);
+
+ ns = g_strconcat (config.gfs_prefix, ".chunks", NULL);
+ mongo_sync_cmd_update (conn, ns, MONGO_WIRE_FLAG_UPDATE_UPSERT,
+ meta, update);
+ bson_free (meta);
+ bson_free (update);
+ g_free (ns);
+ g_free (oid);
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_write_invalid (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ bson *meta;
+ gchar *ns;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+ ns = g_strconcat (config.gfs_prefix, ".files", NULL);
+
+ /* Try to write a file with a custom, non-OID _id */
+ meta = bson_build (BSON_TYPE_STRING, "filename", "lmc-invalid-id", -1,
+ BSON_TYPE_STRING, "_id", "Short and stout", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_new (gfs, meta);
+ ok (stream == NULL,
+ "mongo_sync_gridfs_stream_new() should fail if meta has an invalid _id");
+ bson_free (meta);
+
+ /* Write a file with a non-OID _id, bypassing the GridFS API. */
+ meta = bson_build (BSON_TYPE_STRING, "_id", "Short and stout", -1,
+ BSON_TYPE_STRING, "my-id", "stream:string-id", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ mongo_sync_cmd_insert (conn, ns, meta, NULL);
+ bson_free (meta);
+
+ /* Insert metadata with invalid length type. */
+ meta = bson_build (BSON_TYPE_DOUBLE, "length", 1.0,
+ BSON_TYPE_STRING, "my-id", "stream:invalid-length", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ mongo_sync_cmd_insert (conn, ns, meta, NULL);
+ bson_free (meta);
+
+ /* Insert metadata with invalid chunkSize type. */
+ meta = bson_build (BSON_TYPE_INT32, "length", 10,
+ BSON_TYPE_DOUBLE, "chunkSize", 12.5,
+ BSON_TYPE_STRING, "my-id", "stream:invalid-chunkSize", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ mongo_sync_cmd_insert (conn, ns, meta, NULL);
+ bson_free (meta);
+
+ /* Insert a valid metadata, without chunks. */
+ meta = bson_build (BSON_TYPE_INT32, "length", 32,
+ BSON_TYPE_INT32, "chunkSize", 12,
+ BSON_TYPE_UTC_DATETIME, "uploadDate", (gint64)1234,
+ BSON_TYPE_STRING, "md5", "deadbeef", -1,
+ BSON_TYPE_STRING, "my-id", "stream:no-chunks", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ mongo_sync_cmd_insert (conn, ns, meta, NULL);
+ bson_free (meta);
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_read (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ guint8 data[12345];
+ gint64 pos = 0;
+ bson *meta;
+
+ GChecksum *chk;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+ meta = bson_build (BSON_TYPE_STRING, "filename", "libmongo-test-stream", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ ok (stream != NULL,
+ "mongo_sync_gridfs_stream_find() works");
+ bson_free (meta);
+
+ chk = g_checksum_new (G_CHECKSUM_MD5);
+
+ while (pos < FILE_SIZE)
+ {
+ gint64 r;
+
+ r = mongo_sync_gridfs_stream_read (stream, data, sizeof (data));
+ if (r == -1)
+ break;
+
+ g_checksum_update (chk, data, r);
+ pos += r;
+ }
+
+ cmp_ok (pos, "==", FILE_SIZE,
+ "mongo_sync_gridfs_stream_read() works");
+ is (g_checksum_get_string (chk), write_md5,
+ "md5sums match");
+
+ g_checksum_free (chk);
+ ok (mongo_sync_gridfs_stream_close (stream) == TRUE,
+ "mongo_sync_gridfs_stream_close() works");
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_read_binary_subtype (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ guint8 *data;
+ gint64 r;
+ bson *meta;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+ meta = bson_build (BSON_TYPE_STRING, "filename", "libmongo-test-stream-bintype", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ ok (stream != NULL,
+ "mongo_sync_gridfs_stream_find() works");
+ bson_free (meta);
+
+ data = g_malloc (BUFFER_SIZE);
+ r = mongo_sync_gridfs_stream_read (stream, data, BUFFER_SIZE);
+ cmp_ok (r, "==", BUFFER_SIZE,
+ "mongo_sync_gridfs_stream_read() works");
+
+ ok (mongo_sync_gridfs_stream_close (stream) == TRUE,
+ "mongo_sync_gridfs_stream_close() works");
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_meta (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ bson *meta;
+ const guint8 *id;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+ meta = bson_build (BSON_TYPE_STRING, "filename", "libmongo-test-stream", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ bson_free (meta);
+
+ id = mongo_sync_gridfs_file_get_id (stream);
+ ok (id != NULL,
+ "mongo_sync_gridfs_file_get_id() works on streams");
+
+ ok (mongo_sync_gridfs_file_get_md5 (stream) == NULL,
+ "mongo_sync_gridfs_file_get_md5() fails on streams");
+ ok (mongo_sync_gridfs_file_get_date (stream) == -1,
+ "mongo_sync_gridfs_file_get_date() fails on streams");
+ ok (mongo_sync_gridfs_file_get_metadata (stream) == NULL,
+ "mongo_sync_gridfs_file_get_metadata() fails on streams");
+
+ mongo_sync_gridfs_stream_close (stream);
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_read_invalid (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ guint8 data[1245];
+ gint64 r;
+ bson *meta;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+
+ /* ---- */
+ meta = bson_build (BSON_TYPE_STRING, "my-id", "stream:string-id", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ ok (stream == NULL,
+ "mongo_sync_gridfs_stream_find() should fail if _id is non-OID");
+ bson_free (meta);
+
+ /* ---- */
+ meta = bson_build (BSON_TYPE_STRING, "my-id", "stream:invalid-length", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ ok (stream == NULL,
+ "mongo_sync_gridfs_stream_find() should fail with invalid metadata");
+ bson_free (meta);
+
+ /* ---- */
+ meta = bson_build (BSON_TYPE_STRING, "my-id", "stream:invalid-chunkSize", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ ok (stream == NULL,
+ "mongo_sync_gridfs_stream_find() should fail with invalid metadata");
+ bson_free (meta);
+
+ /* no-chunk test */
+ meta = bson_build (BSON_TYPE_STRING, "my-id", "stream:no-chunks", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ ok (stream != NULL,
+ "mongo_sync_gridfs_stream_find() works [stream:no-chunks]");
+ bson_free (meta);
+
+ r = mongo_sync_gridfs_stream_read (stream, data, sizeof (data));
+ cmp_ok (r, "==", -1,
+ "Reading from a chunk-less file should fail");
+
+ mongo_sync_gridfs_stream_close (stream);
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_seek (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ bson *meta;
+ guint8 *chunk1, *chunk2, *chunk3;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+ meta = bson_build (BSON_TYPE_STRING, "filename", "libmongo-test-stream", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ bson_free (meta);
+
+ chunk1 = g_malloc (300 * 1024);
+ chunk2 = g_malloc (300 * 1024);
+ chunk3 = g_malloc (300 * 1024);
+
+ cmp_ok (mongo_sync_gridfs_stream_read (stream, chunk1, 300 * 1024), "==",
+ 300 * 1024,
+ "reading the first chunk works");
+ cmp_ok (mongo_sync_gridfs_stream_read (stream, chunk2, 300 * 1024), "==",
+ 300 * 1024,
+ "reading the second chunk works");
+ ok (memcmp (chunk1, chunk2, 300 * 1024) != 0,
+ "The two chunks differ, as they should");
+
+ ok (mongo_sync_gridfs_stream_seek (stream, 0, SEEK_END) == TRUE,
+ "mongo_sync_gridfs_stream_seek() works, with SEEK_END");
+ cmp_ok (stream->file.offset, "==", stream->file.length,
+ "mongo_sync_gridfs_stream_seek() can seek to the end");
+
+ ok (mongo_sync_gridfs_stream_seek (stream, 1, SEEK_SET) == TRUE,
+ "mongo_sync_gridfs_stream_seek() works, with SEEK_SET");
+ cmp_ok (stream->file.offset, "==", 1,
+ "mongo_sync_gridfs_stream_seek()'s SEEK_SET works");
+ ok (mongo_sync_gridfs_stream_seek (stream, 1, SEEK_SET) == TRUE,
+ "mongo_sync_gridfs_stream_seek() works, with SEEK_SET");
+
+ ok (mongo_sync_gridfs_stream_seek (stream, -1, SEEK_CUR) == TRUE,
+ "mongo_sync_gridfs_stream_seek() works, with SEEK_CUR");
+ cmp_ok (stream->file.offset, "==", 0,
+ "mongo_sync_gridfs_stream_seek()'s SEEK_CUR works");
+ ok (mongo_sync_gridfs_stream_seek (stream, 0, SEEK_CUR) == TRUE,
+ "mongo_sync_gridfs_stream_seek() works, with SEEK_CUR");
+
+ cmp_ok (mongo_sync_gridfs_stream_read (stream, chunk3, 300 * 1024), "==",
+ 300 * 1024,
+ "reading after seeking works");
+
+ ok (memcmp (chunk1, chunk3, 300 * 1024) == 0,
+ "After seeking, we're at the beginning");
+
+ mongo_sync_gridfs_stream_close (stream);
+ g_free (chunk3);
+ g_free (chunk2);
+ g_free (chunk1);
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream_seek_invalid (void)
+{
+ mongo_sync_connection *conn;
+ mongo_sync_gridfs *gfs;
+ mongo_sync_gridfs_stream *stream;
+ bson *meta;
+
+ conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE);
+ gfs = mongo_sync_gridfs_new (conn, config.gfs_prefix);
+ meta = bson_build (BSON_TYPE_STRING, "my-id", "stream:no-chunks", -1,
+ BSON_TYPE_NONE);
+ bson_finish (meta);
+
+ stream = mongo_sync_gridfs_stream_find (gfs, meta);
+ bson_free (meta);
+
+ ok (mongo_sync_gridfs_stream_seek (stream, 1, SEEK_SET) == FALSE,
+ "mongo_sync_gridfs_stream_seek() should fail with no chunks");
+
+ mongo_sync_gridfs_stream_close (stream);
+
+ mongo_sync_gridfs_free (gfs, TRUE);
+}
+
+void
+test_func_sync_gridfs_stream (void)
+{
+ test_func_sync_gridfs_stream_without_oid_init ();
+
+ mongo_util_oid_init (0);
+
+ test_func_sync_gridfs_stream_write ();
+ test_func_sync_gridfs_stream_write_binary_subtype ();
+ test_func_sync_gridfs_stream_write_invalid ();
+ test_func_sync_gridfs_stream_read ();
+ test_func_sync_gridfs_stream_read_binary_subtype ();
+ test_func_sync_gridfs_stream_read_invalid ();
+ test_func_sync_gridfs_stream_seek ();
+ test_func_sync_gridfs_stream_seek_invalid ();
+ test_func_sync_gridfs_stream_meta ();
+
+ g_free (write_md5);
+}
+
+RUN_NET_TEST (38, func_sync_gridfs_stream);