Index: /trunk/psModules/test/config/Makefile.am
===================================================================
--- /trunk/psModules/test/config/Makefile.am	(revision 14879)
+++ /trunk/psModules/test/config/Makefile.am	(revision 14880)
@@ -12,5 +12,9 @@
 
 TEST_PROGS = \
-	tst_pmConfig
+	tap_pmConfig \
+	tap_pmConfigCommand \
+	tap_pmConfigMask \
+	tap_pmErrorCodes \
+	tap_pmVersion
 
 check_DATA = \
Index: /trunk/psModules/test/config/data/SampleIPPConfig
===================================================================
--- /trunk/psModules/test/config/data/SampleIPPConfig	(revision 14879)
+++ /trunk/psModules/test/config/data/SampleIPPConfig	(revision 14880)
@@ -3,12 +3,36 @@
     DATAPATH	str	datapath
 
+PATH            STR     .
+
 ### Database configuration
-    DBSERVER	STR	localhost
-    DBUSER		STR	test
-    DBPASSWORD	STR	""
-    DBNAME          STR     test
-    DBPORT		S32	0
+DBSERVER	STR	localhost		# Database host name (for psDBInit)
+DBUSER		STR	test			# Database user name (for psDBInit)
+DBPASSWORD	STR	DB-PW			# Database password (for psDBInit)
+DBNAME          STR     test                    # ????
+DBPORT		S32	0
+
 
 ### Setups for each camera system
+CAMERAS		METADATA
+	CAMERA0		STR	camera0/camera.config
+	CAMERA1		STR	camera1/camera.config
+END
+
+### psLib setup
+#TIME		STR	/home/mithrandir/price/pan-starrs/jhroot/i686-pc-linux-gnu/etc/pslib/psTime.config	# Time configuration file
+LOGLEVEL	S32	3			# Logging level; 3=INFO
+LOGFORMAT	STR	HLNM			# Log format
+LOGDEST	STR	STDOUT				# Log destination
+TRACE		METADATA			# Trace levels
+	dummyTraceFunc01	S32	1
+	dummyTraceFunc02	S32	2
+END
+ARBITRARY_STRING_S32	S32	20
+ARBITRARY_STRING_F32	F32	21.0
+ARBITRARY_STRING_F64	F64	22.0
+ARBITRARY_STRING_STR	STR	19.0
+ARBITRARY_STRING_BOOL_T	BOOL	true
+ARBITRARY_STRING_BOOL_F	BOOL	false
+=======
     CAMERAS		METADATA
 	CAMERA0		STR	camera0/camera.config
@@ -44,2 +68,7 @@
     ARBITRARY_STRING_BOOL_F	BOOL	false
 
