Browse Source

Added unit tests for the recording of linksets from one end (->Set('xxxxx_list')

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3748 a333f486-631f-4898-b8df-5754b55c2be0
romainq 9 years ago
parent
commit
20796bd8fc
1 changed files with 623 additions and 1 deletions
  1. 623 1
      test/testlist.inc.php

+ 623 - 1
test/testlist.inc.php

@@ -24,6 +24,43 @@
  */
 
 
+class TestBeHappy extends TestHandler // TestFunctionInOut, TestBizModel...
+{
+	static public function GetName()
+	{
+		return 'Be happy!';
+	}
+
+	static public function GetDescription()
+	{
+		return 'Sample test with success';
+	}
+
+	protected function DoExecute()
+	{
+		echo "<p>Am I happy?</p>";
+		echo "<p>Yes, I am!</p>";
+	}
+}
+class TestBeSad extends TestHandler
+{
+	static public function GetName()
+	{
+		return 'Be sad...';
+	}
+
+	static public function GetDescription()
+	{
+		return 'Sample test with failure';
+	}
+
+	protected function DoExecute()
+	{
+		echo "Am I happy?";
+		throw new Exception('jamais content');
+	}
+}
+
 class TestSQLQuery extends TestScenarioOnDB
 {
 	static public function GetName() {return 'SQLQuery';}
@@ -3560,4 +3597,589 @@ class TestEmailAsynchronous extends TestBizModel
 	}
 }
 
