
/** @file  tst_psMetadata_04.c
*
*  @brief Test driver for psMetadata functions
*
*  This test driver contains the following tests for psMetadata:
*     Test A - Allocate metadata and items
*     Test B - Lookup metadata item by name
*     Test C - Attempt to use null metadata
*     Test D - Attempt to use null key
*     Test E - Attempt to lookup non-existant metadata item
*     Test F - Lookup metadata item by index
*     Test G - Lookup metadata item and return psS32 value
*     Test H - Lookup metadata item and return psF64 value
*     Test I - Lookup metadata item and return psVector pointer
*     Test J - Attempt to use null metadata
*     Test K - Attempt to get non-existant metadata item
*     Test L - Attempt to look up with an invalid metadata object
*     Test M - Attempt get item  with an invalid metadata object
*     Test N - Attempt get value of non-existant metadata item
*     Test O - Free psMetadata
*
*  @author  Ross Harman, MHPCC
*
*  @version $Revision: 1.11 $  $Name: not supported by cvs2svn $
*  @date  $Date: 2005-01-13 21:19:31 $
*
*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
*
*/

#include "pslib.h"
#include "psTest.h"
#include <string.h>

static void printMetadataItem(psMetadataItem *metadataItem)
{
    printf("Key Name: %8s  ", metadataItem->name);
    printf("Key pType: %2d  ", metadataItem->pType);
    printf("Key mdType: %2d  ", metadataItem->type);

    switch (metadataItem->type) {
    case PS_META_LIST:
        printf("Key Value: %17c", ' ');
        break;
    case PS_META_PRIMITIVE:
        switch(metadataItem->pType) {
        case PS_TYPE_BOOL:
            printf("Key Value: %15d  ", metadataItem->data.B);
            break;
        case PS_TYPE_S32:
            printf("Key Value: %15d  ", metadataItem->data.S32);
            break;
        case PS_TYPE_F32:
            printf("Key Value: %15.3f  ", metadataItem->data.F32);
            break;
        case PS_TYPE_F64:
            printf("Key Value: %15.3f  ", metadataItem->data.F64);
            break;
        default:
            printf("Bad type: %d ", metadataItem->pType);
        }
        break;
    case PS_META_STR:
        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
        break;
    default:
        printf("Bad type: %d ", metadataItem->type);
    }
    printf("Key Comment: %s\n", metadataItem->comment);
}


