//--------------------------------------------------------------------------- #pragma warn -com #include #pragma warn +com #include #pragma hdrstop #include "stdio.h" #include "io.h" #include "dir.h" #include "RunTests.h" #include "Utilities.h" #define MASSUDWriter "MASSUDWriter" #define ADV_PROGRESS_BAR //#define STORE_IN_DATABASE #define STORE_PAYLOAD #define INITIALISETXNSTRUCTURE //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "Grids_ts" #pragma link "TSDBGrid" #pragma link "TSGrid" #pragma link "AdvProgressBar" #pragma resource "*.dfm" TRunTestsForm *RunTestsForm; //--------------------------------------------------------------------------- /** * Process paint message. */ void ProcessPaintMessages( HWND Handle ) { MSG msg; while ( PeekMessage( &msg, Handle, WM_PAINT, WM_PAINT, PM_REMOVE ) ) { DispatchMessage( &msg ); } } //--------------------------------------------------------------------------- __fastcall TRunTestsForm::TRunTestsForm(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- /** * Get the collection of schemas and find our schema in that collection. */ const bool TRunTestsForm::findSchema( vector< AnsiString > & xmlSchemas, TXMLSchema & schema, const AnsiString & currentProject, const int & currentIteration ) { vector< string > schemas; if ( schema.GetSchemas( schemas ) ) { AnsiString theSchema; for ( vector< string >::iterator what = schemas.begin(); what != schemas.end(); ++what ) { theSchema = what->c_str(); if ( theSchema.Pos( MASSUDWriter ) == 1 ) { xmlSchemas.push_back( theSchema ); } } } string handle; for ( vector< AnsiString >::iterator where = xmlSchemas.begin(); where != xmlSchemas.end(); ++where ) { handle = where->c_str(); vector< string > schema_structures; string project; string majorversion; schema.GetAttributeProperty( handle, "project", project ); if ( currentProject.UpperCase() == AnsiString( project.c_str() ).UpperCase() ) { schema.GetAttributeProperty( handle, "majorversion", majorversion ); if ( currentIteration == atoi( majorversion.c_str() ) ) { return ( true ); } } } return ( false ); } //--------------------------------------------------------------------------- /** * Build the transaction map for faster lookup. */ void TRunTestsForm::buildTranactionMap( TXNIndexMap & transactions, const AnsiString & currentProject, const int & currentIteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sql_statement; sql_statement.sprintf( "SELECT " "NAME, " "UDTYPE, " "UDSUBTYPE " "FROM " "MASS_TXNS " "WHERE " "PROJECTCODE=\'%s\' AND " "ITERATION=%d ", currentProject.c_str(), currentIteration ); query->SQL->Text = sql_statement; query->Open(); unsigned short udtype = 0; unsigned short udsubtype = 0; unsigned int udindex = 0; while ( !query->Eof ) { udtype = query->FieldByName( "UDTYPE" )->AsInteger; udsubtype = query->FieldByName( "UDSUBTYPE" )->AsInteger; udindex = ( udtype << 16 ) + udsubtype; transactions.insert( TXNIndexPair( udindex, query->FieldByName( "NAME" )->AsString ) ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- /** * Substitute any macros with the appropriate value. */ AnsiString & TRunTestsForm::substituteMacro( AnsiString & value, const unsigned short & udType ) { if ( value == "@ACCOUNTTYPE" ) { int accountFormat = 0; switch ( udType ) { case 1: // Card accountFormat = 2; break; case 2: // Application accountFormat = 1; break; case 3: // Product accountFormat = 3; break; case 4: // Other accountFormat = 4; break; case 5: // Audit accountFormat = 4; break; case 6: // Event accountFormat = 4; break; case 7: // Project accountFormat = 4; break; } // switch value.sprintf( "%d", accountFormat ); } return ( value ); } //--------------------------------------------------------------------------- /** * Evaluate to true when the given value is a macro, and to false otherwise. */ const bool TRunTestsForm::isMacro( const string & value ) { return ( value == "@ACCOUNTTYPE" ); } //--------------------------------------------------------------------------- /** * Build the header that we use as the basis for prefixing each transaction * when prefixing is required. */ void TRunTestsForm::buildHeader( string & handle, TXMLSchema & schema, vector< pair< string, string > > & macros, const AnsiString & currentProject, const int & currentIteration ) { const char * headerStructure = "SysHdr_t"; TADOQuery * query = 0; try { try { if ( schema.Create( headerStructure, currentIteration, handle, 0 ) ) { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "* " "FROM " "TXNHDR_VALUES " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d ", currentProject.c_str(), currentIteration ); query->SQL->Text = sqlStatement; query->Open(); string fieldName; string fieldValue; string attributePath; string valuemap; while ( !query->Eof ) { fieldName = query->FieldByName( "FIELDNAME" )->AsString.c_str(); fieldValue = query->FieldByName( "FIELDVALUE" )->AsString.c_str(); if ( !isMacro( fieldValue ) ) { attributePath = handle + "." + fieldName; m_XMLSchema->GetAttributeProperty( attributePath, "valuemap", valuemap ); if ( valuemap.empty() ) { // string fieldDatatype; // schema.GetAttributeProperty( attributePath, "datatype", fieldDatatype ); if ( fieldValue[ 0 ] == '-' ) { schema.SetAttributeValue( handle, fieldName.c_str(), atoi( fieldValue.c_str() ) ); } else { schema.SetAttributeValue( handle, fieldName.c_str(), fieldValue.c_str()); } } else { if ( ( fieldValue[ 0 ] >= '0' && fieldValue[ 0 ] <= '9' ) || ( fieldValue[ 0 ] == '-' && fieldValue[ 1 ] >= '0' && fieldValue[ 1 ] <= '9' ) ) { schema.SetAttributeValue( handle, fieldName.c_str(), atoi( fieldValue.c_str() ) ); } else { schema.SetAttributeValue( handle, fieldName.c_str(), fieldValue.c_str()); } } } else { macros.push_back( std::pair< std::string, std::string >( fieldName, fieldValue ) ); } query->Next(); } query->Close(); } else { MessageDlg( "Failed to create header structure", mtError, TMsgDlgButtons() << mbOK, 0 ); MTHROW( std::runtime_error, \ "Cannot create \"" \ << headerStructure \ << "\", version " \ << currentIteration \ << '.' ); } } catch ( ... ) { if ( !handle.empty() ) { schema.Destroy( handle ); handle = ""; } throw; } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- /** * Replace the given macros. */ void TRunTestsForm::substituteMacros( string & handle, TXMLSchema & schema, const vector< pair< string, string > > & macros, const unsigned short & udType ) { AnsiString value; for ( vector< pair< string, string > >::const_iterator where = macros.begin(); where != macros.end(); ++where ) { schema.SetAttributeValue( handle, where->first.c_str(), substituteMacro( value = where->second.c_str(), udType ).c_str() ); } } //--------------------------------------------------------------------------- /** * Load transaction parameters. */ void TRunTestsForm::loadParameters( IterationParams & parameters, const int & testScenario, const int & transactionSpecification ) { TADOQuery * query = 0; try { AnsiString sql_statement; sql_statement.sprintf( "SELECT " "FIELDNAME, " "SUBSCRIPT, " "FIELDVALUE " "FROM " "TXNSPEC_VALUES " "WHERE " "TESTSCENARIO_NO=%d AND " "TXNSPEC_NO=%d AND " "( FIELDVALUE IS NOT NULL OR FIELDVALUE<>\'\')", testScenario, transactionSpecification ); query = new TADOQuery( 0 ); query->Connection = Data_Module->IntegrationDBConnection; query->SQL->Text = sql_statement; query->Open(); AnsiString field; while ( !query->Eof ) { if ( query->FieldByName( "SUBSCRIPT" )->AsInteger == 0 ) { field = query->FieldByName( "FIELDNAME" )->AsString; } else { field.sprintf( "%s.%d", query->FieldByName( "FIELDNAME" )->AsString.c_str(), query->FieldByName( "SUBSCRIPT" )->AsInteger ); } parameters.insert( IterationParamsPair( field.c_str(), query->FieldByName( "FIELDVALUE" )->AsString.c_str() ) ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- /** * Get the value of the key assigned last to the named table. */ const unsigned int getLastAssignedSk( TADOConnection * database, const char * tableName ) { unsigned int value = 0; AnsiString sqlQuery; TADOQuery * query = 0; try { query = new TADOQuery( 0 ); query->Connection = database; AnsiString sequenceName; sequenceName.sprintf( "%s_SK", tableName ); sqlQuery.sprintf( "SELECT FN_SEQ_CURRVAL( \'%s\' ) FROM DUAL", sequenceName ); query->SQL->Text = sqlQuery; query->Open(); value = query->Fields->Fields[ 0 ]->AsInteger; } __finally { query->Close(); delete query; } return value; } //--------------------------------------------------------------------------- /** * Create an instance of the given scenario, and evaluate to its key. */ void createScenario( TADOConnection * database, int & key, const unsigned int & testScenario ) { TADOQuery * query = 0; try { query = new TADOQuery( 0 ); query->Connection = database; AnsiString sqlQuery; sqlQuery.sprintf( "INSERT INTO GENERATED_SCENARIO( TEST_SCENARIO_FK ) VALUES ( %u )", testScenario ); query->SQL->Text = sqlQuery; query->ExecSQL(); key = getLastAssignedSk( database, "GENERATED_SCENARIO" ); } __finally { query->Close(); delete query; } } //--------------------------------------------------------------------------- /** * Create a batch for the given scenario instance, and evaluate to its key. */ void createBatch( TADOConnection * database, int & key, const unsigned int & number, const int & scenario ) { TADOQuery * query = 0; try { query = new TADOQuery( 0 ); query->Connection = database; AnsiString sqlQuery; sqlQuery.sprintf( "INSERT INTO GENERATED_BATCH( GENERATED_SCENARIO_FK, SEQUENCE_NUMBER ) VALUES ( %d, %u )", scenario, number ); query->SQL->Text = sqlQuery; query->ExecSQL(); key = getLastAssignedSk( database, "GENERATED_BATCH" ); } __finally { query->Close(); delete query; } } //--------------------------------------------------------------------------- /** * Create a transaction for the given batch and transaction specification, * and evaluate to its key. */ void createTransaction( TADOConnection * database, int & key, const int & batch, const int & transactionSpecification, TMemoryStream * payload ) { TADOQuery * query = 0; try { query = new TADOQuery( 0 ); query->Connection = database; /** * This is a strange way of going about inserting a row, but it * seems to be the only one that works with Oracle. */ query->SQL->Text = "SELECT * FROM GENERATED_TRANSACTION"; query->Open(); query->Append(); query->FieldByName( "GENERATED_BATCH_FK" )->AsInteger = batch; query->FieldByName( "TRANSACTION_SPECIFICATION_FK" )->AsInteger = transactionSpecification; TBlobField *blob = dynamic_cast< TBlobField * >( query->FieldByName( "PAYLOAD" ) ); if ( blob ) { blob->LoadFromStream( payload ); } query->Post(); key = getLastAssignedSk( database, "GENERATED_TRANSACTION" ); } __finally { query->Close(); delete query; } } //--------------------------------------------------------------------------- /** * Generate the given transaction. */ void TRunTestsForm::generateScenario( const unsigned int & testscenario_no, TXNIndexMap & mass_txns, const bool & isTds, string & headerHandle, TransactionSchedule & transactionSchedule, const vector< pair< string, string > > & macros, const unsigned int & repeatCount, const unsigned int & total, const int & batchSk ) { TMemoryStream * payload = 0; try { payload = new TMemoryStream(); bool txngen_error = false; #ifdef STORE_IN_DATABASE int transactionSk = 0; #endif for ( TransactionSchedule::iterator transaction = transactionSchedule.begin(); !txngen_error && transaction != transactionSchedule.end(); ++transaction ) { payload->Clear(); #if 1 // If this is a TDS then prefix with a SysHdr_t if ( isTds ) // TDS { substituteMacros( headerHandle, *m_XMLSchema, macros, transaction->second->getUdType() ); const string streamtype = "XDR"; const string stream_args; void * stream = 0; unsigned int stream_size = 0; if ( m_XMLSchema->Serialise( headerHandle, streamtype, stream_args, stream, stream_size, 0, 0, 0 ) ) { payload->Write( stream, stream_size ); } } #ifdef INITIALISETXNSTRUCTURE // Initialise our transaction artefact with its parameters if ( InitialiseTxnStructure( transaction->second->getHandle(), 0, transaction->second->getIterationParameters() ) ) #endif { // If we have initialised the Txn successfully then Serialise the outcome const string streamtype = "XDR"; const string stream_args; void * stream = 0; unsigned int stream_size = 0; if ( m_XMLSchema->Serialise( transaction->second->getHandle(), streamtype, stream_args, stream, stream_size, 0, 0, 0 ) ) { payload->Write( stream, stream_size ); #ifdef STORE_IN_DATABASE createTransaction( Data_Module->IntegrationDBConnection, transactionSk, batchSk, transaction->first, payload ); #endif } else { AnsiString msg; msg.sprintf( "Failed to serialise txn \'%s\' for \'%s\'", transaction->second->getName().c_str(), m_testcase.c_str() ); MessageDlg(msg, mtError, TMsgDlgButtons() << mbOK, 0); txngen_error = true; } } #ifdef INITIALISETXNSTRUCTURE else { txngen_error = true; } #endif #endif } // while } __finally { delete payload; payload = 0; } } //--------------------------------------------------------------------------- /** * Read the transaction schedule for the given test scenario. */ void TRunTestsForm::readTransactionSchedule( TADOConnection * database, TXMLSchema & schema, const int & currentIteration, TXNIndexMap & massTransactions, const int & testScenario, TransactionSchedule & transactionSchedule ) { TADOQuery * query = 0; try { query = new TADOQuery( 0 ); query->Connection = database; AnsiString sqlQuery; sqlQuery.sprintf( "SELECT " "TXNSPEC_NO, " "UDTYPE, " "UDSUBTYPE " "FROM " "TRANSACTION_SPECIFICATION " "WHERE " "TESTSCENARIO_NO=%d " "ORDER BY " "SEQ_NO", testScenario ); query->SQL->Text = sqlQuery; pair< TransactionSchedule::iterator, bool > where; int transactionSpecification = 0; unsigned short udType = 0; unsigned short udSubtype = 0; TransactionArtefact * transactionArtefact = 0; string handle; TXNIndexMap::iterator transaction; string structureName; for ( query->Open(); !query->Eof; query->Next() ) { transactionSpecification = query->FieldByName( "TXNSPEC_NO" )->AsInteger; udType = query->FieldByName( "UDTYPE" )->AsInteger; udSubtype = query->FieldByName( "UDSUBTYPE" )->AsInteger; // Resolve the UD type and subtype into a structure name. transaction = massTransactions.find( ( udType << 16 ) + udSubtype ); if ( transaction != massTransactions.end() ) { structureName = transaction->second.c_str(); where = transactionSchedule.insert( TransactionSchedule::value_type( transactionSpecification, 0 ) ); if ( where.second ) { try { transactionArtefact = new TransactionArtefact( schema, structureName, udType ); if ( schema.Create( "", structureName.c_str(), currentIteration, handle, 0 ) ) { where.first->second = transactionArtefact; transactionArtefact->setHandle( handle ); } else { MTHROW( std::runtime_error, \ "Cannot create structure \"" \ << structureName \ << "\" for iteration " \ << currentIteration \ << '.' ); } loadParameters( transactionArtefact->getIterationParameters(), testScenario, transactionSpecification ); } catch ( ... ) { delete transactionArtefact; transactionArtefact = 0; transactionSchedule.erase( where.first ); throw; } } else { MTHROW( std::runtime_error, \ "Cannot cache handle for structure \"" \ << structureName \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot find structure for UD type " \ << udType \ << ", subtype " \ << udSubtype \ << '.' ); } } } __finally { query->Close(); delete query; } } //--------------------------------------------------------------------------- /** * Generate the given test case. */ void TRunTestsForm::generateTestCase( void ) { #ifdef ADV_PROGRESS_BAR m_progressBar->Show(); m_progressBar->Position = 0; #else m_progressBarOld->Show(); m_progressBarOld->Position = 0; #endif const bool isTds = ( GenerationTargetComboBox->ItemIndex == 1 ); TransactionSchedule transactionSchedule; TADOQuery * query = 0; try { const bool foundSchema = findSchema( m_xml_schemas, *m_XMLSchema, m_currentproject, m_currentiteration ); // Did we find the Target XML Writer Schema ? if ( foundSchema ) { /** * When we need a header, then create the header that we'll * prepend to every transaction. Macros are evaluated later, * so we need to remember them until then. */ string headerHandle; vector< pair< string, string > > macros; if ( isTds ) { buildHeader( headerHandle, *m_XMLSchema, macros, m_currentproject, m_currentiteration ); } Data_Module->IntegrationDBConnection->BeginTrans(); AnsiString sql_statement; query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; // Build a MASS Txn Map for fast lookup TXNIndexMap mass_txns; buildTranactionMap( mass_txns, m_currentproject, m_currentiteration ); // Process ALL TestScenarios, in order, for this TestCase bool txngen_error = false; sql_statement=""; sql_statement.sprintf("select testscenario_no,testcase_seqno,name,repeat_count,batch_size " "from test_scenarios " "where project_code='%s' and iteration=%d " "and testcase_id='%s' " "order by testcase_seqno", m_currentproject.c_str(), m_currentiteration, m_testcase.c_str()); query->SQL->Text = sql_statement; /** * First, we traverse the result set to scope out the work that * we're about to embark upon. We use this as an indication of * progress. */ query->Open(); unsigned int total = 0; unsigned int count = 0; while ( !query->Eof ) { total += ( !query->FieldByName("REPEAT_COUNT")->IsNull ? query->FieldByName("REPEAT_COUNT")->AsInteger : 1 ); query->Next(); } query->Close(); /** * Now we traverse the result set to actually do the work. */ query->Open(); TDateTime beginning = TDateTime::CurrentDateTime(); TDateTime now = TDateTime::CurrentDateTime(); TDateTime update = TDateTime::CurrentDateTime(); const TDateTime step( 0, 0, 2, 500 ); double duration; double estimate; double scale = 0.0; AnsiString progress; #ifdef STORE_IN_DATABASE int scenarioSk = 0; #endif int batchSk = 0; int batchNumber = 0; unsigned int batchLength = 0; while ( !txngen_error && !query->Eof ) { const unsigned int testscenario_no = query->FieldByName( "TESTSCENARIO_NO" )->AsInteger; const unsigned int repeatCount = ( !query->FieldByName( "REPEAT_COUNT" )->IsNull ? query->FieldByName("REPEAT_COUNT")->AsInteger : 1 ); const unsigned int batchSize = ( !query->FieldByName( "BATCH_SIZE" )->IsNull ? query->FieldByName("batch_size")->AsInteger : 1 ); const AnsiString name = query->FieldByName("NAME")->AsString.c_str(); AnsiString testcase_desc; testcase_desc.sprintf("(%d) %s", query->FieldByName("TESTCASE_SEQNO")->AsInteger, name.c_str() ); readTransactionSchedule( Data_Module->IntegrationDBConnection, *m_XMLSchema, m_currentiteration, mass_txns, testscenario_no, transactionSchedule ); batchNumber = 1; batchLength = 0; #ifdef STORE_IN_DATABASE createScenario( Data_Module->IntegrationDBConnection, scenarioSk, testscenario_no ); createBatch( Data_Module->IntegrationDBConnection, batchSk, batchNumber, scenarioSk ); #endif // TTreeNode *testcase_node = TestCaseTxnTreeView->Items->AddObject(NULL, testcase_desc, (void *)testscenario_no); /** * Determine the set of Transaction Specifications for the ordered * set of test scenarios */ for ( unsigned int i=0; i= batchSize ) { ++batchNumber; batchLength = 1; #ifdef STORE_IN_DATABASE createBatch( Data_Module->IntegrationDBConnection, batchSk, batchNumber, scenarioSk ); #endif } else { ++batchLength; } generateScenario( testscenario_no, mass_txns, isTds, headerHandle, transactionSchedule, macros, repeatCount, total, batchSk ); ++count; now = TDateTime::CurrentDateTime(); if ( now - update >= step ) { scale = double( total ) / double( count ); duration = now - beginning; estimate = ( duration * scale ) - duration; StatusBar->Panels->Items[0]->Text = "Estimated Time Remaining: " + TDateTime( estimate ).FormatString( "tt" ); progress.sprintf( "Count: %d, avg: %f ms/t", count, ( duration / count ) * 24 * 60 * 60 * 1000 ); StatusBar->Panels->Items[1]->Text = progress; ProcessPaintMessages( StatusBar->Handle ); update = now; } #ifdef ADV_PROGRESS_BAR if ( m_progressBar->Position != int( count / double( total ) * 100.0 ) ) { m_progressBar->Position = int( count / double( total ) * 100.0 ); } #else m_progressBarOld->Position = count / double( total ) * 100.0; #endif } query->Next(); } // while StatusBar->Panels->Items[0]->Text = ""; StatusBar->Panels->Items[1]->Text = ""; if (!txngen_error) { Data_Module->IntegrationDBConnection->CommitTrans(); } } else { AnsiString msg; msg.sprintf("Failed to locate XML for %s (%s) Iteration: %d\nPlease verify XMLSchema.ini", MASSUDWriter, m_currentproject.c_str(), m_currentiteration ); MessageDlg(msg.c_str(), mtError, TMsgDlgButtons() << mbOK, 0); } } __finally { delete query; query = 0; if (Data_Module->IntegrationDBConnection->InTransaction) { Data_Module->IntegrationDBConnection->RollbackTrans(); } // Clear the transaction schedule. for ( TransactionSchedule::iterator where = transactionSchedule.begin(); where != transactionSchedule.end(); ++where ) { delete where->second; where->second = 0; } transactionSchedule.clear(); #ifdef ADV_PROGRESS_BAR m_progressBar->Hide(); #else m_progressBarOld->Hide(); #endif } } //--------------------------------------------------------------------------- void __fastcall TRunTestsForm::GenerateTransactionsClick(TObject *Sender) { const TCursor Save_Cursor = Screen->Cursor; Screen->Cursor = crHourGlass; try { TestCaseTxnTreeView->Items->Clear(); generateTestCase(); MWARNING( "TODO: rebuild tree view." ); } __finally { Screen->Cursor = Save_Cursor; } } //--------------------------------------------------------------------------- bool __fastcall TRunTestsForm::InitialiseTxnStructure(const string &structure_handle, int subscript, IterationParams &structure_params) { vector structure_attributes; vector::iterator s_itr; // AnsiString sql_statement; bool noerror = true; m_XMLSchema->GetAttributes(structure_handle, structure_attributes); s_itr = structure_attributes.begin(); while ( noerror && (s_itr != structure_attributes.end()) ) { string elementtype; string attr_handle = (*s_itr); m_XMLSchema->GetAttributeProperty(attr_handle, "type", elementtype); if (elementtype == "field") { string datatype; m_XMLSchema->GetAttributeProperty(attr_handle, "datatype", datatype); if (datatype == "Struct") { noerror = InitialiseTxnStructure(attr_handle, subscript, structure_params); } else { string fieldname; string tagvalue; string xpath; m_XMLSchema->GetAttributeProperty(attr_handle, "tag", tagvalue); if (tagvalue.length() > 0) { m_XMLSchema->GetAttributeProperty(attr_handle, "name", fieldname); AnsiString fieldid; if (subscript == 0) { fieldid = fieldname.c_str(); } else { fieldid.sprintf("%s.%d", fieldname.c_str(), subscript); } IterationParams::iterator f_itr = structure_params.find(fieldid.c_str()); if (f_itr != structure_params.end()) { string fieldvalue = (*f_itr).second; string valuemap; m_XMLSchema->GetAttributeProperty(attr_handle, "valuemap", valuemap); if (valuemap.empty()) { if (fieldvalue[0] == '-') { int int_value = atoi( fieldvalue.c_str() ); m_XMLSchema->SetAttributeValue(attr_handle, "", int_value); } else if (m_XMLSchema->SetAttributeValue(attr_handle, "", fieldvalue.c_str()) == false) { AnsiString msg; msg.sprintf("Failed to initialise attribute '%s' to (%s) DataType: %s\n" "Continue ?", fieldname.c_str(), fieldvalue.c_str(), datatype.c_str()); if (MessageDlg(msg, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrNo) { noerror = false; } } } else { if ( (fieldvalue[0] == '-') || (fieldvalue[0] >='0' && fieldvalue[0] <='9') ) { int int_value = atoi( fieldvalue.c_str() ); if (m_XMLSchema->SetAttributeValue(attr_handle, "", int_value) == false) { AnsiString msg; msg.sprintf("Failed to initialise attribute '%s' to (%s) DataType: %s\n" "Continue ?", fieldname.c_str(), fieldvalue.c_str(), datatype.c_str()); if (MessageDlg(msg, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrNo) { noerror = false; } } } else { if (m_XMLSchema->SetAttributeValue(attr_handle, "", fieldvalue.c_str()) == false) { AnsiString msg; msg.sprintf("Failed to initialise attribute '%s' to (%s) DataType: %s\n" "Continue ?", fieldname.c_str(), fieldvalue.c_str(), datatype.c_str()); if (MessageDlg(msg, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrNo) { noerror = false; } } } } } } } } else if (elementtype == "repeat") { string refcountfield; string maxOccursStr; string refcountAttribute; m_XMLSchema->GetAttributeProperty(attr_handle, "refcountfield", refcountfield); if (!refcountfield.empty()) { string refcountAttribute = structure_handle+"."+refcountfield; m_XMLSchema->GetAttributeProperty(refcountAttribute, "max", maxOccursStr); } if (maxOccursStr.empty()) { m_XMLSchema->GetAttributeProperty(attr_handle, "maxOccurs", maxOccursStr); } int maxOccurs = atoi(maxOccursStr.c_str()); // Limit to 100 elements if (maxOccurs > 100) { maxOccurs = 100; } string refcount_value; m_XMLSchema->GetAttributeValue(structure_handle, refcountfield, refcount_value); string repeat_name; m_XMLSchema->GetAttributeProperty(attr_handle, "name", repeat_name); if (!refcount_value.empty()) { maxOccurs = atoi(refcount_value.c_str()); } m_XMLSchema->SetAttributeValue(structure_handle, refcountfield, maxOccurs); for (int occurrence=1; occurrence<=maxOccurs; occurrence++) { string repeat_attribute_handle; AnsiString temp; temp.sprintf("%s.%d", attr_handle.c_str(), occurrence); repeat_attribute_handle = temp.c_str(); noerror = InitialiseTxnStructure(repeat_attribute_handle, occurrence, structure_params); } // for (int i=1; i<=occurrence; i++) } s_itr++; } // while return noerror; } //--------------------------------------------------------------------------- void TRunTestsForm::ShowForm(const AnsiString &testcase, const AnsiString &testname, const AnsiString &project, int currentiteration, const AnsiString &user_gen_dir, TXMLSchema *XMLSchema) { m_currentproject = project; m_currentiteration = currentiteration; m_XMLSchema = XMLSchema; m_testcase = testcase; m_user_gen_dir = user_gen_dir; TestCaseTitle->Caption = testname; ShowModal(); } //--------------------------------------------------------------------------- void __fastcall TRunTestsForm::TestCaseTxnTreeViewChange(TObject *Sender, TTreeNode *Node) { if (Node->Level == 1) { TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; int testscenario_no = (int)(Node->Parent->Data); int txnspec_no = (int)(Node->Data); AnsiString sql_statement; sql_statement.sprintf("SELECT PAYLOAD FROM TRANSACTION_SPECIFICATION " "WHERE TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d", testscenario_no, txnspec_no); query->SQL->Text = sql_statement; query->Open(); if (query->RecordCount == 1) { TStream* payload_stream = query->CreateBlobStream(query->FieldByName("PAYLOAD"), bmRead); unsigned int payload_size = payload_stream->Size; void* payload = malloc(payload_size); payload_stream->ReadBuffer(payload, payload_stream->Size); PayloadGrid->Rows = (payload_size+15)/16; unsigned char *p = (unsigned char *)payload; for (unsigned row=0; row<(payload_size+15)/16; row++) { for (unsigned col=0; col<16; col++) { AnsiString abyte; abyte.sprintf("%02X", *p); PayloadGrid->Cell[col+1][row+1] = abyte; p++; } } free(payload); } delete query; } // PayloadGrid } //--------------------------------------------------------------------------- void __fastcall TRunTestsForm::SaveTxnsToFileClick(TObject *Sender) { TCursor Save_Cursor = Screen->Cursor; Screen->Cursor = crHourGlass; // Show hourglass cursor try { AnsiString sql_statement; TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; TADOQuery *query2 = new TADOQuery(this); query2->Connection = Data_Module->IntegrationDBConnection; sql_statement=""; sql_statement.sprintf("SELECT TXNSTORAGE_PATH " "FROM ITERATIONS " "WHERE PROJECT_CODE='%s' " "AND ITERATION=%d ", m_currentproject.c_str(), m_currentiteration); query->SQL->Text = sql_statement; query->Open(); AnsiString txnstorage_path = query->FieldByName("TXNSTORAGE_PATH")->AsString; AnsiString target_path; if (!m_user_gen_dir.IsEmpty() && (txnstorage_path[2] != ':') ) { target_path = m_user_gen_dir; target_path += "\\"; target_path += txnstorage_path; } else { target_path = txnstorage_path; } if (access(target_path.c_str(), 0) == 0) { // Build a MASS Txn Map for fast lookup TXNIndexMap mass_txns; sql_statement=""; sql_statement.sprintf("SELECT NAME,UDTYPE,UDSUBTYPE " "FROM MASS_TXNS " "WHERE PROJECTCODE='%s' " "AND ITERATION=%d ", m_currentproject.c_str(), m_currentiteration); query->SQL->Text = sql_statement; query->Open(); while (!query->Eof) { unsigned short udtype = query->FieldByName("UDTYPE")->AsInteger; unsigned short udsubtype = query->FieldByName("UDSUBTYPE")->AsInteger; unsigned int udindex = (udtype << 16) + udsubtype; TXNIndexPair pair(udindex, query->FieldByName("NAME")->AsString); mass_txns.insert(pair); query->Next(); } sql_statement=""; sql_statement.sprintf("select testscenario_no,testcase_seqno,name " "from test_scenarios " "where project_code='%s' and iteration=%d " "and testcase_id='%s' " "order by testcase_seqno", m_currentproject.c_str(), m_currentiteration, m_testcase.c_str()); query->SQL->Text = sql_statement; query->Open(); while ( !query->Eof ) { unsigned int testscenario_no = query->FieldByName("TESTSCENARIO_NO")->AsInteger; // Determine the set of Transaction Specifications for the ordered // set of test scenarios sql_statement=""; sql_statement.sprintf("select txnspec_no,seq_no,udtype,udsubtype,payload " "from transaction_specification " "where testscenario_no=%d " "order by seq_no", testscenario_no); query2->SQL->Text = sql_statement; query2->Open(); while (!query2->Eof) { TBlobField *payload_field = dynamic_cast(query2->FieldByName("PAYLOAD")); if (!payload_field->IsNull) { AnsiString filename; unsigned short udtype = query2->FieldByName("UDTYPE")->AsInteger; unsigned short udsubtype = query2->FieldByName("UDSUBTYPE")->AsInteger; unsigned int udindex = (udtype << 16) + udsubtype; // Locate the MASS Txn based on UD Type and SubType TXNIndexMap::iterator txn_itr = mass_txns.find(udindex); if (txn_itr != mass_txns.end()) { string structure_name = (*txn_itr).second.c_str(); AnsiString target_directory; target_directory.sprintf("%s/%s", target_path.c_str(), m_testcase.c_str()); if (access(target_directory.c_str(), 0) != 0) { mkdir(target_directory.c_str()); } if (access(target_directory.c_str(), 0) == 0) { filename.sprintf("%s/%s/%s_%03d_%02d_%s.xdr", target_path.c_str(), m_testcase.c_str(), m_testcase.c_str(), query->FieldByName("TESTCASE_SEQNO")->AsInteger, query2->FieldByName("SEQ_NO")->AsInteger, structure_name.c_str() ); payload_field->SaveToFile(filename); } // Found Target Directory } // Found MASS Txn } // if (!payload_field->IsNull) query2->Next(); } query->Next(); } delete query; delete query2; AnsiString msg; msg.sprintf("Generated Transactions to: %s" , target_path.c_str()); MessageDlg(msg, mtInformation, TMsgDlgButtons() << mbOK, 0); } else { AnsiString msg; msg.sprintf("Directory '%s' Not Found or Not Accessible", target_path.c_str()); MessageDlg(msg, mtInformation, TMsgDlgButtons() << mbOK, 0); } } __finally { Screen->Cursor = Save_Cursor; } } //--------------------------------------------------------------------------- void __fastcall TRunTestsForm::FormCreate(TObject *Sender) { #ifdef ADV_PROGRESS_BAR m_progressBar = new TAdvProgressBar( StatusBar ); m_progressBar->Parent = StatusBar; m_progressBar->Steps = 10; m_progressBar->Position = 0; m_progressBar->ShowBorder = false; m_progressBar->ShowGradient = true; m_progressBar->ShowPercentage = true; m_progressBar->Stacked = false; m_progressBar->CompletionSmooth = false; m_progressBar->Visible = false; // m_progressBar->Level0Color = Graphics::TColor( 0x006AA676 ); // m_progressBar->Level0ColorTo = Graphics::TColor( 0x00BAE3C3 ); m_progressBar->Level0Color = Graphics::TColor( 0x00C961AD ); m_progressBar->Level0ColorTo = Graphics::TColor( 0x00FFBCEF ); m_progressBar->Level1Color = Graphics::TColor( 0x00C961AD ); m_progressBar->Level1ColorTo = Graphics::TColor( 0x00FFBCEF ); m_progressBar->Level2Color = Graphics::TColor( 0x00C961AD ); m_progressBar->Level2ColorTo = Graphics::TColor( 0x00FFBCEF ); m_progressBar->Level3Color = Graphics::TColor( 0x00C961AD ); m_progressBar->Level3ColorTo = Graphics::TColor( 0x00FFBCEF ); #else m_progressBarOld = new TProgressBar ( StatusBar ); m_progressBarOld->Parent = StatusBar; m_progressBarOld->Step = 10; m_progressBarOld->Max = 100; m_progressBarOld->Position = 0; m_progressBarOld->Visible = false; #endif } //--------------------------------------------------------------------------- void __fastcall TRunTestsForm::StatusBarResize(TObject *Sender) { RECT Rect; StatusBar->Perform( SB_GETRECT, 0, (LPARAM)&Rect ); const int progressPanel = 2; int offset = 0; for ( int i = 0; i < progressPanel; i++ ) { offset += StatusBar->Panels->Items[ i ]->Width; } #ifdef ADV_PROGRESS_BAR m_progressBar->Top = Rect.top + 2; m_progressBar->Left = Rect.left + offset + 4; m_progressBar->Width = StatusBar->Panels->Items[ progressPanel ]->Width - 6; m_progressBar->Height = Rect.bottom - Rect.top - 4; #else m_progressBarOld->Top = Rect.top; m_progressBarOld->Left = Rect.left + offset + 2; m_progressBarOld->Width = StatusBar->Panels->Items[ progressPanel ]->Width - 2; m_progressBarOld->Height = Rect.bottom - Rect.top; #endif } //---------------------------------------------------------------------------