[rygel] tests: Add test for ItemCreator class
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] tests: Add test for ItemCreator class
- Date: Mon, 20 Feb 2012 09:34:40 +0000 (UTC)
commit e5b60f1ffa86a780934470567b95ca0f9543e8b0
Author: Jens Georg <mail jensge org>
Date: Sun Dec 25 21:00:57 2011 +0100
tests: Add test for ItemCreator class
tests/Makefile.am | 11 +-
tests/rygel-item-creator-test.vala | 392 +++++++++++++++++++++++++++
tests/rygel-item-creator.vala | 1 +
tests/rygel-relational-expression.vala | 1 +
tests/rygel-search-expression.vala | 1 +
tests/rygel-state-machine_item-creator.vala | 1 +
6 files changed, 406 insertions(+), 1 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a05d0be..5739c99 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -9,6 +9,7 @@ AM_CFLAGS = $(LIBGUPNP_CFLAGS) \
$(GEE_CFLAGS) \
$(UUID_CFLAGS) \
$(LIBSOUP_CFLAGS) \
+ $(LIBGUPNP_DLNA_CFLAGS) \
-I$(top_srcdir) -DDATA_DIR='"$(shareddir)"' \
-include config.h -DG_LOG_DOMAIN='"Rygel"' \
$(COVERAGE_CFLAGS)
@@ -22,12 +23,14 @@ LDADD = $(LIBGUPNP_LIBS) \
$(GEE_LIBS) \
$(UUID_LIBS) \
$(LIBSOUP_LIBS) \
+ $(LIBGUPNP_DLNA_LIBS) \
$(COVERAGE_LIBS)
AM_VALAFLAGS = --disable-warnings --thread \
--pkg gupnp-1.0 --pkg gupnp-av-1.0 --pkg dbus-glib-1 \
--pkg gconf-2.0 --pkg gstreamer-0.10 --pkg gstreamer-base-0.10 \
--pkg gio-2.0 --pkg gee-1.0 --pkg gstreamer-pbutils-0.10 \
+ --pkg gupnp-dlna-1.0 -g
$(COVERAGE_VALAFLAGS)
check_PROGRAMS = rygel-http-item-uri-test \
@@ -37,7 +40,8 @@ check_PROGRAMS = rygel-http-item-uri-test \
rygel-http-get-test \
rygel-album-art-spec-test \
rygel-http-post-test \
- rygel-searchable-container-test
+ rygel-searchable-container-test \
+ rygel-item-creator-test
TESTS = $(check_PROGRAMS)
@@ -82,6 +86,11 @@ rygel_searchable_container_test_SOURCES = \
rygel-searchable-container.vala \
rygel-searchable-container-test.vala
+rygel_item_creator_test_SOURCES = rygel-item-creator-test.vala \
+ rygel-item-creator.vala \
+ rygel-state-machine_item-creator.vala \
+ rygel-relational-expression.vala \
+ rygel-search-expression.vala
if ALWAYS_TEST
all-local: check
diff --git a/tests/rygel-item-creator-test.vala b/tests/rygel-item-creator-test.vala
new file mode 100644
index 0000000..90c881c
--- /dev/null
+++ b/tests/rygel-item-creator-test.vala
@@ -0,0 +1,392 @@
+[CCode (cname = "uuid_generate", cheader_filename = "uuid/uuid.h")]
+internal extern static void uuid_generate ([CCode (array_length = false)]
+ uchar[] uuid);
+[CCode (cname = "uuid_unparse", cheader_filename = "uuid/uuid.h")]
+internal extern static void uuid_unparse ([CCode (array_length = false)]
+ uchar[] uuid,
+ [CCode (array_length = false)]
+ uchar[] output);
+
+public const string DIDL_ITEM = """<?xml version="1.0" encoding="UTF-8"?>
+<DIDL-Lite
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
+ xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/
+ http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd
+ urn:schemas-upnp-org:metadata-1-0/upnp/
+ http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd">
+ <item id="" parentID="0" restricted="0">
+ <dc:title>New Song</dc:title>
+ <upnp:class>object.item.audioItem</upnp:class>
+ <res protocolInfo="*:*:*:*" />
+ </item>
+</DIDL-Lite>""";
+
+public class Rygel.ServiceAction : GLib.Object {
+ public int error_code;
+ public string error_message;
+ public string id;
+ public string elements;
+
+ public ServiceAction (string? container_id,
+ string? elements) {
+ this.id = container_id;
+ this.elements = elements;
+ }
+
+ public void @return() {}
+ public void return_error (int code, string message) {
+ this.error_code = code;
+ this.error_message = message;
+ }
+
+ public new void @get (string arg1_name,
+ Type arg1_type,
+ out string arg1_val,
+ string arg2_name,
+ Type arg2_type,
+ out string arg2_val) {
+ assert (arg1_name == "ContainerID");
+ assert (arg1_type == typeof (string));
+ arg1_val = id;
+
+ assert (arg2_name == "Elements");
+ assert (arg2_type == typeof (string));
+ arg2_val = elements;
+ }
+
+ public new void @set (string arg1_name,
+ Type arg1_type,
+ string arg1_val,
+ string arg2_name,
+ Type arg2_type,
+ string arg2_val) {
+ assert (arg1_name == "ObjectID");
+ assert (arg1_type == typeof (string));
+
+ assert (arg2_name == "Result");
+ assert (arg2_type == typeof (string));
+ }
+}
+
+public class Rygel.HTTPServer : GLib.Object {
+}
+
+public class Rygel.ItemRemovalQueue : GLib.Object {
+ public static ItemRemovalQueue get_default () {
+ return new ItemRemovalQueue ();
+ }
+
+ public void queue (MediaItem item, Cancellable? cancellable) {
+ }
+}
+
+public class Rygel.MediaObject : GLib.Object {
+ public string id;
+ public string ref_id;
+ public unowned MediaContainer parent;
+ public string upnp_class;
+ public string title;
+ public GUPnP.OCMFlags ocm_flags;
+ public Gee.ArrayList<string> uris;
+
+ public void add_uri (string uri) {
+ this.uris.add (uri);
+ }
+}
+
+public class Rygel.MediaItem : Rygel.MediaObject {
+ public string dlna_profile;
+ public string mime_type;
+ public long size;
+ public bool place_holder;
+
+ public MediaItem (string id, MediaContainer parent, string title) {
+ this.id = id;
+ this.parent = parent;
+ this.title = title;
+ }
+
+ public void serialize (GUPnP.DIDLLiteWriter writer, HTTPServer server) {
+ }
+}
+
+public class Rygel.MusicItem : Rygel.AudioItem {
+ public const string UPNP_CLASS = "object.item.audioItem.musicTrack";
+
+ public MusicItem (string id, MediaContainer parent, string title) {
+ base (id, parent, title);
+ }
+}
+
+public class Rygel.AudioItem : Rygel.MediaItem {
+ public const string UPNP_CLASS = "object.item.audioItem";
+ public string artist;
+ public string album;
+
+ public AudioItem (string id, MediaContainer parent, string title) {
+ base (id, parent, title);
+ }
+}
+public class Rygel.ImageItem : Rygel.MediaItem {
+ public const string UPNP_CLASS = "object.item.imageItem";
+ public ImageItem (string id, MediaContainer parent, string title) {
+ base (id, parent, title);
+ }
+}
+
+public class Rygel.VideoItem : Rygel.MediaItem {
+ public const string UPNP_CLASS = "object.item.videoItem";
+ public VideoItem (string id, MediaContainer parent, string title) {
+ base (id, parent, title);
+ }
+}
+
+public class Rygel.PhotoItem : Rygel.MediaItem {
+ public const string UPNP_CLASS = "object.item.imageItem.photo";
+ public string creator;
+
+ public PhotoItem (string id, MediaContainer parent, string title) {
+ base (id, parent, title);
+ }
+}
+public class Rygel.ContentDirectory : GLib.Object {
+ public Cancellable cancellable;
+ public MediaContainer root_container;
+ public HTTPServer http_server;
+}
+
+public class Rygel.MediaContainer : Rygel.MediaObject {
+ public Gee.ArrayList<string> create_classes = new Gee.ArrayList<string> ();
+ public int child_count;
+
+ // mockable elements
+ public MediaObject found_object = null;
+
+ public async MediaObject? find_object (string id,
+ Cancellable? cancellable = null) {
+ Idle.add (() => { find_object.callback (); return false; });
+ yield;
+
+ return found_object;
+ }
+
+ public signal void container_updated (MediaContainer container);
+}
+
+public class Rygel.MediaObjects : Gee.ArrayList<MediaObject> {
+}
+
+public class Rygel.WritableContainer : Rygel.MediaContainer {
+ public async File? get_writable (Cancellable? cancellable = null) {
+ return File.new_for_commandline_arg ("/tmp");
+ }
+
+ public async void add_item (MediaItem item,
+ Cancellable? cancellable = null) {
+ }
+}
+
+public class Rygel.SearchableContainer : Rygel.MediaContainer {
+ public MediaObjects result = new MediaObjects ();
+
+ public async MediaObjects search (SearchExpression expression,
+ int offset,
+ int count,
+ out int total_matches,
+ Cancellable? cancellable = null) {
+ Idle.add (() => { search.callback (); return false; });
+ yield;
+
+ return result;
+ }
+}
+
+public errordomain Rygel.ContentDirectoryError {
+ BAD_METADATA,
+ NO_SUCH_OBJECT,
+ INVALID_ARGS,
+ RESTRICTED_PARENT,
+ ERROR
+}
+
+public class Rygel.HTTPItemCreatorTest : GLib.Object {
+
+ public static int main (string[] args) {
+ var test = new HTTPItemCreatorTest ();
+ test.test_parse_args ();
+ test.test_didl_parsing ();
+ test.test_fetch_container ();
+
+ return 0;
+ }
+
+ // expected errors
+ Error no_such_object;
+ Error restricted_parent;
+ Error bad_metadata;
+ Error invalid_args;
+
+ public HTTPItemCreatorTest () {
+ this.no_such_object = new ContentDirectoryError.NO_SUCH_OBJECT("");
+ this.restricted_parent = new ContentDirectoryError.RESTRICTED_PARENT("");
+ this.bad_metadata = new ContentDirectoryError.BAD_METADATA("");
+ this.invalid_args = new ContentDirectoryError.INVALID_ARGS("");
+ }
+
+ private void test_parse_args () {
+ // check null container id
+ var content_directory = new ContentDirectory ();
+
+ var action = new ServiceAction (null, "");
+ var creator = new ItemCreator (content_directory, action);
+ creator.run ();
+ assert (action.error_code == no_such_object.code);
+
+ // check elements containing a comment
+ action = new ServiceAction ("0", "<!-- This is an XML comment -->");
+ creator = new ItemCreator (content_directory, action);
+ creator.run ();
+ assert (action.error_code == bad_metadata.code);
+
+ // check null elements
+ action = new ServiceAction ("0", null);
+ creator = new ItemCreator (content_directory, action);
+ creator.run ();
+ assert (action.error_code == bad_metadata.code);
+ }
+
+ private void test_didl_parsing_step (Xml.Doc *doc, int expected_code) {
+ string xml;
+
+ doc->dump_memory_enc (out xml);
+ var action = new ServiceAction ("0", xml);
+ var content_directory = new ContentDirectory ();
+ var creator = new ItemCreator (content_directory, action);
+ creator.run ();
+ assert (action.error_code == expected_code);
+ }
+
+ private void test_didl_parsing () {
+ var xml = Xml.Parser.read_memory (DIDL_ITEM,
+ DIDL_ITEM.length,
+ null,
+ null,
+ Xml.ParserOption.RECOVER |
+ Xml.ParserOption.NOBLANKS);
+ var didl_node = xml->children;
+ var item_node = didl_node->children;
+ var content_directory = new ContentDirectory ();
+
+ // test no DIDL
+ var action = new ServiceAction ("0", "");
+ var creator = new ItemCreator (content_directory, action);
+ creator.run ();
+ assert (action.error_code == bad_metadata.code);
+ assert (action.error_message == "Bad metadata");
+
+ // test empty DIDL
+ item_node->unlink ();
+ didl_node->set_content (" ");
+ this.test_didl_parsing_step (xml, 701);
+
+ // test item node with missing restricted attribute
+ var tmp = item_node->copy (1);
+ tmp->unset_prop ("restricted");
+ didl_node->add_child (tmp);
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+
+ // test item node with restricted=1
+ tmp->set_prop ("restricted", "1");
+ this.test_didl_parsing_step (xml, invalid_args.code);
+
+ // test item node with invalid id
+ tmp->unlink ();
+ tmp = item_node->copy (1);
+ tmp->set_prop ("id", "InvalidItemId");
+ didl_node->add_child (tmp);
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+
+ // test item node with missing id
+ tmp->unset_prop ("id");
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+
+ // test item node with missing title
+ tmp->unlink ();
+ tmp = item_node->copy (1);
+ var title_node = tmp->children;
+ title_node->unlink ();
+ didl_node->add_child (tmp);
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+
+ // test missing, empty or non-item upnp class
+ tmp->unlink ();
+ tmp = item_node->copy (1);
+ var class_node = tmp->children->next;
+ class_node->set_content ("object.container");
+ didl_node->add_child (tmp);
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+
+ class_node->set_content ("");
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+
+ class_node->unlink ();
+ this.test_didl_parsing_step (xml, bad_metadata.code);
+ }
+
+ private void test_fetch_container_run (ItemCreator creator) {
+ var main_loop = new MainLoop (null, false);
+ creator.run.begin ( () => { main_loop.quit (); });
+ main_loop.run ();
+ }
+
+ private void test_fetch_container () {
+ // check case when object is not found
+ var content_directory = new ContentDirectory ();
+ var root_container = new SearchableContainer ();
+ content_directory.root_container = root_container;
+ var action = new ServiceAction ("0", DIDL_ITEM);
+ var creator = new ItemCreator (content_directory, action);
+ this.test_fetch_container_run (creator);
+ assert (action.error_code == no_such_object.code);
+
+ // check case when found object is not a container â Error 710
+ // cf. ContentDirectory:2 spec, Table 2-22
+ root_container.found_object = new MediaObject ();
+ this.test_fetch_container_run (creator);
+ assert (action.error_code == no_such_object.code);
+
+ // check case when found container does not have OCMUpload set
+ root_container.found_object = new MediaContainer ();
+ this.test_fetch_container_run (creator);
+ assert (action.error_code == restricted_parent.code);
+
+ // check case when found container is not a writable container
+ root_container.found_object.ocm_flags |= GUPnP.OCMFlags.UPLOAD;
+ this.test_fetch_container_run (creator);
+ assert (action.error_code == restricted_parent.code);
+
+ // check when found container does not have the correct create class
+ var container = new WritableContainer ();
+ container.create_classes.add ("object.item.imageItem.musicTrack");
+ container.ocm_flags |= GUPnP.OCMFlags.UPLOAD;
+ root_container.found_object = container;
+ this.test_fetch_container_run (creator);
+ assert (action.error_code == bad_metadata.code);
+
+ // check DLNA.ORG_AnyContainer when root container is not searchable
+ content_directory.root_container = new MediaContainer ();
+ action.id = "DLNA.ORG_AnyContainer";
+ this.test_fetch_container_run (creator);
+ assert (action.error_code == no_such_object.code);
+
+ // check DLNA.ORG_AnyContainer when no writable container is found
+ content_directory.root_container = new SearchableContainer ();
+ this.test_fetch_container_run (creator);
+ // We cannot distinguish this case from the "create-class doesn't match"
+ // case
+ assert (action.error_code == bad_metadata.code);
+ }
+}
diff --git a/tests/rygel-item-creator.vala b/tests/rygel-item-creator.vala
new file mode 120000
index 0000000..4d22d87
--- /dev/null
+++ b/tests/rygel-item-creator.vala
@@ -0,0 +1 @@
+../src/rygel/rygel-item-creator.vala
\ No newline at end of file
diff --git a/tests/rygel-relational-expression.vala b/tests/rygel-relational-expression.vala
new file mode 120000
index 0000000..d0490ad
--- /dev/null
+++ b/tests/rygel-relational-expression.vala
@@ -0,0 +1 @@
+../src/rygel/rygel-relational-expression.vala
\ No newline at end of file
diff --git a/tests/rygel-search-expression.vala b/tests/rygel-search-expression.vala
new file mode 120000
index 0000000..5892005
--- /dev/null
+++ b/tests/rygel-search-expression.vala
@@ -0,0 +1 @@
+../src/rygel/rygel-search-expression.vala
\ No newline at end of file
diff --git a/tests/rygel-state-machine_item-creator.vala b/tests/rygel-state-machine_item-creator.vala
new file mode 120000
index 0000000..5063d68
--- /dev/null
+++ b/tests/rygel-state-machine_item-creator.vala
@@ -0,0 +1 @@
+../src/rygel/rygel-state-machine.vala
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]