+RECIPES         METADATA
+	MASKS			STR	recipes_masks.config
+        JUNK_RECIPE_00		STR	recipe_file00
+        JUNK_RECIPE_01		STR	recipe_file01
+END
Index: /trunk/psModules/test/config/data/camera0/camera.config
===================================================================
--- /trunk/psModules/test/config/data/camera0/camera.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera0/camera.config	(revision 14880)
@@ -0,0 +1,15 @@
+FORMATS         METADATA
+        C0_FM0     STR     camera0/format0.config
+        C0_FM1     STR     camera0/format1.config
+END
+
+RECIPES         METADATA
+        C0_RECIPE0          STR     camera0/recipe0.config
+        C0_RECIPE1          STR     camera0/recipe1.config
+END
+
+FPA     METADATA
+        ccd00   STR     LeftAmp RightAmp
+        ccd01   STR     LeftAmp RightAmp
+END
+ID      STR     CAMERA0
Index: /trunk/psModules/test/config/data/camera0/format0.config
===================================================================
--- /trunk/psModules/test/config/data/camera0/format0.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera0/format0.config	(revision 14880)
@@ -0,0 +1,36 @@
+RULE    METADATA
+        F0_KEY0        STR     string20
+        F0_KEY1        STR     string21
+        F0_KEY2        S32     20
+END
+
+FILE    METADATA
+        PHU             STR     FPA
+        EXTENSIONS      STR     CELL
+        FPA.NAME        STR     EXPNUM
+END
+
+DEFAULTS        METADATA
+        F0_DEF0           STR     DefString20
+        F0_DEF1           STR     DefString21
+        F0_DEF2           F32     21.0
+        F0_DEF3           S32     22
+END
+
+CELLS   METADATA
+        left    METADATA        # Left amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+        right   METADATA        # Right amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+END
+
+ID	STR	camera0/format0.config
+
+TRANSLATION     METADATA
+        FPA.TELESCOPE   STR     TELESCOP
+        FPA.INSTRUMENT  STR     INSTRUME
+END
Index: /trunk/psModules/test/config/data/camera0/format1.config
===================================================================
--- /trunk/psModules/test/config/data/camera0/format1.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera0/format1.config	(revision 14880)
@@ -0,0 +1,34 @@
+RULE    METADATA
+        F1_KEY0        STR     string30
+        F1_KEY1        STR     string31
+        F1_KEY2        S32     30
+END
+
+FILE    METADATA
+        PHU             STR     FPA
+        EXTENSIONS      STR     CELL
+        FPA.NAME        STR     EXPNUM
+END
+
+DEFAULTS        METADATA
+        F1_DEF0           STR     DefString30
+        F1_DEF1           STR     DefString31
+        F1_DEF2           F32     31.0
+        F1_DEF3           S32     32
+END
+
+CELLS   METADATA
+        left    METADATA        # Left amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+        right   METADATA        # Right amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+END
+
+TRANSLATION     METADATA
+        FPA.TELESCOPE   STR     TELESCOP
+        FPA.INSTRUMENT  STR     INSTRUME
+END
Index: /trunk/psModules/test/config/data/camera0/recipe0.config
===================================================================
--- /trunk/psModules/test/config/data/camera0/recipe0.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera0/recipe0.config	(revision 14880)
@@ -0,0 +1,4 @@
+R0_KEY0		STR	RecipeString0
+R0_KEY1		STR	RecipeString1
+R0_KEY2		S32	2
+R0_KEY3		F32	3
Index: /trunk/psModules/test/config/data/camera0/recipe1.config
===================================================================
--- /trunk/psModules/test/config/data/camera0/recipe1.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera0/recipe1.config	(revision 14880)
@@ -0,0 +1,4 @@
+R1_KEY0		STR	RecipeString10
+R1_KEY1		STR	RecipeString11
+R1_KEY2		S32	12
+R1_KEY3		F32	13
Index: /trunk/psModules/test/config/data/camera1/camera.config
===================================================================
--- /trunk/psModules/test/config/data/camera1/camera.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera1/camera.config	(revision 14880)
@@ -0,0 +1,14 @@
+FORMATS         METADATA
+        C1_FM0     STR     camera1/format0.config
+        C1_FM1     STR     camera1/format1.config
+END
+
+RECIPES         METADATA
+        C1_RECIPE0          STR     camera1/recipe0.config
+        C1_RECIPE1          STR     camera1/recipe1.config
+END
+
+FPA     METADATA
+        ccd00   STR     LeftAmp RightAmp
+        ccd01   STR     LeftAmp RightAmp
+END
Index: /trunk/psModules/test/config/data/camera1/format0.config
===================================================================
--- /trunk/psModules/test/config/data/camera1/format0.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera1/format0.config	(revision 14880)
@@ -0,0 +1,34 @@
+RULE    METADATA
+        F0_KEY0        STR     string40
+        F0_KEY1        STR     string41
+        F0_KEY2        S32     420
+END
+
+FILE    METADATA
+        PHU             STR     FPA
+        EXTENSIONS      STR     CELL
+        FPA.NAME        STR     EXPNUM
+END
+
+DEFAULTS        METADATA
+        F0_DEF0           STR     DefString40
+        F0_DEF1           STR     DefString41
+        F0_DEF2           F32     41.0
+        F0_DEF3           S32     44
+END
+
+CELLS   METADATA
+        left    METADATA        # Left amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+        right   METADATA        # Right amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+END
+
+TRANSLATION     METADATA
+        FPA.TELESCOPE   STR     TELESCOP
+        FPA.INSTRUMENT  STR     INSTRUME
+END
Index: /trunk/psModules/test/config/data/camera1/format1.config
===================================================================
--- /trunk/psModules/test/config/data/camera1/format1.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera1/format1.config	(revision 14880)
@@ -0,0 +1,34 @@
+RULE    METADATA
+        F1_KEY0        STR     string80
+        F1_KEY1        STR     string81
+        F1_KEY2        S32     80
+END
+
+FILE    METADATA
+        PHU             STR     FPA
+        EXTENSIONS      STR     CELL
+        FPA.NAME        STR     EXPNUM
+END
+
+DEFAULTS        METADATA
+        F1_DEF0           STR     DefString80
+        F1_DEF1           STR     DefString81
+        F1_DEF2           F32     81.0
+        F1_DEF3           S32     82
+END
+
+CELLS   METADATA
+        left    METADATA        # Left amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+        right   METADATA        # Right amplifier
+                CELL.BIASSEC.SOURCE     STR     HEADER
+                CELL.TRIMSEC.SOURCE     STR     HEADER
+        END
+END
+
+TRANSLATION     METADATA
+        FPA.TELESCOPE   STR     TELESCOP
+        FPA.INSTRUMENT  STR     INSTRUME
+END
Index: /trunk/psModules/test/config/data/camera1/recipe0.config
===================================================================
--- /trunk/psModules/test/config/data/camera1/recipe0.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera1/recipe0.config	(revision 14880)
@@ -0,0 +1,4 @@
+R0_KEY0		STR	RecipeString120
+R0_KEY1		STR	RecipeString121
+R0_KEY2		S32	122
+R0_KEY3		F32	123
Index: /trunk/psModules/test/config/data/camera1/recipe1.config
===================================================================
--- /trunk/psModules/test/config/data/camera1/recipe1.config	(revision 14880)
+++ /trunk/psModules/test/config/data/camera1/recipe1.config	(revision 14880)
@@ -0,0 +1,4 @@
+R1_KEY0		STR	RecipeString230
+R1_KEY1		STR	RecipeString2311
+R1_KEY2		S32	232
+R1_KEY3		F32	233
Index: /trunk/psModules/test/config/data/path2/SampleIPPConfig2
===================================================================
--- /trunk/psModules/test/config/data/path2/SampleIPPConfig2	(revision 14880)
+++ /trunk/psModules/test/config/data/path2/SampleIPPConfig2	(revision 14880)
@@ -0,0 +1,32 @@
+### Example .ipprc file
+
+### Database configuration
+DBSERVER	STR	ippdb.ifa.hawaii.edu	# Database host name (for psDBInit)
+DBUSER		STR	ipp			# Database user name (for psDBInit)
+DBPASSWORD	STR	password		# Database password (for psDBInit)
+
+### Setups for each camera system
+CAMERAS		METADATA
+	MEGACAM_RAW	STR	megacam_raw.config
+	MEGACAM_SPLICE	STR	megacam_splice.config
+	GPC1_RAW	STR	gpc1_raw.config
+	LRIS_BLUE	STR	lris_blue.config
+	LRIS_RED	STR	lris_red.config
+END
+
+### psLib setup
+#TIME		STR	/home/mithrandir/price/pan-starrs/jhroot/i686-pc-linux-gnu/etc/pslib/psTime.config	# Time configuration file
+LOGLEVEL	S32	3			# Logging level; 3=INFO
+LOGFORMAT	STR	HLNM			# Log format
+LOGDEST	STR	STDOUT				# Log destination
+TRACE		METADATA			# Trace levels
+	dummyTraceFunc01	S32	1
+	dummyTraceFunc02	S32	2
+END
+ARBITRARY_STRING_S32	S32	20
+ARBITRARY_STRING_F32	F32	21.0
+ARBITRARY_STRING_F64	F64	22.0
+ARBITRARY_STRING_STR	STR	19.0
+ARBITRARY_STRING_BOOL_T	BOOL	true
+ARBITRARY_STRING_BOOL_F	BOOL	false
+
Index: /trunk/psModules/test/config/data/recipe_file00
===================================================================
--- /trunk/psModules/test/config/data/recipe_file00	(revision 14880)
+++ /trunk/psModules/test/config/data/recipe_file00	(revision 14880)
@@ -0,0 +1,2 @@
+recipe00		BOOL    TRUE
+recipe01		BOOL    FALSE
Index: /trunk/psModules/test/config/data/recipe_file01
===================================================================
--- /trunk/psModules/test/config/data/recipe_file01	(revision 14880)
+++ /trunk/psModules/test/config/data/recipe_file01	(revision 14880)
@@ -0,0 +1,2 @@
+recipe00		BOOL    FALSE
+recipe01		BOOL    TRUE
Index: /trunk/psModules/test/config/data/recipes_masks.config
===================================================================
--- /trunk/psModules/test/config/data/recipes_masks.config	(revision 14880)
+++ /trunk/psModules/test/config/data/recipes_masks.config	(revision 14880)
@@ -0,0 +1,10 @@
+### Recipe specifying values for various mask concepts
+BLANK           U8      0x01            # The pixel is blank or has no (valid) data
+FLAT            U8      0x02            # The pixel is non-positive in the flat-field
+DETECTOR        U8      0x02            # The detector pixel is bad (e.g., bad column, charge trap)
+SAT             U8      0x04            # The pixel is saturated in the image of interest
+BAD             U8      0x04            # The pixel is low in the image of interest
+RANGE           U8      0x04            # The pixel is out of range in the image of interest
+CR              U8      0x08            # The pixel is probably a CR
+SUSPECT         U8      0x40            # The pixel is suspected of being bad, but may not be
+MARK            U8      0x80            # The pixel is marked as temporarily ignored
Index: /trunk/psModules/test/config/tap_pmConfig.c
===================================================================
--- /trunk/psModules/test/config/tap_pmConfig.c	(revision 14879)
+++ /trunk/psModules/test/config/tap_pmConfig.c	(revision 14880)
@@ -3,18 +3,23 @@
  *  @brief Contains the tests for pmConfig.c:
  *
