PageRenderTime 117ms CodeModel.GetById 15ms RepoModel.GetById 3ms app.codeStats 0ms

/tests/functional/WindowsAzure/Table/TableServiceFunctionalTestUtils.php

http://github.com/WindowsAzure/azure-sdk-for-php
PHP | 497 lines | 432 code | 36 blank | 29 comment | 204 complexity | cf6db512e9498e1a859eb4687acd536e MD5 | raw file
  1. <?php
  2. /**
  3. * LICENSE: Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. *
  14. * PHP version 5
  15. *
  16. * @category Microsoft
  17. * @package Tests\Functional\WindowsAzure\Table
  18. * @author Azure PHP SDK <azurephpsdk@microsoft.com>
  19. * @copyright 2012 Microsoft Corporation
  20. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
  21. * @link https://github.com/windowsazure/azure-sdk-for-php
  22. */
  23. namespace Tests\Functional\WindowsAzure\Table;
  24. use WindowsAzure\Common\Internal\Utilities;
  25. use WindowsAzure\Common\ServiceException;
  26. use WindowsAzure\Table\TableService;
  27. use WindowsAzure\Table\Models\DeleteEntityOptions;
  28. use WindowsAzure\Table\Models\EdmType;
  29. use WindowsAzure\Table\Models\Entity;
  30. use WindowsAzure\Table\Models\InsertEntityResult;
  31. use WindowsAzure\Table\Models\Property;
  32. use WindowsAzure\Table\Models\Query;
  33. use WindowsAzure\Table\Models\QueryEntitiesOptions;
  34. use WindowsAzure\Table\Models\QueryEntitiesResult;
  35. use WindowsAzure\Table\Models\QueryTableResults;
  36. use WindowsAzure\Table\Models\QueryTablesOptions;
  37. use WindowsAzure\Table\Models\TableServiceOptions;
  38. use WindowsAzure\Table\Models\UpdateEntityResult;
  39. use WindowsAzure\Table\Models\Filters\BinaryFilter;
  40. use WindowsAzure\Table\Models\Filters\ConstantFilter;
  41. use WindowsAzure\Table\Models\Filters\Filter;
  42. use WindowsAzure\Table\Models\Filters\PropertyNameFilter;
  43. use WindowsAzure\Table\Models\Filters\QueryStringFilter;
  44. use WindowsAzure\Table\Models\Filters\UnaryFilter;
  45. class MutatePivot {
  46. const ChangeValues = 'ChangeValues';
  47. const AddProperty = 'AddProperty';
  48. const RemoveProperty = 'RemoveProperty';
  49. const NullProperty = 'NullProperty';
  50. public static function values() {
  51. return array('ChangeValues', 'AddProperty', 'RemoveProperty', 'NullProperty');
  52. }
  53. }
  54. class TableServiceFunctionalTestUtils {
  55. static function isEqNotInTopLevel($filter) {
  56. return self::isEqNotInTopLevelWorker($filter, 0);
  57. }
  58. private static function isEqNotInTopLevelWorker($filter, $depth) {
  59. if (is_null($filter)) {
  60. return false;
  61. }
  62. else if ($filter instanceof UnaryFilter) {
  63. return self::isEqNotInTopLevelWorker($filter->getOperand(), $depth + 1);
  64. }
  65. else if ($filter instanceof BinaryFilter) {
  66. $binaryFilter = $filter;
  67. if ($binaryFilter->getOperator() == ('eq') && $depth != 0) {
  68. return true;
  69. }
  70. $left = self::isEqNotInTopLevelWorker($binaryFilter->getLeft(), $depth + 1);
  71. $right = self::isEqNotInTopLevelWorker($binaryFilter->getRight(), $depth + 1);
  72. return $left || $right;
  73. }
  74. else {
  75. return false;
  76. }
  77. }
  78. static function cloneRemoveEqNotInTopLevel($filter) {
  79. return self::cloneRemoveEqNotInTopLevelWorker($filter, 0);
  80. }
  81. private static function cloneRemoveEqNotInTopLevelWorker($filter, $depth) {
  82. if ($filter instanceof PropertyNameFilter) {
  83. $ret = new PropertyNameFilter($filter->getPropertyName());
  84. return $ret;
  85. }
  86. else if ($filter instanceof ConstantFilter) {
  87. $ret = new ConstantFilter($filter->getEdmType(), $filter->getValue());
  88. return $ret;
  89. }
  90. else if ($filter instanceof UnaryFilter) {
  91. $operand = self::cloneRemoveEqNotInTopLevelWorker($filter->getOperand(), $depth + 1);
  92. $ret = new UnaryFilter($filter->getOperator(), $operand);
  93. return $ret;
  94. }
  95. else if ($filter instanceof BinaryFilter) {
  96. if ($filter->getOperator() == ('eq') && $depth != 0) {
  97. return Filter::applyConstant(false);
  98. }
  99. $left = self::cloneRemoveEqNotInTopLevelWorker($filter->getLeft(), $depth + 1);
  100. $right = self::cloneRemoveEqNotInTopLevelWorker($filter->getRight(), $depth + 1);
  101. $ret = new BinaryFilter($left, $filter->getOperator(), $right);
  102. return $ret;
  103. }
  104. else if ($filter instanceof QueryStringFilter) {
  105. $ret = new QueryStringFilter($filter->getQueryString());
  106. return $ret;
  107. }
  108. else {
  109. var_dump($filter);
  110. throw new \Exception();
  111. }
  112. }
  113. public static function filterList($filter, $input) {
  114. $output = array();
  115. foreach($input as $i) {
  116. if (self::filterInterperter($filter, $i)) {
  117. array_push($output, $i);
  118. }
  119. }
  120. return $output;
  121. }
  122. public static function filterEntityList($filter, $input) {
  123. $output = array();
  124. foreach($input as $i) {
  125. try {
  126. $result = self::filterInterperter($filter, $i);
  127. if (!is_null($result) && $result) {
  128. array_push($output, $i);
  129. }
  130. }
  131. catch (NoSuchFieldException $e) {
  132. $e->printStackTrace();
  133. // That is OK, bacuse the types are just bags.
  134. }
  135. catch (Exception $e) {
  136. $e->printStackTrace();
  137. }
  138. }
  139. return $output;
  140. }
  141. static function cloneEntity($initialEnt) {
  142. $ret = new Entity();
  143. $initialProps = $initialEnt->getProperties();
  144. $retProps = array();
  145. foreach($initialProps as $propName => $initialProp) {
  146. // Don't mess with the timestamp.
  147. if ($propName == ('Timestamp')) {
  148. continue;
  149. }
  150. $retProp = new Property();
  151. $retProp->setEdmType($initialProp->getEdmType());
  152. $retProp->setValue($initialProp->getValue());
  153. $retProps[$propName] = $retProp;
  154. }
  155. $ret->setProperties($retProps);
  156. $ret->setEtag($initialEnt->getEtag());
  157. return $ret;
  158. }
  159. static function mutateEntity($ent, $pivot) {
  160. if ($pivot == MutatePivot::ChangeValues) {
  161. self::mutateEntityChangeValues($ent);
  162. }
  163. else if ($pivot == MutatePivot::AddProperty) {
  164. $ent->addProperty('BOOLEAN' . TableServiceFunctionalTestData::getNewKey(), EdmType::BOOLEAN, true);
  165. $ent->addProperty('DATETIME' . TableServiceFunctionalTestData::getNewKey(), EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000473Z'));
  166. $ent->addProperty('DOUBLE' . TableServiceFunctionalTestData::getNewKey(), EdmType::DOUBLE, 12345678901);
  167. $ent->addProperty('GUID' . TableServiceFunctionalTestData::getNewKey(), EdmType::GUID, '90ab64d6-d3f8-49ec-b837-b8b5b6367b74');
  168. $ent->addProperty('INT32' . TableServiceFunctionalTestData::getNewKey(), EdmType::INT32, 23);
  169. $ent->addProperty('INT64' . TableServiceFunctionalTestData::getNewKey(), EdmType::INT64, '-1');
  170. $ent->addProperty('STRING' . TableServiceFunctionalTestData::getNewKey(), EdmType::STRING, 'this is a test!');
  171. }
  172. else if ($pivot == MutatePivot::RemoveProperty) {
  173. $propToRemove = null;
  174. foreach($ent->getProperties() as $propName => $propValue) {
  175. // Don't mess with the keys.
  176. if ($propName == ('PartitionKey') || $propName == ('RowKey') || $propName == ('Timestamp')) {
  177. continue;
  178. }
  179. $propToRemove = $propName;
  180. break;
  181. }
  182. $props = $ent->getProperties();
  183. unset($props[$propToRemove]);
  184. }
  185. else if ($pivot == MutatePivot::NullProperty) {
  186. foreach($ent->getProperties() as $propName => $propValue) {
  187. // Don't mess with the keys.
  188. if ($propName == ('PartitionKey') || $propName == ('RowKey') || $propName == ('Timestamp')) {
  189. continue;
  190. }
  191. $propValue->setValue(null);
  192. }
  193. }
  194. }
  195. private static function mutateEntityChangeValues($ent) {
  196. foreach($ent->getProperties() as $propName => $initialProp) {
  197. // Don't mess with the keys.
  198. if ($propName == ('PartitionKey') || $propName == ('RowKey') || $propName == ('Timestamp')) {
  199. continue;
  200. }
  201. $ptype = $initialProp->getEdmType();
  202. if (is_null($ptype)) {
  203. $eff = $initialProp->getValue();
  204. $initialProp->setValue($eff . 'AndMore');
  205. }
  206. else if ($ptype == (EdmType::DATETIME)) {
  207. $value = $initialProp->getValue();
  208. if (is_null($value)) {
  209. $value = new \DateTime("1/26/1692");
  210. }
  211. $value->modify('+1 day');
  212. $initialProp->setValue($value);
  213. }
  214. else if ($ptype == (EdmType::BINARY)) {
  215. $eff = $initialProp->getValue();
  216. $initialProp->setValue($eff . 'x');
  217. }
  218. else if ($ptype == (EdmType::BOOLEAN)) {
  219. $eff = $initialProp->getValue();
  220. $initialProp->setValue(!$eff);
  221. }
  222. else if ($ptype == (EdmType::DOUBLE)) {
  223. $eff = $initialProp->getValue();
  224. $initialProp->setValue($eff + 1);
  225. }
  226. else if ($ptype == (EdmType::GUID)) {
  227. $initialProp->setValue(com_create_guid());
  228. }
  229. else if ($ptype == (EdmType::INT32)) {
  230. $eff = $initialProp->getValue();
  231. $eff = ($eff > 10 ? 0 : $eff + 1);
  232. $initialProp->setValue($eff);
  233. }
  234. else if ($ptype == (EdmType::INT64)) {
  235. $eff = $initialProp->getValue();
  236. $eff = ($eff > 10 ? 0 : $eff + 1);
  237. $initialProp->setValue(strval($eff));
  238. }
  239. else if ($ptype == (EdmType::STRING)) {
  240. $eff = $initialProp->getValue();
  241. $initialProp->setValue($eff . 'AndMore');
  242. }
  243. }
  244. }
  245. public static function filterToString($filter, $pad = ' ') {
  246. if (is_null($filter)) {
  247. return $pad . 'filter <null>' . "\n";
  248. }
  249. else if ($filter instanceof PropertyNameFilter) {
  250. return $pad . 'entity.' . $filter->getPropertyName() . "\n";
  251. }
  252. else if ($filter instanceof ConstantFilter) {
  253. $ret = $pad;
  254. if (is_null($filter->getValue())) {
  255. $ret .= 'constant <null>';
  256. } else if (is_bool ($filter->getValue())) {
  257. $ret .= ($filter->getValue() ? 'true' : 'false');
  258. } else {
  259. $ret .= '\'' . FunctionalTestBase::tmptostring($filter->getValue()) . '\'';
  260. }
  261. return $ret . "\n";
  262. }
  263. else if ($filter instanceof UnaryFilter) {
  264. $ret = $pad . $filter->getOperator() . "\n";
  265. $ret .= self::filterToString($filter->getOperand(), $pad . ' ');
  266. return $ret;
  267. }
  268. else if ($filter instanceof BinaryFilter) {
  269. $ret = self::filterToString($filter->getLeft(), $pad . ' ');
  270. $ret .= $pad . $filter->getOperator() . "\n";
  271. $ret .= self::filterToString($filter->getRight(), $pad . ' ');
  272. return $ret;
  273. }
  274. }
  275. private static function filterInterperter($filter, $obj) {
  276. if (is_null($filter)) {
  277. return true;
  278. }
  279. else if (is_null($obj)) {
  280. return false;
  281. }
  282. else if ($filter instanceof PropertyNameFilter) {
  283. $name = $filter->getPropertyName();
  284. $value = ($obj instanceof Entity ? $obj->getPropertyValue($name) : $obj->{$name});
  285. return $value;
  286. }
  287. else if ($filter instanceof ConstantFilter) {
  288. $value = $filter->getValue();
  289. return $value;
  290. }
  291. else if ($filter instanceof UnaryFilter) {
  292. $ret = null;
  293. if ($filter->getOperator() == ('not')) {
  294. $op = self::filterInterperter($filter->getOperand(), $obj);
  295. if (is_null($op)) {
  296. // http://msdn.microsoft/com/en-us/library/ms191504.aspx
  297. $ret = true;
  298. }
  299. else {
  300. $ret = !$op;
  301. }
  302. return $ret;
  303. }
  304. }
  305. else if ($filter instanceof BinaryFilter) {
  306. $left = self::filterInterperter($filter->getLeft(), $obj);
  307. $right = self::filterInterperter($filter->getRight(), $obj);
  308. $ret = null;
  309. if ($filter->getOperator() == ('and')) {
  310. $ret = self::nullPropAnd($left, $right);
  311. }
  312. else if ($filter->getOperator() == ('or')) {
  313. $ret = self::nullPropOr($left, $right);
  314. }
  315. else if ($filter->getOperator() == ('eq')) {
  316. $ret = self::nullPropEq($left, $right);
  317. }
  318. else if ($filter->getOperator() == ('ne')) {
  319. $ret = self::nullPropNe($left, $right);
  320. }
  321. else if ($filter->getOperator() == ('ge')) {
  322. $ret = self::nullPropGe($left, $right);
  323. }
  324. else if ($filter->getOperator() == ('gt')) {
  325. $ret = self::nullPropGt($left, $right);
  326. }
  327. else if ($filter->getOperator() == ('lt')) {
  328. $ret = self::nullPropLt($left, $right);
  329. }
  330. else if ($filter->getOperator() == ('le')) {
  331. $ret = self::nullPropLe($left, $right);
  332. }
  333. return $ret;
  334. }
  335. var_dump(array($filter, $obj));
  336. throw new \Exception();
  337. }
  338. private static function nullPropAnd($left, $right) {
  339. // http://msdn.microsoft.com/en-us/library/ms191504.aspx
  340. if (is_null($left) && is_null($right)) {
  341. return null;
  342. }
  343. else if (is_null($left)) {
  344. return ($right ? null : false);
  345. }
  346. else if (is_null($right)) {
  347. return ($left ? null : false);
  348. }
  349. else {
  350. return $left && $right;
  351. }
  352. }
  353. private static function nullPropOr($left, $right) {
  354. // http://msdn.microsoft.com/en-us/library/ms191504.aspx
  355. if (is_null($left) && is_null($right)) {
  356. return null;
  357. }
  358. else if (is_null($left)) {
  359. return ($right ? true : null);
  360. }
  361. else if (is_null($right)) {
  362. return ($left ? true : null);
  363. }
  364. else {
  365. return $left || $right;
  366. }
  367. }
  368. private static function nullPropEq($left, $right) {
  369. if (is_null($left) || is_null($right)) {
  370. return null;
  371. } else if (is_string($left) || is_string($right)) {
  372. return ('' . $left) == ('' . $right);
  373. }
  374. return $left == $right;
  375. }
  376. private static function nullPropNe($left, $right) {
  377. if (is_null($left) || is_null($right)) {
  378. return null;
  379. } else if (is_string($left) || is_string($right)) {
  380. return ('' . $left) != ('' . $right);
  381. }
  382. return $left != $right;
  383. }
  384. private static function nullPropGt($left, $right) {
  385. if (is_null($left) || is_null($right)) {
  386. return null;
  387. } else if (is_string($left) || is_string($right)) {
  388. return ('' . $left) > ('' . $right);
  389. }
  390. return $left > $right;
  391. }
  392. private static function nullPropGe($left, $right) {
  393. if (is_null($left) || is_null($right)) {
  394. return null;
  395. } else if (is_string($left) || is_string($right)) {
  396. return ('' . $left) >= ('' . $right);
  397. }
  398. return $left >= $right;
  399. }
  400. private static function nullPropLt($left, $right) {
  401. if (is_null($left) || is_null($right)) {
  402. return null;
  403. } else if (is_string($left) || is_string($right)) {
  404. return ('' . $left) < ('' . $right);
  405. }
  406. return $left < $right;
  407. }
  408. private static function nullPropLe($left, $right) {
  409. if (is_null($left) || is_null($right)) {
  410. return null;
  411. } else if (is_string($left) || is_string($right)) {
  412. return ('' . $left) <= ('' . $right);
  413. }
  414. return $left <= $right;
  415. }
  416. public static function showEntityListDiff($actualData, $expectedData) {
  417. $ret = '';
  418. if (count($expectedData) != count($actualData))
  419. {
  420. $ret .= 'VVV actual VVV' . "\n";
  421. for ($i = 0; $i < count($actualData); $i++) {
  422. $e = $actualData[$i];
  423. $ret .= $e->getPartitionKey() . '/' . $e->getRowKey() . "\n";
  424. }
  425. $ret .= '-----------------' . "\n";
  426. for ($i = 0; $i < count($expectedData); $i++) {
  427. $e = $expectedData[$i];
  428. $ret .= $e->getPartitionKey() . '/' . $e->getRowKey() . "\n";
  429. }
  430. $ret .= '^^^ expected ^^^' . "\n";
  431. for ($i = 0; $i < count($actualData); $i++) {
  432. $in = false;
  433. $ei = $actualData[$i];
  434. for ($j = 0; $j < count($expectedData); $j++) {
  435. $ej = $expectedData[$j];
  436. if ($ei->getPartitionKey() == $ej->getPartitionKey() && $ei->getRowKey() == $ej->getRowKey()) {
  437. $in = true;
  438. }
  439. }
  440. if (!$in) {
  441. $ret .= 'returned ' . $this->tmptostring($ei). "\n";
  442. }
  443. }
  444. for ($j = 0; $j < count($expectedData); $j++) {
  445. $in = false;
  446. $ej = $expectedData[$j];
  447. for ($i = 0; $i < count($actualData); $i++) {
  448. $ei = $actualData[$i];
  449. if ($ei->getPartitionKey() == $ej->getPartitionKey() && $ei->getRowKey() == $ej->getRowKey()) {
  450. $in = true;
  451. }
  452. }
  453. if (!$in) {
  454. $ret .= 'expected ' . $this->tmptostring($ej). "\n";
  455. }
  456. }
  457. }
  458. return $ret;
  459. }
  460. }
  461. ?>