psS32 main( psS32 argc, char* argv[] )
{
    psBool status = 0;
    psMetadataItem *item1 = NULL;
    psMetadataItem *item2 = NULL;
    psMetadataItem *item3 = NULL;
    psMetadataItem *item4 = NULL;
    psMetadataItem *item5 = NULL;
    psMetadataItem *item6 = NULL;
    psMetadataItem *item = NULL;
    psMetadata *metadata = NULL;
    psHash* tmpTable = NULL;
    psList* tmpList = NULL;


    // Test A - Allocate metadata and items
    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
    psVector *vec = psVectorAlloc(5, PS_TYPE_S32);
    metadata = psMetadataAlloc();
    item1 = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_F64, PS_META_PRIMITIVE, "I am a double", 3.14);
    item6 = psMetadataItemAlloc("myItem6", PS_TYPE_PTR, PS_META_VEC, "I am a vector", vec);
    printMetadataItem(item1);
    printMetadataItem(item2);
    printMetadataItem(item3);
    printMetadataItem(item4);
    printMetadataItem(item5);
    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
    psMetadataAddItem(metadata, item5, PS_LIST_HEAD);
    psMetadataAddItem(metadata, item6, PS_LIST_HEAD);
    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);


    // Test B - Lookup metadata item by name
    printPositiveTestHeader(stdout, "psMetadata", "Test B - Lookup metadata item by name");
    item = psMetadataLookup(metadata, "myItem2");
    printf("Found item named %s\n", item->name);
    if(item == NULL) {
        printf("ERROR: Item should not be null\n");
        return 10;
    }
    printFooter(stdout, "psMetadata", "Test B - Lookup metadata item by name", true);


    // Test C - Attempt to use null metadata
    printNegativeTestHeader(stdout,"psMetadata", "Test C - Attempt to use null metadata",
                            "Null metadata collection not allowed", 0);
    if ( psMetadataLookup(NULL, "myItem2") != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return NULL with null metadata.");
        return 11;
    }
    printFooter(stdout, "psMetadata", "Test C - Attempt to use null metadata", true);


    // Test D - Attempt to use null key
    printNegativeTestHeader(stdout,"psMetadata", "Test D - Attempt to use null key",
                            "Null key name not allowed", 0);
    if ( psMetadataLookup(metadata, NULL) != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadata did not return NULL with null key.");
        return 12;
    }
    printFooter(stdout, "psMetadata", "Test D - Attempt to use null key", true);


    // Test E - Attempt to lookup non-existant metadata item
    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to lookup non-existant metadata item",
                            "Couldn't find metadata item. Name: AARGH", 0);
    if ( psMetadataLookup(metadata, "AARGH") != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadata did not return NULL with a non-existant item.");
        return 13;
    }
    printFooter(stdout, "psMetadata", "Test E - Attempt to lookup non-existant metadata item", true);


    // Test F - Lookup metadata item by index
    printPositiveTestHeader(stdout, "psMetadata", "Test F - Lookup metadata item by index");
    item = psMetadataGet(metadata, 0);
    printf("Found item named %s\n", item->name);
    if(item == NULL) {
        printf("ERROR: Item should not be null\n");
        return 14;
    }
    printFooter(stdout, "psMetadata", "Test F - Lookup metadata item by index", true);

    // Test G - Lookup metadata item and return psS32 value
    printPositiveTestHeader(stdout, "psMetadata", "Test G - Lookup metadata item and return psS32 value");
    psS32 valueS32 = 0;
    valueS32 = psMetadataLookupS32(metadata, "myItem2", &status);
    if(valueS32 != 55) {
        printf("ERROR: Bad value, %d, Expected 55\n", valueS32);
        return 15;
    } else if(! status) {
        printf("ERROR: Bad status, %d\n", status);
        return 15;
    }
    printFooter(stdout, "psMetadata", "Test G - Lookup metadata item and return psS32 value", true);

    // Test H - Lookup metadata item and return psF64 value
    printPositiveTestHeader(stdout, "psMetadata", "Test H - Lookup metadata item and return psF64 value");
    psF64 valueF64 = 0.0;
    valueF64 = psMetadataLookupF64(metadata, "myItem5", &status);
    if(fabs(valueF64-3.14) > FLT_EPSILON) {
        printf("ERROR: Bad value, %g, Expected 3.14\n", valueF64);
        return 16;
    } else if(! status) {
        printf("ERROR: Bad status, %d\n", status);
        return 16;
    }
    printFooter(stdout, "psMetadata", "Test H - Lookup metadata item and return psF64 value", true);

    // Test I - Lookup metadata item and return psVector pointer
    printPositiveTestHeader(stdout, "psMetadata", "Test I - Lookup metadata item and return psVector pointer");
    psVector *valueVec = NULL;
    valueVec = psMetadataLookupPtr(metadata, "myItem6", &status);
    if(valueVec != vec) {
        printf("ERROR: Bad vector pointer\n");
        return 17;
    } else if(! status) {
        printf("ERROR: Bad status, %d\n", status);
        return 17;
    }
    printFooter(stdout, "psMetadata", "Test I - Lookup metadata item and return psVector pointer", true);


    // Test J - Attempt to use null metadata
    printNegativeTestHeader(stdout,"psMetadata", "Test J - Attempt to use null metadata",
                            "Null metadata collection not allowed", 0);
    item = psMetadataGet(NULL, 0);
    if ( item != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataGet did not return NULL with null metadata structure");
        return 18;
    }
    printFooter(stdout, "psMetadata", "Test J - Attempt to use null metadata", true);


    // Test K - Attempt to get non-existant metadata item
    printNegativeTestHeader(stdout,"psMetadata", "Test K - Attempt to get non-existant metadata item",
                            "Couldn't find metadata item with given index. Index: 22", 0);
    if ( psMetadataGet(metadata, 22) != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataGet did not return NULL with non-existant metadata item");
        return 19;
    }
    printFooter(stdout, "psMetadata", "Test K - Attempt to get non-existant metadata item", true);

    // Test L - Attempt to look up with an invalid metadata object
    printNegativeTestHeader(stdout,"psMetadata","Test L - Attemp to look up with an invalid metadata",
                            "Lookup item with invalid metadata object.", 0 );
    tmpTable = metadata->table;
    metadata->table = NULL;
    if ( psMetadataLookup(metadata,"myItem2") != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return null for invalid metadata object");
        return 20;
    }
    metadata->table = tmpTable;
    printFooter(stdout, "psMetadata","Test L - Attempt to lookup an invalid metadata object.",true);

    // Test M - Attempt get item with an invalid metadata object
    printNegativeTestHeader(stdout,"psMetadata","Test M - Attempt to get item with an invalid metadata",
                            "Get item with invalid metadata object.", 0 );
    tmpList = metadata->list;
    metadata->list = NULL;
    if ( psMetadataGet(metadata,0) != NULL ) {
        psError(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return null for invalid metadata object");
        return 21;
    }
    metadata->list = tmpList;
    printFooter(stdout, "psMetadata","Test M - Attempt to get item with  invalid metadata object",true);

    // Test N - Attempt get psS32 value of non-existant metadata item
    printPositiveTestHeader(stdout, "psMetadata", "Test N - Attempt get psS32 value of non-existant metadata item");
    valueS32 = psMetadataLookupS32(metadata, "myItem22", &status);
    if(status) {
        printf("ERROR: Bad status, %d, \n", status);
        return 22;
    }
    printFooter(stdout, "psMetadata","Test N - Attempt get psS32 value of non-existant metadata item",true);

    // Test O - Attempt get psF64 value of non-existant metadata item
    printPositiveTestHeader(stdout, "psMetadata", "Test O - Attempt get psF64 value of non-existant metadata item");
    valueF64 = psMetadataLookupF64(metadata, "myItem22", &status);
    if(status) {
        printf("ERROR: Bad status, %d, \n", status);
        return 23;
    }
    printFooter(stdout, "psMetadata","Test O - Attempt get psF64 value of non-existant metadata item",true);

    // Test P - Attempt get psVector value of non-existant metadata item
    printPositiveTestHeader(stdout, "psMetadata", "Test P - Attempt get psVector value of non-existant metadata item");
    valueVec = psMetadataLookupPtr(metadata, "myItem22", &status);
    if(status) {
        printf("ERROR: Bad status, %d, \n", status);
        return 24;
    }
    printFooter(stdout, "psMetadata","Test P - Attempt get psVector value of non-existant metadata item",true);

    // Test Q - Free psMetadata
    printPositiveTestHeader(stdout, "psMetadata", "Test Q - Free psMetadata");
    psFree(metadata);
    psFree(item1);
    psFree(item2);
    psFree(item3);
    psFree(item4);
    psFree(item5);
    psFree(item6);
    if ( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
        psError(PS_ERR_UNKNOWN, true,"memory leaks detected.");
        return 23;
    }
    psMemCheckCorruption(0);
    psS32 nBad = psMemCheckCorruption(0);
    if(nBad) {
        printf("ERROR: Found %d bad memory blocks\n", nBad);
        return 24;
    }
    printFooter(stdout, "psMetadata", "Test Q - Free psMetadata", true);


    return 0;
}