- * test00: This code will test the pmConfig() routine.
- *
- *  @author GLG, MHPCC
- *
- * XXX: Untested:
- * pmConfigValidateCamera()
- * pmConfigCameraFromHeader()
- * pmConfigRecipeFromCamera()
- * pmConfigDB()
- *
+ * This code will test the pmConfig() routine.
+*       pmConfigReadParamsSet
+*       pmConfigAlloc		
+*       pmConfigSet
+*       pmConfigDone
+*       pmConfigFileRead
+*        pmConfigValidateCameraFormat
+*        pmConfigCameraFormatFromHeader
+*        pmConfigCameraByName
+?        pmConfigDB
+*        pmConfigConformHeader
+-        pmConfigFileSets
+-        pmConfigFileSetsMD
+*        pmConfigConvertFilename
+*        pmConfigRead
  * XXXX: Must determine what to do with NULL arguments, then test it.
  *
- *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-06-19 18:28:38 $
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-09-18 18:55:36 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -26,4 +31,6 @@
 #include "tap.h"
 #include "pstap.h"
+#define ERR_TRACE_LEVEL         0
+#define	VERBOSE			0
 
 int main(int argc, char* argv[])
@@ -32,6 +39,25 @@
     psLogSetLevel(PS_LOG_INFO);
     psTraceSetLevel(".", 0);
-    plan_tests(20);
-
+    psTraceSetLevel("err", ERR_TRACE_LEVEL);
+    plan_tests(181);
+    
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Tests for pmConfigReadParamsSet()
+    {
+        psMemId id = psMemGetId();
+        bool oldReadCameraConfig = pmConfigReadParamsSet(false);
+        ok(oldReadCameraConfig == true, "pmConfigReadParamsSet() returned old value correctly");
+        oldReadCameraConfig = pmConfigReadParamsSet(true);
+        ok(oldReadCameraConfig == false, "pmConfigReadParamsSet() returned old value correctly");
+        oldReadCameraConfig = pmConfigReadParamsSet(true);
+        ok(oldReadCameraConfig == true, "pmConfigReadParamsSet() returned new value correctly");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+    
+    
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
     // Tests for pmConfigAlloc()
     // XXX: Add a MemCheckConfig() function to verify the return type
@@ -62,6 +88,921 @@
     }
 
