コード例 #1
0
 protected function DoExecScenario($aSingleScenario)
 {
     echo "<div style=\"padding: 10;\">\n";
     echo "<h3 style=\"background-color: #ddddff; padding: 10;\">{$aSingleScenario['desc']}</h3>\n";
     $sClass = $aSingleScenario['target_class'];
     $aTargetData = $aSingleScenario['target_data'];
     $aSourceData = $aSingleScenario['source_data'];
     $aTargetAttributes = array_shift($aTargetData);
     $aSourceAttributes = array_shift($aSourceData);
     if (count($aSourceData) + 1 != count($aTargetData)) {
         throw new Exception("Target data must contain exactly " . (count($aSourceData) + 1) . " items, found " . count($aTargetData));
     }
     // Create the data source
     //
     $oDataSource = new SynchroDataSource();
     $oDataSource->Set('name', 'Test data sync ' . time());
     $oDataSource->Set('description', 'unit test - created automatically');
     $oDataSource->Set('status', 'production');
     $oDataSource->Set('user_id', 0);
     $oDataSource->Set('scope_class', $sClass);
     $oDataSource->Set('scope_restriction', '');
     $oDataSource->Set('full_load_periodicity', $aSingleScenario['full_load_periodicity']);
     $oDataSource->Set('reconciliation_policy', $aSingleScenario['reconciliation_policy']);
     $oDataSource->Set('action_on_zero', $aSingleScenario['action_on_zero']);
     $oDataSource->Set('action_on_one', $aSingleScenario['action_on_one']);
     $oDataSource->Set('action_on_multiple', $aSingleScenario['action_on_multiple']);
     $oDataSource->Set('delete_policy', $aSingleScenario['delete_policy']);
     $oDataSource->Set('delete_policy_update', $aSingleScenario['delete_policy_update']);
     $oDataSource->Set('delete_policy_retention', $aSingleScenario['delete_policy_retention']);
     $iDataSourceId = $this->ObjectToDB($oDataSource, true);
     $oAttributeSet = $oDataSource->Get('attribute_list');
     while ($oAttribute = $oAttributeSet->Fetch()) {
         if (array_key_exists($oAttribute->Get('attcode'), $aSingleScenario['attributes'])) {
             $aAttribInfo = $aSingleScenario['attributes'][$oAttribute->Get('attcode')];
             if (array_key_exists('reconciliation_attcode', $aAttribInfo)) {
                 $oAttribute->Set('reconciliation_attcode', $aAttribInfo['reconciliation_attcode']);
             }
             $oAttribute->Set('update', $aAttribInfo['do_update']);
             $oAttribute->Set('reconcile', $aAttribInfo['do_reconcile']);
         } else {
             $oAttribute->Set('update', false);
             $oAttribute->Set('reconcile', false);
         }
         $this->UpdateObjectInDB($oAttribute);
     }
     // Prepare list of prefixes -> make sure objects are unique with regard to the reconciliation scheme
     $aPrefixes = array();
     // attcode => prefix
     foreach ($aSourceAttributes as $iDummy => $sAttCode) {
         $aPrefixes[$sAttCode] = '';
         // init with something
     }
     foreach ($aSingleScenario['attributes'] as $sAttCode => $aAttribInfo) {
         if (isset($aAttribInfo['automatic_prefix']) && $aAttribInfo['automatic_prefix']) {
             $aPrefixes[$sAttCode] = 'TEST_' . $iDataSourceId . '_';
         }
     }
     // List existing objects (to be ignored in the analysis
     //
     $oAllObjects = new DBObjectSet(new DBObjectSearch($sClass));
     $aExisting = $oAllObjects->ToArray(true);
     $sExistingIds = implode(', ', array_keys($aExisting));
     // Create the initial object list
     //
     $aInitialTarget = $aTargetData[0];
     foreach ($aInitialTarget as $aObjFields) {
         $oNewTarget = MetaModel::NewObject($sClass);
         foreach ($aTargetAttributes as $iAtt => $sAttCode) {
             $oNewTarget->Set($sAttCode, $aPrefixes[$sAttCode] . $aObjFields[$iAtt]);
         }
         $this->ObjectToDB($oNewTarget);
     }
     foreach ($aTargetData as $iRow => $aExpectedObjects) {
         sleep(2);
         // Check the status (while ignoring existing objects)
         //
         if (empty($sExistingIds)) {
             $oObjects = new DBObjectSet(DBObjectSearch::FromOQL("SELECT {$sClass}"));
         } else {
             $oObjects = new DBObjectSet(DBObjectSearch::FromOQL("SELECT {$sClass} WHERE id NOT IN({$sExistingIds})"));
         }
         $aFound = $oObjects->ToArray();
         $aErrors_Unexpected = array();
         foreach ($aFound as $iObj => $oObj) {
             // Is this object in the expected objects list
             $bFoundMatch = false;
             foreach ($aExpectedObjects as $iExp => $aValues) {
                 $bDoesMatch = true;
                 foreach ($aTargetAttributes as $iCol => $sAttCode) {
                     if ($oObj->Get($sAttCode) != $aPrefixes[$sAttCode] . $aValues[$iCol]) {
                         $bDoesMatch = false;
                         break;
                     }
                 }
                 if ($bDoesMatch) {
                     $bFoundMatch = true;
                     unset($aExpectedObjects[$iExp]);
                     break;
                 }
             }
             if (!$bFoundMatch) {
                 $aErrors_Unexpected[] = $oObj->GetKey();
             }
         }
         // Display the current status
         //
         echo "<p>Status at step {$iRow}</p>\n";
         $aCurrentDataSet = array();
         foreach ($aFound as $iObj => $oObj) {
             $aObjDesc = array('Status' => in_array($iObj, $aErrors_Unexpected) ? 'unexpected' : 'ok', 'Object' => $oObj->GetHyperLink());
             foreach ($aTargetAttributes as $iCol => $sAttCode) {
                 $aObjDesc[$sAttCode] = $oObj->Get($sAttCode);
             }
             $aCurrentDataSet[] = $aObjDesc;
         }
         if (count($aExpectedObjects) > 0) {
             foreach ($aExpectedObjects as $iExp => $aValues) {
                 $aObjDesc = array('Status' => 'missing', 'Object' => 'n/a');
                 foreach ($aTargetAttributes as $iCol => $sAttCode) {
                     $aObjDesc[$sAttCode] = $aPrefixes[$sAttCode] . $aValues[$iCol];
                 }
                 $aCurrentDataSet[] = $aObjDesc;
             }
         }
         echo MyHelpers::make_table_from_assoc_array($aCurrentDataSet);
         if (count($aErrors_Unexpected) > 0 || count($aExpectedObjects) > 0) {
             throw new UnitTestException("The current status in iTop does not match the expectations");
         }
         // If not on the final row, run a data exchange sequence
         //
         if (array_key_exists($iRow, $aSourceData)) {
             $aToBeLoaded = $aSourceData[$iRow];
             $sCsvData = implode(';', $aSourceAttributes) . "\n";
             foreach ($aToBeLoaded as $aDataRow) {
                 $aFinalData = array();
                 foreach ($aDataRow as $iCol => $value) {
                     if (is_null($value)) {
                         $aFinalData[] = '<NULL>';
                     } else {
                         $sAttCode = $aSourceAttributes[$iCol];
                         $aFinalData[] = $aPrefixes[$sAttCode] . $value;
                     }
                 }
                 $sCsvData .= implode(';', $aFinalData) . "\n";
             }
             $aPostData = array('csvdata' => $sCsvData);
             $aImportArgs = array('data_source_id' => $iDataSourceId, 'separator' => ';', 'simulate' => 0, 'output' => 'details');
             $aGetParams = array();
             $aGetParamReport = array();
             foreach ($aImportArgs as $sArg => $sValue) {
                 $aGetParams[] = $sArg . '=' . urlencode($sValue);
                 $aGetParamReport[] = $sArg . '=' . $sValue;
             }
             $sGetParams = implode('&', $aGetParams);
             $sLogin = isset($aSingleScenario['login']) ? $aSingleScenario['login'] : '******';
             $sPassword = isset($aSingleScenario['password']) ? $aSingleScenario['password'] : '******';
             $sRes = self::DoPostRequestAuth('../synchro/synchro_import.php?' . $sGetParams, $aPostData, $sLogin, $sPassword);
             // Report the load results
             //
             if (strlen($sCsvData) > 5000) {
                 $sCsvDataViewable = 'INPUT TOO LONG TO BE DISPLAYED (' . strlen($sCsvData) . ")\n" . substr($sCsvData, 0, 500) . "\n... TO BE CONTINUED";
             } else {
                 $sCsvDataViewable = $sCsvData;
             }
             $sCsvDataViewable = htmlentities($sCsvDataViewable, ENT_QUOTES, 'UTF-8');
             echo "<div style=\"\">\n";
             echo "      <pre class=\"vardump\">{$sCsvDataViewable}</pre>\n";
             echo "</div>\n";
             echo "<pre class=\"vardump\" style=\"clear: both; padding: 15; background-color: black; color: green;\">{$sRes}</pre>\n";
             if (stripos($sRes, 'exception') !== false) {
                 throw new UnitTestException('Encountered an Exception during the last import/synchro');
             }
         }
     }
     return;
     echo "</div>\n";
 }