PageRenderTime 68ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/unit-test/testcase/test_system.cache.php

http://buddypress-media.googlecode.com/
PHP | 460 lines | 219 code | 171 blank | 70 comment | 38 complexity | b1b935daeb01db1a935c002805d677c7 MD5 | raw file
Possible License(s): AGPL-1.0, Apache-2.0, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * BP-MEDIA UNIT TEST SCRIPT - SYSTEM CACHE CLASS
  4. * Exercises all functions of the class
  5. *
  6. * @version 0.1.9
  7. * @since 0.1.9
  8. * @package BP-Media
  9. * @subpackage Unit Test
  10. * @license GPL v2.0
  11. * @link http://code.google.com/p/buddypress-media/
  12. *
  13. * ========================================================================================================
  14. */
  15. class core_system_cache_APC extends BPM_testCase {
  16. var $cls;
  17. var $check_array = array();
  18. var $namespace_max = 10; // These values need to be set high enough to get a range of data types
  19. var $key_max = 100;
  20. function setUp() {
  21. parent::setUp();
  22. // Since we're directly instantiating the cache class, we need to
  23. // set the cache engines to use from the settings stored in the test manager
  24. global $bpm_test_manager;
  25. $this->cls = new BPM_mCache( $bpm_test_manager->cache_engine );
  26. // Get APC's status
  27. $result = $this->cls->apcStatus();
  28. $apc_status = $result["status"];
  29. $apc_state = $result["state"];
  30. unset($result);
  31. // If APC is not active on the system, skip the entire block of tests
  32. if(!$apc_status){
  33. switch($apc_state){
  34. case "disabled" : {
  35. $reason = "APC disabled in class file";
  36. } break;
  37. case "inop" : {
  38. $reason = "APC not present on server";
  39. } break;
  40. case "fail" : {
  41. $reason = "APC unknown error";
  42. } break;
  43. }
  44. $this->markTestSkipped($reason);
  45. }
  46. }
  47. function generateData($type=null){
  48. $valid_types = array("null", "bool", "int", "float", "string", "array", "object");
  49. if($type === null){ // "0" is a valid type
  50. $current_type = $valid_types[mt_rand(0,6)];
  51. }
  52. else {
  53. // Using the modulus operator causes the function to cycle
  54. // through types if $type variable exceeds (int)5.
  55. $type_idx = $type % 6;
  56. $current_type = $valid_types[$type_idx];
  57. }
  58. switch($current_type){
  59. case "null" : {
  60. $val = null;
  61. } break;
  62. case "bool" : {
  63. $val = mt_rand(0,1);
  64. $val = (bool)$val;
  65. } break;
  66. case "int" : {
  67. $val = mt_rand(-100,100);
  68. $val = (int)$val;
  69. } break;
  70. case "float" : {
  71. $val = (mt_rand(-100,100) / 17);
  72. $val = (float)$val;
  73. } break;
  74. case "string" : {
  75. $width = mt_rand(0, 87);
  76. $val = BPM_sUtil::random_string($width);
  77. } break;
  78. case "array" : {
  79. $named_keys = mt_rand(0,1);
  80. $val = array();
  81. if(!$named_keys){
  82. for($i=0; $i<5; $i++){
  83. $val[] = mt_rand(-2500, 2500);
  84. }
  85. }
  86. else {
  87. for($i=0; $i<5; $i++){
  88. $width = mt_rand(1, 37);
  89. // PHP does not support arrays with numeric string keys. It silently converts them
  90. // to int keys. For example: $test_array["1234"] = "foo"; $test_array["bar"] = "baz";
  91. // var_dump($test_array) produces [ test_array[(int)1234] = "foo", test_array[(string)bar]
  92. // = "baz"]
  93. //
  94. // BPM_sUtil::random_string() can (and does) produce values like (string)7. To avoid
  95. // debugging problems, prepend all the key names with "k" to ensure PHP treats them as strings.
  96. $key_name = "k" . BPM_sUtil::random_string($width);
  97. $val[$key_name] = mt_rand(-2500, 2500);
  98. }
  99. }
  100. } break;
  101. case "object" : {
  102. $val = new stdClass();
  103. for($i=0; $i<3; $i++){
  104. $width = mt_rand(1, 17);
  105. // We prepend all the key names with "k" because BPM_sUtil::random_string()
  106. // can (and does) produce values like (string)7, which is an illegal name for a
  107. // variable in an object [you can't do $test_object->7 = "foo"; ...because the parser
  108. // doesn't know if you mean (string)7 or (int)7 ]
  109. //
  110. // But, PHP *doesn't catch* this defect when the variable name is created dynamically
  111. // [ $name = "7"; $test_object->{$name} = "foo" ]. Instead, it converts the key's type
  112. // from (string)7 to (int)7 and allows the variable to be accessed only if the name is
  113. // created dynamically [$name = "7"; echo ($test_object->{$name}; ]
  114. $key_name = "k" . BPM_sUtil::random_string($width);
  115. $val->{$key_name} = mt_rand(-2500, 2500);
  116. }
  117. } break;
  118. } // End of switch($current_type)
  119. return $val;
  120. }
  121. function load_table(){
  122. $total_keys = 0;
  123. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  124. for ($key=1; $key < $this->key_max; $key++) {
  125. // Cycle through data types for the first 50 keys, then
  126. // randomly pick data types
  127. if($total_keys < 50){
  128. $val = self::generateData($total_keys);
  129. }
  130. else {
  131. $val = self::generateData();
  132. }
  133. $ns_name = "ns" . $namespace;
  134. $key_name = "key" . $key;
  135. // Write generated value to the cache and the check array
  136. $this->cls->set($ns_name, $key_name, $val);
  137. $this->check_array[$ns_name][$key_name] = $val;
  138. $total_keys++;
  139. } // ENDOF for( $key
  140. } // ENDOF: for( $namespace
  141. }
  142. function check_table(){
  143. // Load every key stored to the table and compare it against
  144. // the value stored in the check array, making sure data types were
  145. // correctly recovered (bool) false doesn't become (int) 0 or "NULL"
  146. // ====================================================================
  147. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  148. for ($key=1; $key < $this->key_max; $key++) {
  149. $ns_name = "ns" . $namespace;
  150. $key_name = "key" . $key;
  151. $result = $this->cls->get($ns_name, $key_name);
  152. $this->assertEquals($this->check_array[$ns_name][$key_name], $result);
  153. }
  154. }
  155. }
  156. function test_create(){
  157. // Delete all entries in the cache
  158. $this->cls->flushAll();
  159. // Load the database and check array with test data. Note that PHPUnit resets ALL the
  160. // class variables between tests, so we have to reload the table and reset the cache
  161. // in each test
  162. self::load_table();
  163. // Verify the stored data matches the check array
  164. self::check_table();
  165. } // End of test_create
  166. function test_update(){
  167. // Delete all entries in the cache
  168. $this->cls->flushAll();
  169. // Load the database and check array with test data. Note that PHPUnit resets ALL the
  170. // class variables between tests, so we have to reload the table and reset the cache
  171. // in each test
  172. self::load_table();
  173. $total_keys = 0;
  174. // Overwrite half of the items in the table with random new data
  175. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  176. for ($key=1; $key < $this->key_max; $key++) {
  177. $overwrite = mt_rand(0,1);
  178. if(true){
  179. // Cycle through data types for the first 50 keys, then
  180. // randomly pick data types
  181. if($total_keys < 50){
  182. $val = self::generateData($total_keys);
  183. }
  184. else {
  185. $val = self::generateData();
  186. }
  187. $ns_name = "ns" . $namespace;
  188. $key_name = "key" . $key;
  189. // Write generated value to the cache and the check array
  190. $this->cls->set($ns_name, $key_name, $val);
  191. $this->check_array[$ns_name][$key_name] = $val;
  192. $total_keys++;
  193. } // ENDOF if($overwrite)
  194. } // ENDOF for( $key
  195. } // ENDOF: for( $namespace
  196. // Verify the stored data matches the check array
  197. self::check_table();
  198. } // End of test_update
  199. function test_del(){
  200. // Delete all entries in the cache
  201. $this->cls->flushAll();
  202. // Load the database and check array with test data. Note that PHPUnit resets ALL the
  203. // class variables between tests, so we have to reload the table and reset the cache
  204. // in each test
  205. self::load_table();
  206. // Delete half the keys in the cache
  207. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  208. for ($key=1; $key < $this->key_max; $key++) {
  209. $delete = mt_rand(0,1);
  210. if($delete){
  211. $ns_name = "ns" . $namespace;
  212. $key_name = "key" . $key;
  213. // Remove the key from the check array
  214. $this->cls->del($ns_name, $key_name);
  215. unset($this->check_array[$ns_name][$key_name]);
  216. } // ENDOF if($delete)
  217. } // ENDOF for( $key
  218. } // ENDOF: for( $namespace
  219. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  220. for ($key=1; $key < $this->key_max; $key++) {
  221. $ns_name = "ns" . $namespace;
  222. $key_name = "key" . $key;
  223. $result = $this->cls->get($ns_name, $key_name, &$success);
  224. $expected = $this->check_array[$ns_name][$key_name];
  225. if( is_array($this->check_array[$ns_name]) && array_key_exists($key_name, $this->check_array[$ns_name]) ){
  226. $key_exists = true;
  227. }
  228. else {
  229. $key_exists = false;
  230. }
  231. if($key_exists){
  232. $this->assertEquals($this->check_array[$ns_name][$key_name], $result);
  233. $this->assertEquals(true, $success);
  234. }
  235. else {
  236. $this->assertEquals($this->check_array[$ns_name][$key_name], $result);
  237. $this->assertEquals(false, $success);
  238. }
  239. }
  240. }
  241. } // End of test_del
  242. function test_flushNamespace(){
  243. // Delete all entries in the cache
  244. $this->cls->flushAll();
  245. // Load the database and check array with test data. Note that PHPUnit resets ALL the
  246. // class variables between tests, so we have to reload the table and reset the cache
  247. // in each test
  248. self::load_table();
  249. // Delete half the namespaces in the cache
  250. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  251. $delete = mt_rand(0,1);
  252. if($delete){
  253. $ns_name = "ns" . $namespace;
  254. $key_name = "key" . $key;
  255. // Remove the namespace from the check array
  256. $this->cls->flushNamespace($ns_name);
  257. unset($this->check_array[$ns_name]);
  258. } // ENDOF if($delete)
  259. } // ENDOF: for( $namespace
  260. // Check that the cache returns the correct value when loading keys from both
  261. // active and deleted namespaces
  262. for( $namespace=1; $namespace < $this->namespace_max; $namespace++){
  263. for ($key=1; $key < $this->key_max; $key++) {
  264. $ns_name = "ns" . $namespace;
  265. $key_name = "key" . $key;
  266. $result = $this->cls->get($ns_name, $key_name, &$success);
  267. $expected = $this->check_array[$ns_name][$key_name];
  268. if( is_array($this->check_array[$ns_name]) && array_key_exists($key_name, $this->check_array[$ns_name]) ){
  269. $key_exists = true;
  270. }
  271. else {
  272. $key_exists = false;
  273. }
  274. if($key_exists){
  275. $this->assertEquals($this->check_array[$ns_name][$key_name], $result);
  276. $this->assertEquals(true, $success);
  277. }
  278. else {
  279. $this->assertEquals($this->check_array[$ns_name][$key_name], $result);
  280. $this->assertEquals(false, $success);
  281. }
  282. }
  283. }
  284. } // End of test_flushNamespace
  285. function tearDown() {
  286. parent::tearDown();
  287. }
  288. }
  289. ?>