-
-    // Verify error with NULL argc pointer
+    
+    
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigSet()
+    // Test with NULL input
+    // XX: Test with empty string?
+    {
+        psMemId id = psMemGetId();
+        pmConfigSet(NULL);
+        ok(true, "called pmConfigSet() with NULL input pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigSet(NULL) created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+    
+    
+    // Test with acceptable config file name, with a simple path
+    {
+        pmConfigDone();
+        psMemId id = psMemGetId();
+        psMetadata *config = NULL;
+        bool rc = pmConfigFileRead(&config, "SampleIPPConfig2", "DESCRIPTION");
+        ok(rc == false, "pmConfigFileRead() returned FALSE before calling pmConfigSet()");
+        pmConfigSet("data/path2");
+        rc = pmConfigFileRead(&config, "SampleIPPConfig2", "DESCRIPTION");
+        ok(rc == true, "pmConfigFileRead() returned TRUE after calling pmConfigSet() (test 1)");
+        psFree(config);
+        pmConfigDone();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with acceptable config file name, with a compound path
+    {
+        pmConfigDone();
+        psMemId id = psMemGetId();
+        psMetadata *config = NULL;
+        bool rc = pmConfigFileRead(&config, "SampleIPPConfig2", "DESCRIPTION");
+        ok(rc == false, "pmConfigFileRead() returned FALSE before calling pmConfigSet()");
+        pmConfigSet("junk:data/path2:data/path5");
+        rc = pmConfigFileRead(&config, "SampleIPPConfig2", "DESCRIPTION");
+        ok(rc == true, "pmConfigFileRead() returned TRUE after calling pmConfigSet() (test 2)");
+        psFree(config);
+        pmConfigDone();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigDone(): ensure it frees memory allocated by pmConfigSet();
+    // This also ensures that pmConfigSet() psFrees memory between calls
+    {
+        psMemId id = psMemGetId();
+        pmConfigSet("junk01");
+        pmConfigSet("junk:data/path2:data/path5");
+        pmConfigSet("junk02");
+        pmConfigDone();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks: pmConfigDone()");
+    }
+
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigFileRead()
+    // Test with NULL config pointer
+    // XXX: There's a memory leak if the first argument points to data that's
+    // already allocated (pmConfigFileRead() frees the first argument)
+    {
+        psMemId id = psMemGetId();
+        psString name = "foo1";
+        psString desc = "foo2";
+        bool rc = pmConfigFileRead(NULL, name, desc);
+        ok(rc == false, "pmConfigFileRead() returned FALSE with NULL config pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigFileRead() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL name pointer
+    // XXX: Test with empty name string?
+    {
+        psMemId id = psMemGetId();
+        psMetadata *config = psMetadataAlloc();
+        psString desc = "foo2";
+        bool rc = pmConfigFileRead(&config, NULL, desc);
+        ok(rc == false, "pmConfigFileRead() returned FALSE with NULL name pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileRead() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL desc pointer
+    // XXX: Test with empty desc string and otherwise acceptable inputs.
+    // That generated errors elsewhere.
+    {
+        psMemId id = psMemGetId();
+        psMetadata *config = psMetadataAlloc();
+        psString name = "foo1";
+        bool rc = pmConfigFileRead(&config, name, NULL);
+        ok(rc == false, "pmConfigFileRead() returned FALSE with NULL desc pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileRead() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with acceptable config file name, no paths
+    // This generates an error because config is non-NULL and pmConfigFileRead()
+    // psFrees it.  Create a bugzilla report.
+    {
+        psMemId id = psMemGetId();
+        psMetadata *config = psMetadataAlloc();
+        psString name = "data/SampleIPPConfig";
+        psString desc = "DESCRIPTION";
+        bool rc = pmConfigFileRead(&config, name, desc);
+        ok(rc == true, "pmConfigFileRead() returned TRUE with acceptable inputs");
+
+        // Test the several arbitrary config file strings.
+        psS32 tmpInt = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_S32");
+        ok(rc == true && tmpInt == 20, "pmConfigFileRead() properly set metadata (S32)");
+        psF32 tmpFloat = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F32");
+        ok(rc == true && tmpFloat == 21.0, "pmConfigFileRead() properly set metadata (F32)");
+        psF64 tmpDub = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F64");
+        ok(rc == true && tmpDub == 22.0, "pmConfigFileRead() properly set metadata (F64)");
+        psBool tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_T");
+        ok(rc == true && tmpBool == true, "pmConfigFileRead() properly set metadata (bool)");
+        tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_F");
+        ok(rc == true && tmpBool == false, "pmConfigFileRead() properly set metadata (bool)");
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with acceptable config file name, no paths
+    {
+        psMemId id = psMemGetId();
+        psMetadata *config = NULL;
+        psString name = "data/SampleIPPConfig";
+        psString desc = "DESCRIPTION";
+        bool rc = pmConfigFileRead(&config, name, desc);
+        ok(rc == true, "pmConfigFileRead() returned TRUE with acceptable inputs");
+
+        // Test the several arbitrary config file strings.
+        psS32 tmpInt = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_S32");
+        ok(rc == true && tmpInt == 20, "pmConfigFileRead() properly set metadata (S32)");
+        psF32 tmpFloat = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F32");
+        ok(rc == true && tmpFloat == 21.0, "pmConfigFileRead() properly set metadata (F32)");
+        psF64 tmpDub = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F64");
+        ok(rc == true && tmpDub == 22.0, "pmConfigFileRead() properly set metadata (F64)");
+        psBool tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_T");
+        ok(rc == true && tmpBool == true, "pmConfigFileRead() properly set metadata (bool)");
+        tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_F");
+        ok(rc == true && tmpBool == false, "pmConfigFileRead() properly set metadata (bool)");
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable config file name, no paths
+    {
+        psMemId id = psMemGetId();
+        psMetadata *config = NULL;
+        psString name = "data/SampleIPPConfig";
+        psString desc = "DESCRIPTION";
+        bool rc = pmConfigFileRead(&config, name, desc);
+        ok(rc == true, "pmConfigFileRead() returned TRUE with acceptable inputs");
+
+        // Test the several arbitrary config file strings.
+        psS32 tmpInt = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_S32");
+        ok(rc == true && tmpInt == 20, "pmConfigFileRead() properly set metadata (S32)");
+        psF32 tmpFloat = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F32");
+        ok(rc == true && tmpFloat == 21.0, "pmConfigFileRead() properly set metadata (F32)");
+        psF64 tmpDub = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F64");
+        ok(rc == true && tmpDub == 22.0, "pmConfigFileRead() properly set metadata (F64)");
+        psBool tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_T");
+        ok(rc == true && tmpBool == true, "pmConfigFileRead() properly set metadata (bool)");
+        tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_F");
+        ok(rc == true && tmpBool == false, "pmConfigFileRead() properly set metadata (bool)");
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable config file name, with path
+    // Note: This also tests the pmConfigSet() function.
+    {
+        psMemId id = psMemGetId();
+        psMetadata *config = NULL;
+        psString name = "SampleIPPConfig2";
+        psString desc = "DESCRIPTION";
+        pmConfigSet("data/path2");
+        bool rc = pmConfigFileRead(&config, name, desc);
+        ok(rc == true, "pmConfigFileRead() returned TRUE using paths");
+        // Test the several arbitrary config file strings.
+        psS32 tmpInt = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_S32");
+        ok(rc == true && tmpInt == 20, "pmConfigFileRead() properly set metadata (S32)");
+        psF32 tmpFloat = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F32");
+        ok(rc == true && tmpFloat == 21.0, "pmConfigFileRead() properly set metadata (F32)");
+        psF64 tmpDub = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_F64");
+        ok(rc == true && tmpDub == 22.0, "pmConfigFileRead() properly set metadata (F64)");
+        psBool tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_T");
+        ok(rc == true && tmpBool == true, "pmConfigFileRead() properly set metadata (bool)");
+        tmpBool = psMetadataLookupS32(&rc, config, "ARBITRARY_STRING_BOOL_F");
+        ok(rc == true && tmpBool == false, "pmConfigFileRead() properly set metadata (bool)");
+        psFree(config);
+        pmConfigDone();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigValidateCameraFormat()
+    // Test with NULL valid pointer
+    // XXX: This is commented out because of a seg-fault
+    if (0) {
+        psMemId id = psMemGetId();
+        psMetadata *cameraFormat = psMetadataAlloc();
+        psMetadata *header = psMetadataAlloc();
+        bool rc = pmConfigValidateCameraFormat(NULL, cameraFormat, header);
+        ok(rc == false, "pmConfigValidateCameraFormat() returned FALSE with NULL valid pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(cameraFormat);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL cameraFormat pointer
+    {
+        psMemId id = psMemGetId();
+        bool valid;
+        psMetadata *cameraFormat = psMetadataAlloc();
+        psMetadata *header = psMetadataAlloc();
+        bool rc = pmConfigValidateCameraFormat(&valid, NULL, header);
+        ok(rc == false, "pmConfigValidateCameraFormat() returned FALSE with NULL valid pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(cameraFormat);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL header pointer
+    {
+        psMemId id = psMemGetId();
+        bool valid;
+        psMetadata *cameraFormat = psMetadataAlloc();
+        psMetadata *header = psMetadataAlloc();
+        bool rc = pmConfigValidateCameraFormat(&valid, cameraFormat, NULL);
+        ok(rc == false, "pmConfigValidateCameraFormat() returned FALSE with NULL valid pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(cameraFormat);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable input
+    // psTraceSetLevel("psModules.config", 10);
+    {
+        psMemId id = psMemGetId();
+        bool valid;
+        psMetadata *header = psMetadataAlloc();
+        psMetadata *camera = psMetadataAlloc();
+        // Test with unitialized camera metadata
+        bool rc = pmConfigValidateCameraFormat(&valid, camera, header);
+        ok(rc == false && valid == false, "pmConfigValidateCameraFormat() returned FALSE with uninitialized psMetadata");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_UNKNOWN == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_UNKNOWN error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(camera);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable input
+    // psTraceSetLevel("psModules.config", 10);
+    // Add a test that sets the metadata value incorrectly
+    {
+        psMemId id = psMemGetId();
+        bool valid;
+        psMetadata *header = psMetadataAlloc();
+        psMetadata *camera = NULL;
+        bool rc = pmConfigFileRead(&camera, "data/camera0/format0.config", "Camera 0 Config File");
+        ok(rc == true, "pmConfigFileRead() read data/camera0/format0.config");
+        psMetadataAddStr(header, PS_LIST_TAIL, "F0_KEY0", 0, "", "string20");
+        rc = pmConfigValidateCameraFormat(&valid, camera, header);
+        ok(rc == true, "pmConfigValidateCameraFormat() returned FALSE with acceptable input, wrong values");
+        ok(valid == false, "pmConfigValidateCameraFormat() rejected header correctly");
+        psMetadataAddStr(header, PS_LIST_TAIL, "F0_KEY1", 0, "", "string21");
+        rc = pmConfigValidateCameraFormat(&valid, camera, header);
+        ok(rc == true, "pmConfigValidateCameraFormat() returned FALSE with acceptable input, wrong values");
+        ok(valid == false, "pmConfigValidateCameraFormat() rejected header correctly");
+        psMetadataAddS32(header, PS_LIST_TAIL, "F0_KEY2", 0, "", 20);
+        rc = pmConfigValidateCameraFormat(&valid, camera, header);
+        ok(rc == true, "pmConfigValidateCameraFormat() returned TRUE with acceptable input, correct values");
+        ok(valid == true, "pmConfigValidateCameraFormat() accepted header correctly");
+        psFree(camera);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigCameraFormatFromHeader()
+    //
+    // Given a FITS header, check it against all known cameras (unless we
+    // already know which camera, from pmConfigRead) and all known formats
+    // for those cameras in order to identify which is appropriate.
+    //
+    // psMetadata *pmConfigCameraFormatFromHeader(
+    //    pmConfig *config,
+    //    const psMetadata *header,
+    //    bool readRecipes)
+    // Test with NULL config pointer
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        psMetadata *header = psMetadataAlloc();
+        bool readRecipes = false;
+        psMetadata *camera = pmConfigCameraFormatFromHeader(NULL, header, readRecipes);
+        ok(camera == NULL, "pmConfigCameraFormatFromHeader() returned NULL with NULL config pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigCameraFormatFromHeader() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL header pointer
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        psMetadata *header = psMetadataAlloc();
+        bool readRecipes = false;
+        psMetadata *camera = pmConfigCameraFormatFromHeader(config, NULL, readRecipes);
+        ok(camera == NULL, "pmConfigCameraFormatFromHeader() returned NULL with NULL header pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigCameraFormatFromHeader() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable inputs
+    if (1) {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        psMetadata *header = psMetadataAlloc();
+        bool readRecipes = false;
+        // Load a sample config file
+        bool rc = pmConfigFileRead(&config->site, "data/SampleIPPConfig", "DESCRIPTION");
+        ok(rc == true && !config, "pmConfigFileRead() was successful");
+        // Set metadata tags for a simulated FITS header
+        psMetadataAddStr(header, PS_LIST_TAIL, "F0_KEY0", 0, "", "string20");
+        psMetadataAddStr(header, PS_LIST_TAIL, "F0_KEY1", 0, "", "string21");
+        psMetadataAddS32(header, PS_LIST_TAIL, "F0_KEY2", 0, "", 20);
+        psMetadata *camera = pmConfigCameraFormatFromHeader(config, header, readRecipes);
+
+        ok(camera != NULL,
+          "pmConfigCameraFormatFromHeader() returned non-NULL with acceptable inputs");
+        ok(camera != NULL && psMemCheckMetadata(camera),
+          "pmConfigCameraFormatFromHeader() returned non-NULL and correct type with acceptable inputs");
+        psFree(config);
+        psFree(header);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigCameraByName()
+    //    psMetadata *pmConfigCameraByName(pmConfig *config, const char *cameraName)
+    // Test with NULL config pointer
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        psString cameraName = "CameraName";
+        psMetadata *camera = pmConfigCameraByName(NULL, cameraName);
+        ok(camera == NULL, "pmConfigCameraByName() returned NULL with NULL config pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigCameraByName() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL camera Name
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        // psString cameraName = "CameraName";
+        psMetadata *camera = pmConfigCameraByName(config, NULL);
+        ok(camera == NULL, "pmConfigCameraByName() returned NULL with NULL camera name");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigCameraByName() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    psTraceSetLevel("err", 10);
+    // Test with acceptable data
+    if (1) {
+        psMemId id = psMemGetId();
+        pmConfigSet("data");
+        pmConfig *config = pmConfigAlloc();
+        bool rc = pmConfigFileRead(&config->site, "data/SampleIPPConfig", "DESCRIPTION");
+        ok(rc == true, "pmConfigFileRead() was successful");
+        psString cameraName = "CAMERA0";
+        psMetadata *camera = pmConfigCameraByName(config, cameraName);
+        ok(camera != NULL && psMemCheckMetadata(camera),
+          "pmConfigCameraByName() returned non-NULL with acceptable");
+        char *tmpStr = psMetadataLookupStr(&rc, camera, "ID");
+        ok(tmpStr != NULL && !strcmp(tmpStr, "CAMERA0"), "pmConfigCameraByName() returned non-NULL(CAMERA0)");
+        pmConfigDone();
+        psFree(config);
+        psFree(tmpStr);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigDB()
+    // psDB *pmConfigDB(pmConfig *config)
+    // Test with NULL config pointer
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        psDB *db = pmConfigDB(NULL);
+        ok(db == NULL, "pmConfigDB() returned NULL with NULL config pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigDB()() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL config->site pointer
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        config->site = NULL;
+        psDB *db = pmConfigDB(config);
+        ok(db == NULL, "pmConfigDB() returned NULL with NULL config->site pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigDB()() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable data
+    // XXX: Not tested.
+    if (1) {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        config->site = psMetadataAlloc();
+        bool rc = pmConfigFileRead(&config->site, "data/SampleIPPConfig", "DESCRIPTION");
+        ok(rc == true, "pmConfigFileRead() was successful");
+        skip_start(rc == false, 1, "Skipping pmConfigDB() tests because we could not read config file");
+        psDB *db = pmConfigDB(config);
+        ok(db != NULL, "pmConfigDB() returned non NULL with acceptable data");
+        psFree(db);
+        skip_end();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigConformHeader()
+    // Test with NULL header pointer
+    {
+        psMemId id = psMemGetId();
+        psMetadata *header = psMetadataAlloc();
+        psMetadata *format = psMetadataAlloc();
+        bool rc = pmConfigConformHeader(NULL, (const psMetadata *) format);
+        ok(rc == false, "pmConfigConformHeader() returned FALSE with NULL header pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigConformHeader() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(header);
+        psFree(format);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test with NULL format pointer
+    {
+        psMemId id = psMemGetId();
+        psMetadata *header = psMetadataAlloc();
+        psMetadata *format = psMetadataAlloc();
+        bool rc = pmConfigConformHeader(header, NULL);
+        ok(rc == false, "pmConfigConformHeader() returned FALSE with NULL header pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigConformHeader() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(header);
+        psFree(format);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test with acceptable data
+    {
+        psMemId id = psMemGetId();
+        bool valid;
+        psMetadata *header = psMetadataAlloc();
+        psMetadata *format = psMetadataAlloc();
+        bool rc = pmConfigFileRead(&format, "data/camera0/format0.config", "Camera 0 Config File");
+        ok(rc == true, "pmConfigFileRead() read camera format correctly");
+
+        // First ensure that the header is not accepted
+        rc = pmConfigValidateCameraFormat(&valid, format, header);
+        ok(rc == true && valid == false, "pmConfigValidateCameraFormat() rejected header with uninitialized psMetadata");
+
+        // Now call pmConfigConformHeader() and ensure that the header is accepted
+        rc = pmConfigConformHeader(header, format);
+        ok(rc == true, "pmConfigConformHeader() returned TRUE");
+        rc = pmConfigValidateCameraFormat(&valid, format, header);
+        ok(rc == true, "pmConfigValidateCameraFormat() returned TRUE");
+        ok(valid == true, "pmConfigValidateCameraFormat() validated camera format");
+        psFree(header);
+        psFree(format);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigFileSets()
+    // test with NULL argc pointer
+    {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        char *filename = "FILENAME";
+        char *list = "LIST";
+        psArray *array = pmConfigFileSets(NULL, str, filename, list);
+        ok(array == NULL, "pmConfigFileSets() returned NULL with NULL argc pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigFileSets() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with negative argc pointer
+    {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = -1;
+        char *filename = "FILENAME";
+        char *list = "LIST";
+        psArray *array = pmConfigFileSets(&myArgc, str, filename, list);
+        ok(array == NULL, "pmConfigFileSets() returned NULL with negative argc pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileSets() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL argv pointer
+    {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *filename = "FILENAME";
+        char *list = "LIST";
+        psArray *array = pmConfigFileSets(&myArgc, NULL, filename, list);
+        ok(array == NULL, "pmConfigFileSets() returned NULL with NULL argv pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigFileSets() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL filename pointer
+    {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *list = "LIST";
+        psArray *array = pmConfigFileSets(&myArgc, str, NULL, list);
+        ok(array == NULL, "pmConfigFileSets() returned NULL with NULL filename pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileSets() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL list pointer
+    {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *filename = "FILENAME";
+        psArray *array = pmConfigFileSets(&myArgc, str, filename, NULL);
+        ok(array == NULL, "pmConfigFileSets() returned NULL with NULL list pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileSets() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with acceptable data
+    if (0) {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *filename = "FILENAME";
+        char *list = "LIST";
+        psArray *array = pmConfigFileSets(&myArgc, str, filename, list);
+        ok(array != NULL && psMemCheckArray(array),
+          "pmConfigFileSets() returned non-NULL with acceptable input data");
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigFileSetsMD()
+    // bool pmConfigFileSetsMD(psMetadata *metadata, int *argc, char **argv, const char *name,
+    //                         const char *file, const char *list)
+    // XX: Should we test/check for bad argv/argc params?
+    // test with NULL metadata pointer
+    {
+        psMemId id = psMemGetId();
+        psMetadata *metadata = psMetadataAlloc();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *name = "NAME";
+        char *file = "FILENAME";
+        char *list = "LIST";
+        bool rc = pmConfigFileSetsMD(NULL, &myArgc, str, name, file, list);
+        ok(rc == false, "pmConfigFileSetsMD() returned FALSE with NULL metadata pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigFileSetsMD() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psFree(metadata);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL name pointer
+    {
+        psMemId id = psMemGetId();
+        psMetadata *metadata = psMetadataAlloc();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *file = "FILENAME";
+        char *list = "LIST";
+        bool rc = pmConfigFileSetsMD(metadata, &myArgc, str, NULL, file, list);
+        ok(rc == false, "pmConfigFileSetsMD() returned FALSE with NULL name pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileSetsMD() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psFree(metadata);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL file pointer
+    {
+        psMemId id = psMemGetId();
+        psMetadata *metadata = psMetadataAlloc();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *name = "NAME";
+        char *list = "LIST";
+        bool rc = pmConfigFileSetsMD(metadata, &myArgc, str, name, NULL, list);
+        ok(rc == false, "pmConfigFileSetsMD() returned FALSE with NULL file pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileSetsMD() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psFree(metadata);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL list pointer
+    {
+        psMemId id = psMemGetId();
+        psMetadata *metadata = psMetadataAlloc();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *name = "NAME";
+        char *file = "FILENAME";
+        bool rc = pmConfigFileSetsMD(metadata, &myArgc, str, name, file, NULL);
+        ok(rc == false, "pmConfigFileSetsMD() returned FALSE with NULL list pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigFileSetsMD() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psFree(metadata);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with acceptable input data
+    if (0) {
+        psMemId id = psMemGetId();
+        psMetadata *metadata = psMetadataAlloc();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int myArgc = 3;
+        char *name = "NAME";
+        char *file = "FILENAME";
+        char *list = "LIST";
+        bool rc = pmConfigFileSetsMD(metadata, &myArgc, str, name, file, list);
+        ok(rc == true, "pmConfigFileSetsMD() returned TRUE with acceptable input data");
+        psFree(metadata);
+        psErrorClear();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigConvertFilename()
+    // convert the supplied name, create a new output psString
+    // psString pmConfigConvertFilename(const char *filename, const pmConfig *config,
+    //                                  bool create)
+    // test with NULL filename pointer
+    {
+        psMemId id = psMemGetId();
+        pmConfig *config = pmConfigAlloc();
+        bool create = false;
+        bool rc = pmConfigConvertFilename(NULL, (const pmConfig *) config, create);
+        ok(rc == false, "pmConfigConvertFilename() returned FALSE with NULL filename pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_VALUE == tmpErr->code,
+          "pmConfigConvertFilename() created the PS_ERR_BAD_PARAMETER_VALUE error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // test with NULL config pointer
+    {
+        psMemId id = psMemGetId();
+        char *name = "NAME";
+        pmConfig *config = pmConfigAlloc();
+        bool create = false;
+        bool rc = pmConfigConvertFilename(name, NULL, create);
+        ok(rc == false, "pmConfigConvertFilename() returned FALSE with NULL config pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigConvertFilename() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    // test with acceptable input data
+    // First call with create==FALSE, and a filename that does not exist.
+    // Should return NULL.  Then set create==TRUE, and call; should return
+    // "JUNK".  Then call again with create==FALSE; should return "JUNK"
+    if (1) {
+        psMemId id = psMemGetId();
+        char *filename = "file:///////JUNK";
+        pmConfig *config = pmConfigAlloc();
+        bool rc = pmConfigFileRead(&config->site, "data/SampleIPPConfig", "DESCRIPTION");
+        ok(rc == true, "pmConfigFileRead() was successful");
+        bool create = false;
+        psString tmpStr = pmConfigConvertFilename(filename, (const pmConfig *) config, create);
+        ok(NULL == tmpStr, "pmConfigConvertFilename() returned NULL with create==FALSE");
+        create = true;
+        tmpStr = pmConfigConvertFilename(filename, (const pmConfig *) config, create);
+        ok(tmpStr != NULL, "pmConfigConvertFilename() returned non-NULL with create==TRUE");
+        ok(!strcmp(tmpStr, "/JUNK"), "pmConfigConvertFilename() returned correct filename (%s)", tmpStr);
+        psFree(tmpStr);
+        psFree(config);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+    // --------------------------------------------------------------------
+    // --------------------------------------------------------------------
+    // Test pmConfigRead()
+    // Test with NULL argc pointer
     {
         psMemId id = psMemGetId();
@@ -72,31 +1013,52 @@
         pmConfig *myConfig = pmConfigRead(NULL, str, "RecipeName");
         ok(myConfig == NULL, "pmConfigRead() returned NULL with NULL argc pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
         psFree(myConfig);
         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     }
 
-    // Verify error with NULL argv pointer
+
+    // Test with NULL argv pointer
     {
         psMemId id = psMemGetId();
         pmConfig *myConfig = pmConfigRead(&argc, NULL, "RecipeName");
         ok(myConfig == NULL, "pmConfigRead() returned NULL with NULL argv pointer");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
         psFree(myConfig);
         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     }
 
-    // Verify non-error with NULL recipe string
-    {
-        psMemId id = psMemGetId();
-        psString str[3];
-        str[0] = "ARGS:";
-        str[1] = "-site";
-        str[2] = "data/SampleIPPConfig";
-        pmConfig *myConfig = pmConfigRead(&argc, str, NULL);
+
+    // Test with NULL recipe string (should not cause error)
+    // XXX: Not working, debug
+    if (0) {
+        psMemId id = psMemGetId();
+        char *str[3];
+        str[0] = "ARGS:";
+        str[1] = "-site";
+        str[2] = "data/SampleIPPConfig";
+        int numArgs = 3;
+        pmConfig *myConfig = pmConfigRead(&numArgs, str, NULL);
         ok(myConfig != NULL, "pmConfigRead() returned non-NULL with NULL recipe");
+        psErr *tmpErr = psErrorLast();
+        ok(PS_ERR_BAD_PARAMETER_NULL == tmpErr->code,
+          "pmConfigValidateCameraFormat() created the PS_ERR_BAD_PARAMETER_NULL error");
+        psFree(tmpErr);
+        psErrorClear();
         psFree(myConfig);
         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     }
 
-    {
+
+    // Test pmConfigRead() with acceptable data.
+    if (1) {
         psMemId id = psMemGetId();
         bool testStatus = true;
@@ -113,4 +1075,5 @@
         bool rc;
         pmConfig *myConfig = pmConfigRead(&argc, str, "RecipeName");
+        ok(myConfig, "pmConfigRead() returned non-NULL");
         if (myConfig == NULL) {
             printf("TEST ERROR: pmConfigRead() returned NULL\n");
@@ -245,4 +1208,5 @@
         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     }
+
 }
-//HERE
+
