From: <ro...@us...> - 2011-03-08 20:42:07
|
Revision: 1815 http://nsclspectcl.svn.sourceforge.net/nsclspectcl/?rev=1815&view=rev Author: ron-fox Date: 2011-03-08 20:42:01 +0000 (Tue, 08 Mar 2011) Log Message: ----------- - Completed testing/refactoring of bits and pieces into internal - Get workspace_base operational. Modified Paths: -------------- trunk/nextgen/primitives/eventstest.c trunk/nextgen/primitives/spectcl_events.c trunk/nextgen/primitives/spectcl_experiment.h trunk/nextgen/primitives/spectcl_experimentInternal.c trunk/nextgen/primitives/spectcl_experimentInternal.h trunk/nextgen/primitives/spectcl_workspace_base.c trunk/nextgen/primitives/spectcl_wsbasetest.c Modified: trunk/nextgen/primitives/eventstest.c =================================================================== --- trunk/nextgen/primitives/eventstest.c 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/eventstest.c 2011-03-08 20:42:01 UTC (rev 1815) @@ -288,7 +288,7 @@ */ START_TEST(test_detach_none1) { - fail_unless(spectcl_events_detach(db, NULL) == SPEXP_NOT_EVENTSDATABASE); + fail_unless(spectcl_events_detach(db, NULL) == SPEXP_UNATTACHED); } END_TEST /* @@ -297,7 +297,7 @@ START_TEST(test_detach_none2) { spectcl_events_attach(db, expName, NULL); - fail_unless(spectcl_events_detach(db, "NoSuchDatabaseHere") == SPEXP_NOT_EVENTSDATABASE); + fail_unless(spectcl_events_detach(db, "NoSuchDatabaseHere") == SPEXP_UNATTACHED); } END_TEST /** Modified: trunk/nextgen/primitives/spectcl_events.c =================================================================== --- trunk/nextgen/primitives/spectcl_events.c 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/spectcl_events.c 2011-03-08 20:42:01 UTC (rev 1815) @@ -415,13 +415,12 @@ } /* Ensure this event database matches the experiment we are open on. */ - myUuidString = getfirst(pEvents, "configuration_values", "config_value", "config_item", "uuid"); - uuid_parse(myUuidString, myuuid); - free(myUuidString); - spectcl_events_close(pEvents); /* don't need the handle for the attach, so close here */ - if (!spectcl_correct_experiment(pExpHandle, &myuuid)) { + if (!spectcl_uuidCheck(pExpHandle, pEvents)) { + spectcl_events_close(pEvents); return SPEXP_WRONGEXPERIMENT; } + + spectcl_events_close(pEvents); /* don't need the handle for the attach, so close here */ /* Try to do the attach. Note that it's not legal (I think) to parameterize the database ** name.. hence the sprintf. @@ -442,56 +441,36 @@ ** @retval SPEXP_NOT_EVENTSDATABASE - there is no events database at that point. ** @retval SPEXP_SQLFAIL - The detach sql failed. ** @retval SPEXP_NOMEM - memory allocation failed. + ** @retval SPEXP_NOT_EXPDATABASE - pExperiment is not a n experiment database. */ int spectcl_events_detach(spectcl_experiment pExperiment, const char* name) { char* pType; const char* pName = DEFAULT_ATTACH_POINT; - const char* pQuery = "DETACH DATABASE :dbname"; char* tableName; size_t tableNameLen; - sqlite3_stmt* statement; int status; + /* Ensure pExperiment is what we think it is: */ + + if (!isExperimentDatabase(pExperiment)) { + return SPEXP_NOT_EXPDATABASE; + } + /* Ensure there's a database attached there */ if (name != NULL) { pName = name; } - tableNameLen = strlen(pName) + strlen(".configuration_values "); - tableName = malloc(tableNameLen); - if(!tableName) return SPEXP_NOMEM; - strcpy(tableName, pName); - strcat(tableName, ".configuration_values"); - pType = getfirst(pExperiment, tableName, "config_value", "config_item", "type"); - free(tableName); - if (!pType) return SPEXP_NOT_EVENTSDATABASE; - - - status = sqlite3_prepare_v2(pExperiment, - pQuery, -1, &statement, NULL); - if (status != SQLITE_OK) { - spectcl_experiment_errno = status; - return SPEXP_SQLFAIL; + status = spectcl_checkAttached(pExperiment, pName, "run-data", SPEXP_NOT_EVENTSDATABASE); + if (status != SPEXP_OK) { + return status; } - status = sqlite3_bind_text(statement, 1, pName, -1, SQLITE_STATIC); - if (status != SQLITE_OK) { - spectcl_experiment_errno = status; - sqlite3_finalize(statement); - return SPEXP_SQLFAIL; - } - status = sqlite3_step(statement); - if (status != SQLITE_DONE) { - sqlite3_finalize(statement); - spectcl_experiment_errno = status; - return SPEXP_SQLFAIL; - } - sqlite3_finalize(statement); - - return SPEXP_OK; + return spectcl_detach(pExperiment, pName); + } /** Modified: trunk/nextgen/primitives/spectcl_experiment.h =================================================================== --- trunk/nextgen/primitives/spectcl_experiment.h 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/spectcl_experiment.h 2011-03-08 20:42:01 UTC (rev 1815) @@ -211,8 +211,8 @@ /** Functions that operate on the configuration items table: */ - const char* spectcl_workspace_version(spectcl_workspace ws); - uuid_t* spectcl_workspace_uuid(spectcl_workspace ws); + char* spectcl_workspace_version(spectcl_workspace ws); + uuid_t* spectcl_workspace_uuid(spectcl_workspace ws); /** Functions used to validate the handle against various conditions */; Modified: trunk/nextgen/primitives/spectcl_experimentInternal.c =================================================================== --- trunk/nextgen/primitives/spectcl_experimentInternal.c 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/spectcl_experimentInternal.c 2011-03-08 20:42:01 UTC (rev 1815) @@ -381,3 +381,110 @@ return SPEXP_OK; } + +/** + ** Detaches a database at the specified detach point. + ** @param db - sqlite3 handle to the database. + ** @param pName - Attach point for the database. + ** @return int + ** @retval SPEXP_OK - Success. + ** @retval SPEXP_SQLFAIL - error prepping or executing the detach statement. + */ +int +spectcl_detach(sqlite3* db, const char* pName) +{ + const char* pQuery = "DETACH DATABASE :dbname"; + sqlite3_stmt* statement; + int status; + + status = sqlite3_prepare_v2(db, + pQuery, -1, &statement, NULL); + if (status != SQLITE_OK) { + spectcl_experiment_errno = status; + return SPEXP_SQLFAIL; + } + status = sqlite3_bind_text(statement, 1, pName, -1, SQLITE_STATIC); + if (status != SQLITE_OK) { + spectcl_experiment_errno = status; + sqlite3_finalize(statement); + return SPEXP_SQLFAIL; + } + status = sqlite3_step(statement); + if (status != SQLITE_DONE) { + sqlite3_finalize(statement); + spectcl_experiment_errno = status; + return SPEXP_SQLFAIL; + } + sqlite3_finalize(statement); + + + return SPEXP_OK; + + + +} +/** + ** Checks that an attach point has the right type of database on it by + ** looking at the configuration_values 'type' entry. + ** @param db - The base database handle to check. + ** @param pAttachName - The Attachment point + ** @param type - Desired database type (e.g. 'events'). + ** @param incorrectStatus - Desired return if the query worked but the database was wrong. + ** @return int + ** @retval SPEXP_OK - All the queries worked and the database was the right type. + ** @retval SPEXP_UNATTACHED - got nothing back from the query..so not attached. + ** @retval incorrectStatus - If the type returned did not match the desired type. + */ +int +spectcl_checkAttached(sqlite3* db, const char* pAttachname, const char* type, int incorrectStatus) +{ + char* pType; + char* tableName; + size_t tableNameLen; + int status; + + tableNameLen = strlen(pAttachname) + strlen(".configuration_values "); + tableName = malloc(tableNameLen); + if(!tableName) return SPEXP_NOMEM; + + strcpy(tableName, pAttachname); + strcat(tableName, ".configuration_values"); + pType = getfirst(db, tableName, "config_value", "config_item", "type"); + free(tableName); + if (!pType) return SPEXP_UNATTACHED; + + status = strcmp(pType, type) == 0 ? SPEXP_OK : incorrectStatus; + + free(pType); + + return status; + +} +/** + ** Determines if the UUID's associated with a pair of databases match. + ** @param db1 - First database. + ** @param db2 - Second database. + ** @return int + ** @retval TRUE - UUID could be retrieved and matched. + ** @retval FALSE - Either one or more UUID's could not be retrieved, + ** or they both could be but did not match. + */ +int +spectcl_uuidCheck(sqlite3* db1, sqlite3* db2) +{ + uuid_t* uuid1; + uuid_t* uuid2; + int retval; + + retval = 0; /* Assume false. */ + + uuid1 = getDBUUID(db1); + uuid2 = getDBUUID(db2); + if (uuid1 && uuid2) { + retval = uuid_compare(*uuid1, *uuid2) == 0; + } + free(uuid1); + free(uuid2); + + return retval; +} Modified: trunk/nextgen/primitives/spectcl_experimentInternal.h =================================================================== --- trunk/nextgen/primitives/spectcl_experimentInternal.h 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/spectcl_experimentInternal.h 2011-03-08 20:42:01 UTC (rev 1815) @@ -42,8 +42,9 @@ pRunInfo marshallRunInfo(sqlite3_stmt* stmt); uuid_t* getDBUUID(sqlite3* db); int spectcl_attach(sqlite3* db, const char* otherDatabase, const char* point, const char* defaultPoint); - - +int spectcl_detach(sqlite3* db, const char* pName); +int spectcl_checkAttached(sqlite3* db, const char* pAttachName, const char* type, int incorrectStatus); +int spectcl_uuidCheck(sqlite3* db1, sqlite3* db2); #ifdef __cplusplus } #endif Modified: trunk/nextgen/primitives/spectcl_workspace_base.c =================================================================== --- trunk/nextgen/primitives/spectcl_workspace_base.c 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/spectcl_workspace_base.c 2011-03-08 20:42:01 UTC (rev 1815) @@ -24,6 +24,7 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <stdio.h> #ifndef TRUE #define TRUE 1 @@ -239,17 +240,13 @@ else { /* Check that the workspace UUID matches that of the experiment */ - expUuid = getDBUUID(pHandle); - wsUuid = getDBUUID(ws); + if (!spectcl_uuidCheck(pHandle, ws)) { + spectcl_workspace_close(ws); + return SPEXP_WRONGEXPERIMENT; + } + spectcl_workspace_close(ws); /* TODO: When close is working use that instead. */ - status = uuid_compare(*expUuid, *wsUuid); - free(expUuid); - free(wsUuid); - - if (status != 0) { - return SPEXP_WRONGEXPERIMENT; - } } /* We've made all the validity checks... attach the database: */ @@ -296,17 +293,123 @@ ** @retval SPEXP_NOT_EXPDATABASE - pHandle is not an experiment database. ** @retval SPEXP_NOT_WORKSPACE - Something is attached there but it's not a workspace. ** @retval SPEXP_UNATTACHED - the sql to do the detach failed. + ** @retval SPEXP_NOMEM - out of memory for some operation. */ int spectcl_workspace_detach(spectcl_experiment pHandle, const char* attachPoint) { - char* attachType; - + const char* whereAttached = DEFAULT_ATTACH_POINT; + char table[1001]; /* Out */ + char* attachedDbType; + const char* pQuery = "DETACH DATABASE :dbname"; + sqlite3_stmt* statement; + int status; + /* Require pHandle to be an epxeriment database */ + if (!isExperimentDatabase(pHandle)) { return SPEXP_NOT_EXPDATABASE; } - attachType = getFirst( - return SPEXP_UNIMPLEMENTED; + /* Figure out the attached point and whether a workspace is attached there. */ + + + if (attachPoint) { + whereAttached = attachPoint; + } + status = spectcl_checkAttached(pHandle, whereAttached, "workspace", SPEXP_NOT_WORKSPACE); + if (status != SPEXP_OK) { + return status; + } + + + /* Do the detach */ + + return spectcl_detach(pHandle, whereAttached); + } +/** + ** Return the schema version of a workspace. + ** @param ws - Workspace handle from spectcl_workspace_open. + ** @return char* + ** @retval NULL - Failed in some way, error reason in spectcl_experiment_errno. + ** @retval other - Pointer to a dynamically allocated version string. + ** + ** Errors: + ** - SPEXP_NOT_WORKSPACE - ws is not a workspace. + ** - SPEXP_SQLFAIL - could not retrieve the version string in some way. + */ +char* +spectcl_workspace_version(spectcl_workspace ws) +{ + char* pResult; + + if (!isWorkspace(ws) ) { + spectcl_experiment_errno = SPEXP_NOT_WORKSPACE; + return NULL; + } + + pResult = getfirst(ws, "configuration_values", "config_value", "config_item", "version"); + if (!pResult) { + spectcl_experiment_errno = SPEXP_SQLFAIL; + } + return pResult; + +} +/** + ** Return the uuid of the workspace. + ** @param ws - Workspace handle. + ** @return uuid_t* (dynamically allocated). + ** @retval NULL - error of some sort. see below. + ** @retval not-null - Pointer to the parsed UUID of the workspace. + ** must be free'd to avoid memory leaks. + ** + ** Errors (in spectcl_experiment_errno if return is NULL): + ** SPEXP_NOT_WORKSPACE - ws is not a workspace. + ** SPEXP_SQLFAIL - Could not get the UUID from the database though it purports to be + ** a workspace. + */ +uuid_t* +spectcl_workspace_uuid(spectcl_workspace ws) +{ + uuid_t* uuid; + + if (!isWorkspace(ws)) { + spectcl_experiment_errno = SPEXP_NOT_WORKSPACE; + return NULL; + } + + uuid = getDBUUID(ws); + if (!uuid) { + spectcl_experiment_errno = SPEXP_SQLFAIL; + } + return uuid; +} +/** + ** Determines if a database handle is a workspace handle. + ** @param ws - Alleged workspace handle. + ** @return int + ** @retval TRUE - Handle is a workspace. + ** @retval FALSE - Handle is not a workspace. + */ +int +spectcl_workspace_isWorkspace(spectcl_workspace ws) +{ + return isWorkspace(ws) ? TRUE : FALSE; +} +/** + ** If both parameters are the proper type of database, returns + ** whether or not the workspace belongs to the experiment. + ** @param expdb - Experiment database. + ** @param ws - Worksapce database. + ** @return int + ** @retval TRUE expdb is an experiment, and ws is a workspace for that exeriment. + ** @retval FALSE (not any of the above). + */ +int +spectcl_workspace_isCorrectExperiment(spectcl_experiment expdb, spectcl_workspace ws) +{ + if (!isExperimentDatabase(expdb)) return FALSE; + if (!isWorkspace(ws)) return FALSE; + return spectcl_uuidCheck(expdb, ws); +} Modified: trunk/nextgen/primitives/spectcl_wsbasetest.c =================================================================== --- trunk/nextgen/primitives/spectcl_wsbasetest.c 2011-03-07 21:50:16 UTC (rev 1814) +++ trunk/nextgen/primitives/spectcl_wsbasetest.c 2011-03-08 20:42:01 UTC (rev 1815) @@ -35,9 +35,13 @@ static char dbName[PATH_MAX]; static char expName[PATH_MAX]; static char wsName[PATH_MAX]; +static char wsName1[PATH_MAX]; + spectcl_experiment db; +spectcl_experiment db1; +spectcl_workspace db_ws; +spectcl_workspace db1_ws; - /*------------------------------------- fixture code ----------------------------------*/ @@ -50,6 +54,23 @@ } + +static void setupws() +{ + setup(); + strcpy(wsName1, tmpnam(NULL)); + + db1 = spectcl_experiment_create(expName); + + spectcl_workspace_create(db, wsName); + db_ws = spectcl_workspace_open(wsName); + + spectcl_workspace_create(db1, wsName1); + db1_ws = spectcl_workspace_open(wsName1); + + +} + static void teardown() { spectcl_experiment_close(db); @@ -58,6 +79,17 @@ unlink(wsName); } +static void teardownws() +{ + spectcl_experiment_close(db1); + spectcl_workspace_close(db_ws); + spectcl_workspace_close(db1_ws); + unlink(wsName1); + + teardown(); + +} + /*------------------------------------ The tests ----------------------------------------------*/ /** Experiment database must be provided */ @@ -337,6 +369,7 @@ { int status; + spectcl_events pEv; spectcl_run_create(db, 1, "this is a test run", NULL); pEv = spectcl_events_create(db, 1, expName); @@ -350,6 +383,151 @@ } END_TEST +/** + ** Should be able to detach a workspace attached on the default + ** attach point + */ +START_TEST(test_detachdefault) +{ + + int status; + + spectcl_workspace_create(db, wsName); + spectcl_workspace_attach(db, wsName, NULL); + status = spectcl_workspace_detach(db, NULL); + fail_unless(status == SPEXP_OK); +} +END_TEST + + +/** + ** If we ask for the version of an experiment workspace, + ** we should not get it and spectcl_experiment_errno = SPEXP_NOT_WORKSPACE + */ +START_TEST(test_vsn_notws) +{ + char* vsn = spectcl_workspace_version(db); + fail_if(vsn != NULL); + fail_unless(spectcl_experiment_errno == SPEXP_NOT_WORKSPACE); +} +END_TEST +/** + ** Workspace versions should be SCHEMA_VERSION + */ +START_TEST(test_vsn_ok) +{ + char* vsn; + spectcl_workspace ws; + + spectcl_workspace_create(db, wsName); + + + ws = spectcl_workspace_open(wsName); + vsn = spectcl_workspace_version(ws); + spectcl_workspace_close(ws); + + fail_if(vsn == NULL); + fail_unless(strcmp(vsn, SCHEMA_VERSION) == 0); + free(vsn); + +} +END_TEST +/** + ** uuid but not a workspace should give me NULL and + ** errno of SPEXP_NOT_WORKSPACE. + */ +START_TEST(test_uuid_notws) +{ + uuid_t* uuid = spectcl_workspace_uuid(db); /* not a worksapce. */ + fail_if(uuid != NULL); + fail_unless(spectcl_experiment_errno == SPEXP_NOT_WORKSPACE); +} +END_TEST +/** + ** UUID should be the same as the one used to create the experiment. + */ +START_TEST(test_uuid_ok) +{ + uuid_t* wsUuid; + uuid_t* expUuid; + spectcl_workspace ws; + + spectcl_workspace_create(db, wsName); + ws = spectcl_workspace_open(wsName); + + wsUuid = spectcl_workspace_uuid(ws); + expUuid= spectcl_experiment_uuid(db); + spectcl_workspace_close(ws); + + fail_if(wsUuid == NULL); + if (wsUuid) { + fail_if(uuid_compare(*wsUuid, *expUuid)); + } + free(wsUuid); + free(expUuid); + + +} +END_TEST + +/* +** Passing an experiment handle into isWorkspace should give FALSE. +*/ +START_TEST(test_isws_no) +{ + fail_if(spectcl_workspace_isWorkspace(db)); +} +END_TEST +/** + ** Passing a workspace handle into isWorkspace should give TRUE + */ +START_TEST(test_isws_yes) +{ + spectcl_workspace ws; + + spectcl_workspace_create(db, wsName); + ws = spectcl_workspace_open(wsName); + fail_unless(spectcl_workspace_isWorkspace(ws)); + spectcl_workspace_close(ws); +} +END_TEST + +/** + * isCorrectExperiment will be false if the experiment is isn't one. + */ +START_TEST(test_iscorrectexp_notexp) +{ + fail_if(spectcl_workspace_isCorrectExperiment(db_ws, db_ws)); +} +END_TEST +/* + isCorrectExperiment sb. false if the workspace isn't wone. + */ +START_TEST(test_iscorrectexp_notws) +{ + fail_if(spectcl_workspace_isCorrectExperiment(db, db)); +} +END_TEST + +/* + isCorrectExperiment sb false if the workspace doesn't match the experiment +*/ +START_TEST(test_iscorrectexp_no) +{ + fail_if(spectcl_workspace_isCorrectExperiment(db, db1_ws)); + fail_if(spectcl_workspace_isCorrectExperiment(db1, db_ws)); +} +END_TEST +/* + isCorrectExperiment sb true if stuff matches: +*/ +START_TEST(test_iscorrectexp_yes) +{ + fail_unless(spectcl_workspace_isCorrectExperiment(db, db_ws)); + fail_unless(spectcl_workspace_isCorrectExperiment(db1, db1_ws)); +} +END_TEST + /*------------------------------------ final setup ---------------------------------------------*/ int main(void) { @@ -360,9 +538,11 @@ SRunner* sr = srunner_create(s); TCase* tc_base = tcase_create("base"); + TCase* tc_basews = tcase_create("basews"); /* tests that need a bit more setup. */ tcase_add_checked_fixture(tc_base, setup, teardown); + tcase_add_checked_fixture(tc_basews, setupws, teardownws); suite_add_tcase(s, tc_base); @@ -386,9 +566,25 @@ tcase_add_test(tc_base, test_detach_notexp); tcase_add_test(tc_base, test_detach_notws); + tcase_add_test(tc_base, test_detachdefault); - srunner_set_fork_status(sr, CK_NOFORK); + tcase_add_test(tc_base, test_vsn_notws); + tcase_add_test(tc_base, test_vsn_ok); + tcase_add_test(tc_base, test_uuid_notws); + tcase_add_test(tc_base, test_uuid_ok); + + tcase_add_test(tc_base, test_isws_no); + tcase_add_test(tc_base, test_isws_yes); + + tcase_add_test(tc_basews, test_iscorrectexp_notexp); + tcase_add_test(tc_basews, test_iscorrectexp_notws); + tcase_add_test(tc_basews, test_iscorrectexp_no); + tcase_add_test(tc_basews, test_iscorrectexp_yes); + + + /* srunner_set_fork_status(sr, CK_NOFORK); /* /* Uncomment for gdb */ + srunner_run_all(sr, CK_NORMAL); failures = srunner_ntests_failed(sr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |