summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-09-30 13:01:57 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-09-30 13:01:57 -0400
commitc2f2ac05aade16d0a238ffe6f77b5994c7d6609d (patch)
treea0afbd8bbd00c77b9e80a11c55cbcb700a03c9a5
parent69f0ce038868eda535aeaab3aaa6ab8d0e592fa0 (diff)
Updates
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--doc/stc-sections.txt9
-rw-r--r--stc/stcenums.h9
-rw-r--r--stc/stcitem.c12
-rw-r--r--stc/stcitem.h3
-rw-r--r--stc/stcmonitor.c315
-rw-r--r--stc/stcmonitor.h33
-rw-r--r--stc/test.c69
-rw-r--r--stc/testdata/semi_valid_conf/stc.conf (renamed from stc/stc.conf)0
-rw-r--r--stc/testdata/semi_valid_conf/stc.d/10.conf3
-rw-r--r--stc/testdata/semi_valid_conf/stc.d/50.conf3
-rw-r--r--stc/testdata/semi_valid_conf/stc.d/90.conf7
-rw-r--r--stc/testdata/semi_valid_conf/stc.d/91.conf3
12 files changed, 309 insertions, 157 deletions
diff --git a/doc/stc-sections.txt b/doc/stc-sections.txt
index 49d81a8..129e6da 100644
--- a/doc/stc-sections.txt
+++ b/doc/stc-sections.txt
@@ -2,10 +2,9 @@
<FILE>stcmonitor</FILE>
<TITLE>StcMonitor</TITLE>
StcMonitor
+StcErrorHandlerFunc
stc_monitor_new
stc_monitor_new_for_config_dir
-stc_monitor_get_active
-stc_monitor_activate
stc_monitor_get_config_dir
stc_monitor_get_items
<SUBSECTION Standard>
@@ -21,13 +20,15 @@ stc_monitor_get_type
<TITLE>StcItem</TITLE>
StcItem
StcItemType
-stc_item_get_applied
-stc_item_get_can_apply
stc_item_get_dependencies
stc_item_get_id
stc_item_get_item_type
stc_item_get_nick_name
stc_item_get_target
+stc_item_get_option
+stc_item_get_option_keys
+stc_item_get_is_applied
+stc_item_get_can_apply
<SUBSECTION Standard>
STC_TYPE_ITEM
STC_ITEM
diff --git a/stc/stcenums.h b/stc/stcenums.h
index d608561..d92d081 100644
--- a/stc/stcenums.h
+++ b/stc/stcenums.h
@@ -34,15 +34,16 @@ G_BEGIN_DECLS
/**
* StcError:
* @STC_ERROR_FAILED: The operation failed / Generic error.
- * @STC_ERROR_PARSE_ERROR: A configurtion is invalid.
+ * @STC_ERROR_PARSE_ERROR: A configurtion item is invalid.
+ * @STC_ERROR_DUPLICATE_ITEM: A configuration item with an existing identifier was encountered.
*
- * Error codes for the #STC_ERROR error domain and the
- * corresponding D-Bus error names.
+ * Error codes for the #STC_ERROR error domain.
*/
typedef enum
{
STC_ERROR_FAILED,
- STC_ERROR_PARSE_ERROR
+ STC_ERROR_PARSE_ERROR,
+ STC_ERROR_DUPLICATE_ITEM
} StcError;
/**
diff --git a/stc/stcitem.c b/stc/stcitem.c
index 7490b0d..f8fa01e 100644
--- a/stc/stcitem.c
+++ b/stc/stcitem.c
@@ -30,8 +30,10 @@
* @title: StcItem
* @short_description: Configuration Item
*
- * Object corresponding to item. You cannot instantiate this type
- * yourself – you must use #StcMonitor.
+ * Object corresponding to a configuration item in
+ * e.g. <filename>/etc/stc.conf</filename>. You cannot instantiate
+ * this type yourself – you must use e.g. #StcMonitor to obtain
+ * instances.
*/
/**
@@ -50,7 +52,7 @@ struct _StcItem
gchar *target;
GHashTable *options;
gboolean can_apply;
- gboolean applied;
+ gboolean is_applied;
/* memoized */
gchar **option_keys;
@@ -146,10 +148,10 @@ stc_item_get_can_apply (StcItem *item)
}
gboolean
-stc_item_get_applied (StcItem *item)
+stc_item_get_is_applied (StcItem *item)
{
g_return_val_if_fail (STC_IS_ITEM (item), FALSE);
- return item->applied;
+ return item->is_applied;
}
diff --git a/stc/stcitem.h b/stc/stcitem.h
index 287bc65..057404f 100644
--- a/stc/stcitem.h
+++ b/stc/stcitem.h
@@ -45,8 +45,9 @@ const gchar* const *stc_item_get_option_keys (StcItem *item);
const gchar *stc_item_get_option (StcItem *item,
const gchar *key);
GList *stc_item_get_dependencies (StcItem *item);
+
gboolean stc_item_get_can_apply (StcItem *item);
-gboolean stc_item_get_applied (StcItem *item);
+gboolean stc_item_get_is_applied (StcItem *item);
G_END_DECLS
diff --git a/stc/stcmonitor.c b/stc/stcmonitor.c
index f6d4242..8f0cc70 100644
--- a/stc/stcmonitor.c
+++ b/stc/stcmonitor.c
@@ -28,6 +28,7 @@
#include "stcmonitor.h"
#include "stcmarshal.h"
#include "stcprivate.h"
+#include "stcitem.h"
/**
* SECTION:stcmonitor
@@ -50,11 +51,13 @@ struct _StcMonitor
GMainContext *context;
- gchar *config_dir;
+ StcErrorHandlerFunc error_handler_func;
+ gpointer error_handler_user_data;
- gboolean active;
+ gchar *config_dir;
GList *items;
+ GHashTable *map_id_to_item;
};
typedef struct _StcMonitorClass StcMonitorClass;
@@ -73,20 +76,11 @@ enum
{
PROP_0,
PROP_CONFIG_DIR,
- PROP_ACTIVE
+ PROP_ERROR_HANDLER_FUNC,
+ PROP_ERROR_HANDLER_USER_DATA
};
-enum
-{
- ERROR_SIGNAL,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static GList *stc_monitor_load_one_file (StcMonitor *monitor,
- const gchar *path,
- GError **error);
+static GList *stc_monitor_load_all_files (StcMonitor *monitor);
static void
stc_monitor_emit_gerror (StcMonitor *monitor,
@@ -113,6 +107,7 @@ stc_monitor_finalize (GObject *object)
g_free (monitor->config_dir);
g_list_foreach (monitor->items, (GFunc) g_object_unref, NULL);
g_list_free (monitor->items);
+ g_hash_table_unref (monitor->map_id_to_item);
if (G_OBJECT_CLASS (stc_monitor_parent_class)->finalize)
G_OBJECT_CLASS (stc_monitor_parent_class)->finalize (object);
@@ -132,8 +127,12 @@ stc_monitor_get_property (GObject *object,
g_value_set_string (value, stc_monitor_get_config_dir (monitor));
break;
- case PROP_ACTIVE:
- g_value_set_boolean (value, stc_monitor_get_active (monitor));
+ case PROP_ERROR_HANDLER_FUNC:
+ g_value_set_pointer (value, monitor->error_handler_func);
+ break;
+
+ case PROP_ERROR_HANDLER_USER_DATA:
+ g_value_set_pointer (value, monitor->error_handler_user_data);
break;
default:
@@ -158,6 +157,14 @@ stc_monitor_set_property (GObject *object,
g_assert (monitor->config_dir != NULL);
break;
+ case PROP_ERROR_HANDLER_FUNC:
+ monitor->error_handler_func = g_value_get_pointer (value);
+ break;
+
+ case PROP_ERROR_HANDLER_USER_DATA:
+ monitor->error_handler_user_data = g_value_get_pointer (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -170,6 +177,34 @@ stc_monitor_init (StcMonitor *monitor)
monitor->context = g_main_context_get_thread_default ();
if (monitor->context != NULL)
g_main_context_ref (monitor->context);
+
+ monitor->map_id_to_item = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+
+static void
+stc_monitor_constructed (GObject *object)
+{
+ StcMonitor *monitor = STC_MONITOR (object);
+ GList *loaded_items;
+ GList *l;
+
+ g_return_if_fail (STC_IS_MONITOR (monitor));
+
+ loaded_items = stc_monitor_load_all_files (monitor);
+
+ for (l = loaded_items; l != NULL; l = l->next)
+ {
+ StcItem *item = STC_ITEM (l->data);
+ /* TODO: check if we have item already - if so, update existing object */
+ monitor->items = g_list_append (monitor->items, g_object_ref (item));
+ g_hash_table_insert (monitor->map_id_to_item, (gpointer) stc_item_get_id (item), item);
+ }
+ g_list_foreach (loaded_items, (GFunc) g_object_unref, NULL);
+ g_list_free (loaded_items);
+
+ if (G_OBJECT_CLASS (stc_monitor_parent_class)->constructed)
+ G_OBJECT_CLASS (stc_monitor_parent_class)->constructed (object);
}
static void
@@ -179,6 +214,7 @@ stc_monitor_class_init (StcMonitorClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = stc_monitor_finalize;
+ gobject_class->constructed = stc_monitor_constructed;
gobject_class->get_property = stc_monitor_get_property;
gobject_class->set_property = stc_monitor_set_property;
@@ -199,80 +235,73 @@ stc_monitor_class_init (StcMonitorClass *klass)
G_PARAM_STATIC_STRINGS));
/**
- * StcMonitor:active:
+ * StcMonitor:error-handler-func:
*
- * Whether the monitor is currently active.
+ * Pointer to a #StcErrorHandlerFunc to call on error, or %NULL.
*/
g_object_class_install_property (gobject_class,
- PROP_ACTIVE,
- g_param_spec_boolean ("active",
- "Active",
- "Whether the monitor is currently active",
- FALSE,
+ PROP_ERROR_HANDLER_FUNC,
+ g_param_spec_pointer ("error-handler-func",
+ "Error handler function",
+ "Function to call on errors",
G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
- * StcMonitor::error:
- * @monitor: The #StcMonitor emitting the signal
- * @filename: The path of the file that caused the error or %NULL.
- * @line_no: The line number the error occured at or -1 if unknown.
- * @error: The error.
+ * StcMonitor:error-handler-user-data:
*
- * Emitted whenever a recoverable error (typically file parsing) is
- * encountered.
- *
- * This signal is emitted in the
- * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
- * that @monitor was created in.
+ * User-data to pass to the function pointer defined in the #StcMonitor:error-handler-func property.
*/
- signals[ERROR_SIGNAL] = g_signal_new ("error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (StcMonitorClass, error),
- NULL,
- NULL,
- _stc_marshal_VOID__STRING_INT_BOXED,
- G_TYPE_NONE,
- 3,
- G_TYPE_STRING,
- G_TYPE_INT,
- G_TYPE_ERROR);
+ g_object_class_install_property (gobject_class,
+ PROP_ERROR_HANDLER_USER_DATA,
+ g_param_spec_pointer ("error-handler-user-data",
+ "Error handler user data",
+ "Error handler user data",
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
/**
* stc_monitor_new:
+ * @error_handler_func: A function to handle errors or %NULL.
+ * @error_handler_user_data: The @user_data #gpointer to pass to @error_handler_func.
*
* Creates a new #StcMonitor that reads configuration files from the
* default configuration directory
* (e.g. <filename>/etc</filename>).
*
- * The returned monitor isn't active. Use stc_monitor_activate() to load
- * and monitor items.
- *
* Returns: A #StcMonitor. Free with g_object_unref().
*/
StcMonitor *
-stc_monitor_new (void)
+stc_monitor_new (StcErrorHandlerFunc error_handler_func,
+ gpointer error_handler_user_data)
{
StcMonitor *monitor;
- monitor = STC_MONITOR (g_object_new (STC_TYPE_MONITOR, NULL));
+ monitor = STC_MONITOR (g_object_new (STC_TYPE_MONITOR,
+ "error-handler-func", error_handler_func,
+ "error-handler-user-data", error_handler_user_data,
+ NULL));
return monitor;
}
/**
* stc_monitor_new_for_config_dir:
* @config_dir: A path to where the <filename>stc.conf</filename> is stored.
+ * @error_handler_func: A function to handle errors or %NULL.
+ * @error_handler_user_data: The @user_data #gpointer to pass to @error_handler_func.
*
* Creates a new #StcMonitor.
*
- * The returned monitor isn't active. Use stc_monitor_activate() to load
- * and monitor items.
- *
* Returns: A #StcMonitor. Free with g_object_unref().
*/
StcMonitor *
-stc_monitor_new_for_config_dir (const gchar *config_dir)
+stc_monitor_new_for_config_dir (const gchar *config_dir,
+ StcErrorHandlerFunc error_handler_func,
+ gpointer error_handler_user_data)
{
StcMonitor *monitor;
@@ -280,60 +309,13 @@ stc_monitor_new_for_config_dir (const gchar *config_dir)
monitor = STC_MONITOR (g_object_new (STC_TYPE_MONITOR,
"config-dir", config_dir,
+ "error-handler-func", error_handler_func,
+ "error-handler-user-data", error_handler_user_data,
NULL));
return monitor;
}
/**
- * stc_monitor_activate:
- * @monitor: A #StcMonitor that isn't active.
- *
- * Starts @monitor. If you are interested in reporting errors, connect
- * to the #StcMonitor::error signal prior to invoking this method.
- */
-void
-stc_monitor_activate (StcMonitor *monitor)
-{
- gchar *path;
- GError *error;
-
- g_return_if_fail (STC_IS_MONITOR (monitor));
- g_return_if_fail (!monitor->active);
-
- path = g_strdup_printf ("%s/stc.conf", monitor->config_dir);
- error = NULL;
- monitor->items = stc_monitor_load_one_file (monitor, path, &error);
- if (error != NULL)
- {
- stc_monitor_emit_gerror (monitor,
- path,
- -1,
- error);
- g_error_free (error);
- }
- g_free (path);
-
- monitor->active = TRUE;
- g_object_notify (G_OBJECT (monitor), "active");
-}
-
-
-/**
- * stc_monitor_get_active:
- * @monitor: A #StcMonitor.
- *
- * Gets whether @monitor is active.
- *
- * Returns: %TRUE if monitor is active, %FALSE otherwise.
- */
-gboolean
-stc_monitor_get_active (StcMonitor *monitor)
-{
- g_return_val_if_fail (STC_IS_MONITOR (monitor), FALSE);
- return monitor->active;
-}
-
-/**
* stc_monitor_get_config_dir:
* @monitor: A #StcMonitor.
*
@@ -364,7 +346,6 @@ stc_monitor_get_items (StcMonitor *monitor)
GList *ret;
g_return_val_if_fail (STC_IS_MONITOR (monitor), NULL);
- g_return_val_if_fail (monitor->active, NULL);
ret = g_list_copy (monitor->items);
g_list_foreach (ret, (GFunc) g_object_ref, NULL);
@@ -582,6 +563,126 @@ stc_monitor_load_one_file (StcMonitor *monitor,
return ret;
}
+static GList *
+stc_monitor_load_one_file_emit_error (StcMonitor *monitor,
+ const gchar *path)
+{
+ GError *error;
+ GList *ret;
+
+ error = NULL;
+ ret = stc_monitor_load_one_file (monitor, path, &error);
+ if (error != NULL)
+ {
+ g_assert (ret == NULL);
+ stc_monitor_emit_gerror (monitor,
+ path,
+ -1,
+ error);
+ g_error_free (error);
+ }
+
+ return ret;
+}
+
+
+static gint
+_p_strcmp (gconstpointer a, gconstpointer b)
+{
+ const gchar *sa;
+ const gchar *sb;
+
+ sa = * ((const gchar **) a);
+ sb = * ((const gchar **) b);
+
+ return strcmp (sa, sb);
+}
+
+static GList *
+stc_monitor_load_all_files (StcMonitor *monitor)
+{
+ gchar *path;
+ gchar *dir_path;
+ GError *error;
+ GList *loaded_items;
+ GList *ret;
+ GDir *dir;
+ guint n;
+ GHashTable *id_to_item;
+ GList *l;
+ GPtrArray *paths;
+
+ ret = NULL;
+ /* hash used to weed out duplicates */
+ id_to_item = g_hash_table_new (g_str_hash, g_str_equal);
+
+ paths = g_ptr_array_new ();
+ g_ptr_array_add (paths, g_strdup_printf ("%s/stc.conf", monitor->config_dir));
+
+ dir_path = g_strdup_printf ("%s/stc.d", monitor->config_dir);
+ error = NULL;
+ dir = g_dir_open (dir_path, 0, &error);
+ if (error != NULL)
+ {
+ stc_monitor_emit_gerror (monitor,
+ dir_path,
+ -1,
+ error);
+ g_error_free (error);
+ }
+ else
+ {
+ const gchar *name;
+ while ((name = g_dir_read_name (dir)) != NULL)
+ {
+ if (g_str_has_suffix (name, ".conf"))
+ {
+ path = g_strdup_printf ("%s/%s", dir_path, name);
+ g_ptr_array_add (paths, path);
+ }
+ }
+ g_dir_close (dir);
+ }
+ g_free (dir_path);
+ g_ptr_array_sort (paths, _p_strcmp);
+
+ for (n = 0; n < paths->len; n++)
+ {
+ path = paths->pdata[n];
+ loaded_items = stc_monitor_load_one_file_emit_error (monitor, path);
+ for (l = loaded_items; l != NULL; l = l->next)
+ {
+ StcItem *item;
+ StcItem *duplicate_item;
+ const gchar *id;
+
+ item = STC_ITEM (l->data);
+ id = stc_item_get_id (item);
+ if ((duplicate_item = g_hash_table_lookup (id_to_item, id)) != NULL)
+ {
+ stc_monitor_emit_stc_error (monitor,
+ path,
+ -1,
+ STC_ERROR_DUPLICATE_ITEM,
+ "Encountered item with duplicate id `%s'. Ignoring previous items.",
+ id);
+ g_assert (g_list_find (ret, duplicate_item) != NULL);
+ ret = g_list_remove (ret, duplicate_item);
+ }
+ g_hash_table_insert (id_to_item, (gpointer) id, item);
+ ret = g_list_prepend (ret, item);
+ }
+ }
+ g_ptr_array_foreach (paths, (GFunc) g_free, NULL);
+ g_ptr_array_free (paths, TRUE);
+
+ g_hash_table_unref (id_to_item);
+
+ ret = g_list_reverse (ret);
+
+ return ret;
+}
+
static void
stc_monitor_emit_gerror (StcMonitor *monitor,
const gchar *filename,
@@ -592,7 +693,9 @@ stc_monitor_emit_gerror (StcMonitor *monitor,
* in the correct context
*/
g_assert (g_main_context_get_thread_default () == monitor->context);
- g_signal_emit (monitor, signals[ERROR_SIGNAL], 0, filename, line_no, error);
+
+ if (monitor->error_handler_func != NULL)
+ monitor->error_handler_func (monitor, filename, line_no, error, monitor->error_handler_user_data);
}
static void
diff --git a/stc/stcmonitor.h b/stc/stcmonitor.h
index a4ee942..c2599ed 100644
--- a/stc/stcmonitor.h
+++ b/stc/stcmonitor.h
@@ -36,13 +36,34 @@ G_BEGIN_DECLS
#define STC_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), STC_TYPE_MONITOR, StcMonitor))
#define STC_IS_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), STC_TYPE_MONITOR))
+/**
+ * StcErrorHandlerFunc:
+ * @monitor: The #StcMonitor with the condition.
+ * @filename: The path of the file that caused the error or %NULL.
+ * @line_no: The line number the error occured at or -1 if unknown.
+ * @error: The error.
+ * @user_data: User data.
+ *
+ * Function pointer for a function that is called whenever @monitor encounters an error condition.
+ *
+ * This function is called from the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * that @monitor was created in.
+ */
+typedef void (*StcErrorHandlerFunc) (StcMonitor *monitor,
+ const gchar *filename,
+ gint line_no,
+ GError *error,
+ gpointer user_data);
+
GType stc_monitor_get_type (void) G_GNUC_CONST;
-StcMonitor *stc_monitor_new (void);
-StcMonitor *stc_monitor_new_for_config_dir (const gchar *config_dir);
-void stc_monitor_activate (StcMonitor *monitor);
-gboolean stc_monitor_get_active (StcMonitor *monitor);
-const gchar *stc_monitor_get_config_dir (StcMonitor *monitor);
-GList *stc_monitor_get_items (StcMonitor *monitor);
+StcMonitor *stc_monitor_new (StcErrorHandlerFunc error_handler_func,
+ gpointer error_handler_user_data);
+StcMonitor *stc_monitor_new_for_config_dir (const gchar *config_dir,
+ StcErrorHandlerFunc error_handler_func,
+ gpointer error_handler_user_data);
+const gchar *stc_monitor_get_config_dir (StcMonitor *monitor);
+GList *stc_monitor_get_items (StcMonitor *monitor);
G_END_DECLS
diff --git a/stc/test.c b/stc/test.c
index f61433a..c3a7f04 100644
--- a/stc/test.c
+++ b/stc/test.c
@@ -115,18 +115,12 @@ test_stc_basic (void)
{
StcMonitor *monitor;
- monitor = stc_monitor_new ();
+ monitor = stc_monitor_new (NULL, NULL);
g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, PACKAGE_SYSCONF_DIR);
- g_assert (!stc_monitor_get_active (monitor));
- stc_monitor_activate (monitor);
- g_assert (stc_monitor_get_active (monitor));
g_object_unref (monitor);
- monitor = stc_monitor_new_for_config_dir (SRCDIR);
+ monitor = stc_monitor_new_for_config_dir (SRCDIR, NULL, NULL);
g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, SRCDIR);
- g_assert (!stc_monitor_get_active (monitor));
- stc_monitor_activate (monitor);
- g_assert (stc_monitor_get_active (monitor));
g_object_unref (monitor);
}
@@ -137,18 +131,13 @@ test_stc_no_conf (void)
GString *str;
str = g_string_new (NULL);
- monitor = stc_monitor_new_for_config_dir (SRCDIR "/nonexistant");
+ monitor = stc_monitor_new_for_config_dir (SRCDIR "/nonexistant", on_error_append_str, str);
g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, SRCDIR "/nonexistant");
- g_assert (!stc_monitor_get_active (monitor));
- g_signal_connect (monitor,
- "error",
- G_CALLBACK (on_error_append_str),
- str);
- stc_monitor_activate (monitor);
- g_assert (stc_monitor_get_active (monitor));
g_object_unref (monitor);
g_assert_cmpstr (str->str, ==,
- SRCDIR "/nonexistant/stc.conf: No such file or directory (g-file-error-quark, 4)\n");
+ SRCDIR "/nonexistant/stc.d: Error opening directory '" SRCDIR "/nonexistant/stc.d': No such file or directory (g-file-error-quark, 4)\n"
+ SRCDIR "/nonexistant/stc.conf: No such file or directory (g-file-error-quark, 4)\n"
+ );
g_string_free (str, TRUE);
}
@@ -162,21 +151,15 @@ test_stc_semi_valid_conf (void)
GList *l;
str = g_string_new (NULL);
- monitor = stc_monitor_new_for_config_dir (SRCDIR);
- g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, SRCDIR);
- g_assert (!stc_monitor_get_active (monitor));
- g_signal_connect (monitor,
- "error",
- G_CALLBACK (on_error_append_str),
- str);
- stc_monitor_activate (monitor);
- g_assert (stc_monitor_get_active (monitor));
+ monitor = stc_monitor_new_for_config_dir (SRCDIR "/testdata/semi_valid_conf", on_error_append_str, str);
+ g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, SRCDIR "/testdata/semi_valid_conf");
g_assert_cmpstr (str->str, ==,
- SRCDIR "/stc.conf: Error parsing group name `Blah' (stc-error-quark, 1)\n"
- SRCDIR "/stc.conf: Error parsing item type `XYZType' in group `XYZType ValidIdentifier' (stc-error-quark, 1)\n"
- SRCDIR "/stc.conf: Invalid item identifer `with-dash' in group `Filesystem with-dash'. Only characters in [a-zA-Z0-9_] are supported. (stc-error-quark, 1)\n"
- SRCDIR "/stc.conf: Error parsing group name `Filesystem with space' (stc-error-quark, 1)\n"
- SRCDIR "/stc.conf: Element 0 of Options, `foo', for item foo of type MDRaid is malformed (no equal sign found). (stc-error-quark, 1)\n"
+ SRCDIR "/testdata/semi_valid_conf/stc.conf: Error parsing group name `Blah' (stc-error-quark, 1)\n"
+ SRCDIR "/testdata/semi_valid_conf/stc.conf: Error parsing item type `XYZType' in group `XYZType ValidIdentifier' (stc-error-quark, 1)\n"
+ SRCDIR "/testdata/semi_valid_conf/stc.conf: Invalid item identifer `with-dash' in group `Filesystem with-dash'. Only characters in [a-zA-Z0-9_] are supported. (stc-error-quark, 1)\n"
+ SRCDIR "/testdata/semi_valid_conf/stc.conf: Error parsing group name `Filesystem with space' (stc-error-quark, 1)\n"
+ SRCDIR "/testdata/semi_valid_conf/stc.conf: Element 0 of Options, `foo', for item foo of type MDRaid is malformed (no equal sign found). (stc-error-quark, 1)\n"
+ SRCDIR "/testdata/semi_valid_conf/stc.d/91.conf: Encountered item with duplicate id `multiple_instances_same_id'. Ignoring previous items. (stc-error-quark, 2)\n"
);
str2 = g_string_new (NULL);
items = stc_monitor_get_items (monitor);
@@ -210,6 +193,30 @@ test_stc_semi_valid_conf (void)
"nick-name `My Secret Stuff (Encrypted)'\n"
"type luks\n"
"options LUKS:password -> `xyz123'\n"
+ "\n"
+ "id `in_pri_10'\n"
+ "target `Device=/dev/sda'\n"
+ "nick-name `(none)'\n"
+ "type filesystem\n"
+ "options (none)\n"
+ "\n"
+ "id `in_pri_50'\n"
+ "target `Device=/dev/sda'\n"
+ "nick-name `(none)'\n"
+ "type filesystem\n"
+ "options (none)\n"
+ "\n"
+ "id `in_pri_90'\n"
+ "target `Device=/dev/sda'\n"
+ "nick-name `(none)'\n"
+ "type filesystem\n"
+ "options (none)\n"
+ "\n"
+ "id `multiple_instances_same_id'\n"
+ "target `Device=/dev/multiple_instances_same_id/second'\n"
+ "nick-name `(none)'\n"
+ "type filesystem\n"
+ "options (none)\n"
"\n");
g_string_free (str2, TRUE);
diff --git a/stc/stc.conf b/stc/testdata/semi_valid_conf/stc.conf
index acfcd9b..acfcd9b 100644
--- a/stc/stc.conf
+++ b/stc/testdata/semi_valid_conf/stc.conf
diff --git a/stc/testdata/semi_valid_conf/stc.d/10.conf b/stc/testdata/semi_valid_conf/stc.d/10.conf
new file mode 100644
index 0000000..73b0c95
--- /dev/null
+++ b/stc/testdata/semi_valid_conf/stc.d/10.conf
@@ -0,0 +1,3 @@
+
+[Filesystem in_pri_10]
+Device=/dev/sda
diff --git a/stc/testdata/semi_valid_conf/stc.d/50.conf b/stc/testdata/semi_valid_conf/stc.d/50.conf
new file mode 100644
index 0000000..bad4e88
--- /dev/null
+++ b/stc/testdata/semi_valid_conf/stc.d/50.conf
@@ -0,0 +1,3 @@
+
+[Filesystem in_pri_50]
+Device=/dev/sda
diff --git a/stc/testdata/semi_valid_conf/stc.d/90.conf b/stc/testdata/semi_valid_conf/stc.d/90.conf
new file mode 100644
index 0000000..15a3de1
--- /dev/null
+++ b/stc/testdata/semi_valid_conf/stc.d/90.conf
@@ -0,0 +1,7 @@
+
+[Filesystem in_pri_90]
+Device=/dev/sda
+
+# this is for testing that we replace the previous entry (see also 91.conf)
+[Filesystem multiple_instances_same_id]
+Device=/dev/multiple_instances_same_id/first
diff --git a/stc/testdata/semi_valid_conf/stc.d/91.conf b/stc/testdata/semi_valid_conf/stc.d/91.conf
new file mode 100644
index 0000000..a97db0f
--- /dev/null
+++ b/stc/testdata/semi_valid_conf/stc.d/91.conf
@@ -0,0 +1,3 @@
+# this is for testing that we replace the previous entry (see also 90.conf)
+[Filesystem multiple_instances_same_id]
+Device=/dev/multiple_instances_same_id/second