-?>
+class TestLinkSetRecording_NN_WithDuplicates extends TestBizModel
+{
+	static public function GetName()
+	{
+		return 'Linkset N-N having duplicated allowed (Connectable CI to Network Device)';
+	}
+
+	static public function GetDescription()
+	{
+		return 'Simulate CSV/data synchro type of recording. Check the values and the history. Lots of issues there: #1145, #1146 and #1147';
+	}
+
+	protected function DoExecute()
+	{
+		CMDBSource::Query('START TRANSACTION');
+		//CMDBSource::Query('ROLLBACK'); automatique !
+		
+		////////////////////////////////////////////////////////////////////////////////
+		// Set the stage
+		//
+		$oServer = MetaModel::NewObject('Server');
+		$oServer->Set('name', 'unit test linkset');
+		$oServer->Set('org_id', 3);
+		$oServer->DBInsert();
+		$iServer = $oServer->GetKey();
+		
+		$oTypes = new DBObjectSet(DBObjectSearch::FromOQL('SELECT NetworkDeviceType WHERE name = "Router"'));
+		$oType = $oTypes->fetch();
+		
+		$oDevice = MetaModel::NewObject('NetworkDevice');
+		$oDevice->Set('name', 'test device A');
+		$oDevice->Set('org_id', 3);
+		$oDevice->Set('networkdevicetype_id', $oType->GetKey());
+		$oDevice->DBInsert();
+		$iDev1 = $oDevice->GetKey();
+		
+		$oDevice = MetaModel::NewObject('NetworkDevice');
+		$oDevice->Set('name', 'test device B');
+		$oDevice->Set('org_id', 3);
+		$oDevice->Set('networkdevicetype_id', $oType->GetKey());
+		$oDevice->DBInsert();
+		$iDev2 = $oDevice->GetKey();
+		
+		
+		////////////////////////////////////////////////////////////////////////////////
+		// Scenarii
+		//
+		$aScenarii = array(
+			array(
+				'description' => 'Add the first item',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev1,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev1, test device A, unit test linkset, , , downlink, test device A",
+				),
+				'history_added' => 1,
+				'history_removed' => 0,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Modify the unique item',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev1,
+						'connectableci_id' => $iServer,
+						'network_port' => 'devTagada',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev1, test device A, unit test linkset, devTagada, , downlink, test device A",
+				),
+				'history_added' => 1,
+				'history_removed' => 1,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Modify again the original item and add a second item',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev1,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev1, test device A, unit test linkset, , , downlink, test device A",
+			 		"$iDev2, test device B, unit test linkset, , , downlink, test device B",
+				),
+				'history_added' => 2,
+				'history_removed' => 1,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'No change, the links are added in the reverse order',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+					array(
+						'networkdevice_id' => $iDev1,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev1, test device A, unit test linkset, , , downlink, test device A",
+			 		"$iDev2, test device B, unit test linkset, , , downlink, test device B",
+				),
+				'history_added' => 0,
+				'history_removed' => 0,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Removing A',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev2, test device B, unit test linkset, , , downlink, test device B",
+				),
+				'history_added' => 0,
+				'history_removed' => 1,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Adding B again (duplicate!)',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => 'port_123',
+						'device_port' => '',
+					),
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => 'port_456',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev2, test device B, unit test linkset, port_123, , downlink, test device B",
+			 		"$iDev2, test device B, unit test linkset, port_456, , downlink, test device B",
+				),
+				'history_added' => 2,
+				'history_removed' => 1,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Remove all',
+				'links' => array(
+				),
+				'expected-res' => array (
+				),
+				'history_added' => 0,
+				'history_removed' => 2,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Device B twice (same characteristics) - known issue #1145',
+				'links' => array(
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+					array(
+						'networkdevice_id' => $iDev2,
+						'connectableci_id' => $iServer,
+						'network_port' => '',
+						'device_port' => '',
+					),
+				),
+				'expected-res' => array (
+			 		"$iDev2, test device B, unit test linkset, portX, , downlink, test device B",
+			 		"$iDev2, test device B, unit test linkset, portX, , downlink, test device B",
+				),
+				'history_added' => 1,
+				'history_removed' => 0,
+				'history_modified' => 0,
+			),
+		);
+		
+		foreach ($aScenarii as $aScenario)
+		{
+			echo "<h4>".$aScenario['description']."</h4>\n";
+		
+			$oChange = MetaModel::NewObject("CMDBChange");
+			$oChange->Set("date", time());
+			$oChange->Set("userinfo", CMDBChange::GetCurrentUserName());
+			$oChange->Set("origin", 'custom-extension');
+			$oChange->DBInsert();
+			CMDBObject::SetCurrentChange($oChange);
+			$iChange = $oChange->GetKey();
+			
+			// Prepare set
+			$oLinkset = DBObjectSet::FromScratch('lnkConnectableCIToNetworkDevice');
+			foreach ($aScenario['links'] as $aLinkData)
+			{
+				$oLink1 = MetaModel::NewObject('lnkConnectableCIToNetworkDevice');
+				foreach ($aLinkData as $sAttCode => $value)
+				{
+					$oLink1->Set($sAttCode, $value);
+				}
+				$oLinkset->AddObject($oLink1);
+			}
+			
+			// Write
+			$oServer = MetaModel::GetObject('Server', $iServer);
+			$oServer->Set('networkdevice_list', $oLinkset);
+			$oServer->DBWrite();
+			
+			// Check Results
+			$bFoundIssue = false;
+			$oServer = MetaModel::GetObject('Server', $iServer);
+			$oLinkset = $oServer->Get('networkdevice_list');
+			
+			$aRes = $this->StandardizedDump($oLinkset, 'connectableci_id');
+			$sRes = var_export($aRes, true);
+			echo "Found: <pre>".$sRes."</pre>\n";
+		
+			$sExpectedRes = var_export($aScenario['expected-res'], true);
+			if ($sRes != $sExpectedRes)
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: <pre>".$sExpectedRes."</pre>\n";
+			}
+			
+			// Check History
+			$aQueryParams = array('change' => $iChange, 'objclass' => get_class($oServer), 'objkey' => $oServer->GetKey());
+			
+			$oAdded = new DBObjectSet(DBSearch::FromOQL("SELECT CMDBChangeOpSetAttributeLinksAddRemove WHERE objclass = :objclass AND objkey = :objkey AND change = :change AND type = 'added'"), array(), $aQueryParams);
+			echo "added: ".$oAdded->Count()."<br/>\n";
+			if ($aScenario['history_added'] != $oAdded->Count())
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: ".$aScenario['history_added']."<br/>\n";
+			}
+		
+			$oRemoved = new DBObjectSet(DBSearch::FromOQL("SELECT CMDBChangeOpSetAttributeLinksAddRemove WHERE objclass = :objclass AND objkey = :objkey AND change = :change AND type = 'removed'"), array(), $aQueryParams);
+			echo "removed: ".$oRemoved->Count()."<br/>\n";
+			if ($aScenario['history_removed'] != $oRemoved->Count())
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: ".$aScenario['history_removed']."<br/>\n";
+			}
+		
+			$oModified = new DBObjectSet(DBSearch::FromOQL("SELECT CMDBChangeOpSetAttributeLinksTune WHERE objclass = :objclass AND objkey = :objkey AND change = :change"), array(), $aQueryParams);
+			echo "modified: ".$oModified->Count()."<br/>\n";
+			if ($aScenario['history_modified'] != $oModified->Count())
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: ".$aScenario['history_modified']."<br/>\n";
+			}
+		
+			if ($bFoundIssue)
+			{
+				throw new Exception('Stopping on failed scenario');
+			}
+		}
+	}
+
+	protected function StandardizedDump($oSet, $sAttPrefixToIgnore)
+	{
+		if (!$oSet->m_bLoaded) $oSet->Load();
+		$oSet->Rewind();
+	
+		$aRet = array();
+		while($oObject = $oSet->Fetch())
+		{
+			$aValues = array();
+			foreach(MetaModel::ListAttributeDefs(get_class($oObject)) as $sAttCode => $oAttDef)
+			{
+				if ($sAttCode == 'friendlyname') continue;
+				if (substr($sAttCode, 0, strlen($sAttPrefixToIgnore)) == $sAttPrefixToIgnore) continue;
+				if ($oAttDef->IsScalar())
+				{
+					$aValues[] = $oObject->Get($sAttCode);
+				}
+			}
+			$aRet[] = implode(', ', $aValues);
+		}
+		sort($aRet);
+		return $aRet;
+	}
+}
+
+class TestLinkSetRecording_NN_NoDuplicates extends TestBizModel
+{
+	static public function GetName()
+	{
+		return 'Linksets N-N in general (99% of them)';
+	}
+
+	static public function GetDescription()
+	{
+		return 'Simulate CSV/data synchro type of recording. Check the values and the history.';
+	}
+
+	protected function DoExecute()
+	{
+		CMDBSource::Query('START TRANSACTION');
+		//CMDBSource::Query('ROLLBACK'); automatique !
+		
+		////////////////////////////////////////////////////////////////////////////////
+		// Set the stage
+		//
+		$oTeam = MetaModel::NewObject('Team');
+		$oTeam->Set('name', 'unit test linkset');
+		$oTeam->Set('org_id', 3);
+		$oTeam->DBInsert();
+		$iTeam = $oTeam->GetKey();
+		
+		$oPerson = MetaModel::NewObject('Person');
+		$oPerson->Set('name', 'test person A');
+		$oPerson->Set('first_name', 'totoche');
+		$oPerson->Set('org_id', 3);
+		$oPerson->DBInsert();
+		$iPerson1 = $oPerson->GetKey();
+		
+		$oPerson = MetaModel::NewObject('Person');
+		$oPerson->Set('name', 'test Person B');
+		$oPerson->Set('first_name', 'totoche');
+		$oPerson->Set('org_id', 3);
+		$oPerson->DBInsert();
+		$iPerson2 = $oPerson->GetKey();
+		
+		$oTypes = new DBObjectSet(DBSearch::FromOQL('SELECT ContactType WHERE name="Manager"'));
+		$iRole = $oTypes->Fetch();
+
+		////////////////////////////////////////////////////////////////////////////////
+		// Scenarii
+		//
+		$aScenarii = array(
+			array(
+				'description' => 'Add the first item',
+				'links' => array(
+					array(
+						'person_id' => $iPerson1,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+				),
+				'expected-res' => array (
+			 		"unit test linkset, $iPerson1, test person A, 0, , totoche test person A, ",
+				),
+				'history_added' => 1,
+				'history_removed' => 0,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Modify the unique item',
+				'links' => array(
+					array(
+						'person_id' => $iPerson1,
+						'team_id' => $iTeam,
+						'role_id' => $iRole,
+					),
+				),
+				'expected-res' => array (
+			 		"unit test linkset, $iPerson1, test person A, $iRole, Manager, totoche test person A, ",
+				),
+				'history_added' => 0,
+				'history_removed' => 0,
+				'history_modified' => 1,
+			),
+			array(
+				'description' => 'Modify again the original item and add a second item',
+				'links' => array(
+					array(
+						'person_id' => $iPerson1,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+					array(
+						'person_id' => $iPerson2,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+				),
+				'expected-res' => array (
+			 		"unit test linkset, $iPerson1, test person A, 0, , totoche test person A, ",
+			 		"unit test linkset, $iPerson2, test person A, 0, , totoche test person A, ",
+				),
+				'history_added' => 1,
+				'history_removed' => 0,
+				'history_modified' => 1,
+			),
+			array(
+				'description' => 'No change, the links are added in the reverse order',
+				'links' => array(
+					array(
+						'person_id' => $iPerson2,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+					array(
+						'person_id' => $iPerson1,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+				),
+				'expected-res' => array (
+			 		"unit test linkset, $iPerson1, test person A, 0, , totoche test person A, ",
+			 		"unit test linkset, $iPerson2, test person A, 0, , totoche test person A, ",
+				),
+				'history_added' => 0,
+				'history_removed' => 0,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Removing A',
+				'links' => array(
+					array(
+						'person_id' => $iPerson2,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+				),
+				'expected-res' => array (
+			 		"unit test linkset, $iPerson2, test person A, 0, , totoche test person A, ",
+				),
+				'history_added' => 0,
+				'history_removed' => 1,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Adding B again (duplicate!)',
+				'links' => array(
+					array(
+						'person_id' => $iPerson2,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+					array(
+						'person_id' => $iPerson2,
+						'team_id' => $iTeam,
+						'role_id' => 0,
+					),
+				),
+				'expected-res' => array (
+			 		"unit test linkset, $iPerson2, test person A, 0, , totoche test person A, ",
+				),
+				'history_added' => 0,
+				'history_removed' => 0,
+				'history_modified' => 0,
+			),
+			array(
+				'description' => 'Remove all',
+				'links' => array(
+				),
+				'expected-res' => array (
+				),
+				'history_added' => 0,
+				'history_removed' => 1,
+				'history_modified' => 0,
+			),
+		);
+		
+		foreach ($aScenarii as $aScenario)
+		{
+			echo "<h4>".$aScenario['description']."</h4>\n";
+		
+			$oChange = MetaModel::NewObject("CMDBChange");
+			$oChange->Set("date", time());
+			$oChange->Set("userinfo", CMDBChange::GetCurrentUserName());
+			$oChange->Set("origin", 'custom-extension');
+			$oChange->DBInsert();
+			CMDBObject::SetCurrentChange($oChange);
+			$iChange = $oChange->GetKey();
+			
+			// Prepare set
+			$oLinkset = DBObjectSet::FromScratch('lnkPersonToTeam');
+			foreach ($aScenario['links'] as $aLinkData)
+			{
+				$oLink1 = MetaModel::NewObject('lnkPersonToTeam');
+				foreach ($aLinkData as $sAttCode => $value)
+				{
+					$oLink1->Set($sAttCode, $value);
+				}
+				$oLinkset->AddObject($oLink1);
+			}
+			
+			// Write
+			$oTeam = MetaModel::GetObject('Team', $iTeam);
+			$oTeam->Set('persons_list', $oLinkset);
+			$oTeam->DBWrite();
+			
+			// Check Results
+			$bFoundIssue = false;
+			$oTeam = MetaModel::GetObject('Team', $iTeam);
+			$oLinkset = $oTeam->Get('persons_list');
+			
+			$aRes = $this->StandardizedDump($oLinkset, 'team_id');
+			$sRes = var_export($aRes, true);
+			echo "Found: <pre>".$sRes."</pre>\n";
+		
+			$sExpectedRes = var_export($aScenario['expected-res'], true);
+			if ($sRes != $sExpectedRes)
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: <pre>".$sExpectedRes."</pre>\n";
+			}
+			
+			// Check History
+			$aQueryParams = array('change' => $iChange, 'objclass' => get_class($oTeam), 'objkey' => $oTeam->GetKey());
+			
+			$oAdded = new DBObjectSet(DBSearch::FromOQL("SELECT CMDBChangeOpSetAttributeLinksAddRemove WHERE objclass = :objclass AND objkey = :objkey AND change = :change AND type = 'added'"), array(), $aQueryParams);
+			echo "added: ".$oAdded->Count()."<br/>\n";
+			if ($aScenario['history_added'] != $oAdded->Count())
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: ".$aScenario['history_added']."<br/>\n";
+			}
+		
+			$oRemoved = new DBObjectSet(DBSearch::FromOQL("SELECT CMDBChangeOpSetAttributeLinksAddRemove WHERE objclass = :objclass AND objkey = :objkey AND change = :change AND type = 'removed'"), array(), $aQueryParams);
+			echo "removed: ".$oRemoved->Count()."<br/>\n";
+			if ($aScenario['history_removed'] != $oRemoved->Count())
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: ".$aScenario['history_removed']."<br/>\n";
+			}
+		
+			$oModified = new DBObjectSet(DBSearch::FromOQL("SELECT CMDBChangeOpSetAttributeLinksTune WHERE objclass = :objclass AND objkey = :objkey AND change = :change"), array(), $aQueryParams);
+			echo "modified: ".$oModified->Count()."<br/>\n";
+			if ($aScenario['history_modified'] != $oModified->Count())
+			{
+				$bFoundIssue = true;
+				echo "NOT COMPLIANT!!! Expecting: ".$aScenario['history_modified']."<br/>\n";
+			}
+		
+			if ($bFoundIssue)
+			{
+				throw new Exception('Stopping on failed scenario');
+			}
+		}
+	}
+
+	protected function StandardizedDump($oSet, $sAttPrefixToIgnore)
+	{
+		if (!$oSet->m_bLoaded) $oSet->Load();
+		$oSet->Rewind();
+	
+		$aRet = array();
+		while($oObject = $oSet->Fetch())
+		{
+			$aValues = array();
+			foreach(MetaModel::ListAttributeDefs(get_class($oObject)) as $sAttCode => $oAttDef)
+			{
+				if ($sAttCode == 'friendlyname') continue;
+				if (substr($sAttCode, 0, strlen($sAttPrefixToIgnore)) == $sAttPrefixToIgnore) continue;
+				if ($oAttDef->IsScalar())
+				{
+					$aValues[] = $oObject->Get($sAttCode);
+				}
+			}
+			$aRet[] = implode(', ', $aValues);
+		}
+		sort($aRet);
+		return $aRet;
+	}
+}