PageRenderTime 135ms CodeModel.GetById 7ms RepoModel.GetById 2ms app.codeStats 0ms

/test/test_mem_cache.rb

https://github.com/ryland/memcache-client
Ruby | 758 lines | 702 code | 56 blank | 0 comment | 1 complexity | 9d1bea5c1c86bdfa63fda0c55b285726 MD5 | raw file
  1. require 'stringio'
  2. require 'test/unit'
  3. require 'rubygems'
  4. require 'test/zentest_assertions'
  5. $TESTING = true
  6. require 'lib/memcache'
  7. class MemCache
  8. attr_writer :namespace
  9. end
  10. class FakeSocket
  11. attr_reader :written, :data
  12. def initialize
  13. @written = StringIO.new
  14. @data = StringIO.new
  15. end
  16. def write(data)
  17. @written.write data
  18. end
  19. def gets
  20. @data.gets
  21. end
  22. def read(arg)
  23. @data.read arg
  24. end
  25. end
  26. class FakeServer
  27. attr_reader :host, :port, :socket
  28. def initialize(socket = nil)
  29. @closed = false
  30. @host = 'example.com'
  31. @port = 11211
  32. @socket = socket || FakeSocket.new
  33. end
  34. def close
  35. @closed = true
  36. end
  37. def alive?
  38. !@closed
  39. end
  40. end
  41. class TestMemCache < Test::Unit::TestCase
  42. def setup
  43. @cache = MemCache.new 'localhost:1', :namespace => 'my_namespace'
  44. end
  45. def test_cache_get
  46. server = util_setup_fake_server
  47. assert_equal "\004\b\"\0170123456789",
  48. @cache.cache_get(server, 'my_namespace:key')
  49. assert_equal "get my_namespace:key\r\n",
  50. server.socket.written.string
  51. end
  52. def test_cache_get_EOF
  53. server = util_setup_fake_server
  54. server.socket.data.string = ''
  55. e = assert_raise MemCache::MemCacheError do
  56. @cache.cache_get server, 'my_namespace:key'
  57. end
  58. assert_equal "lost connection to example.com:11211", e.message
  59. end
  60. def test_cache_get_bad_state
  61. server = FakeServer.new
  62. server.socket.data.write "bogus response\r\n"
  63. server.socket.data.rewind
  64. @cache.servers = []
  65. @cache.servers << server
  66. e = assert_raise MemCache::MemCacheError do
  67. @cache.cache_get(server, 'my_namespace:key')
  68. end
  69. assert_equal "unexpected response \"bogus response\\r\\n\"", e.message
  70. deny server.alive?
  71. assert_equal "get my_namespace:key\r\n",
  72. server.socket.written.string
  73. end
  74. def test_cache_get_miss
  75. socket = FakeSocket.new
  76. socket.data.write "END\r\n"
  77. socket.data.rewind
  78. server = FakeServer.new socket
  79. assert_equal nil, @cache.cache_get(server, 'my_namespace:key')
  80. assert_equal "get my_namespace:key\r\n",
  81. socket.written.string
  82. end
  83. def test_cache_get_multi
  84. server = util_setup_fake_server
  85. server.socket.data.write "VALUE foo 0 7\r\n"
  86. server.socket.data.write "\004\b\"\bfoo\r\n"
  87. server.socket.data.write "VALUE bar 0 7\r\n"
  88. server.socket.data.write "\004\b\"\bbar\r\n"
  89. server.socket.data.write "END\r\n"
  90. server.socket.data.rewind
  91. result = @cache.cache_get_multi server, 'foo bar baz'
  92. assert_equal 2, result.length
  93. assert_equal "\004\b\"\bfoo", result['foo']
  94. assert_equal "\004\b\"\bbar", result['bar']
  95. end
  96. def test_cache_get_multi_EOF
  97. server = util_setup_fake_server
  98. server.socket.data.string = ''
  99. e = assert_raise MemCache::MemCacheError do
  100. @cache.cache_get_multi server, 'my_namespace:key'
  101. end
  102. assert_equal "lost connection to example.com:11211", e.message
  103. end
  104. def test_cache_get_multi_bad_state
  105. server = FakeServer.new
  106. server.socket.data.write "bogus response\r\n"
  107. server.socket.data.rewind
  108. @cache.servers = []
  109. @cache.servers << server
  110. e = assert_raise MemCache::MemCacheError do
  111. @cache.cache_get_multi server, 'my_namespace:key'
  112. end
  113. assert_equal "unexpected response \"bogus response\\r\\n\"", e.message
  114. deny server.alive?
  115. assert_equal "get my_namespace:key\r\n",
  116. server.socket.written.string
  117. end
  118. def test_crc32_ITU_T
  119. assert_equal 0, ''.crc32_ITU_T
  120. assert_equal 1260851911, 'my_namespace:key'.crc32_ITU_T
  121. end
  122. def test_initialize
  123. cache = MemCache.new :namespace => 'my_namespace', :readonly => true
  124. assert_equal 'my_namespace', cache.namespace
  125. assert_equal true, cache.readonly?
  126. assert_equal true, cache.servers.empty?
  127. end
  128. def test_initialize_compatible
  129. cache = MemCache.new ['localhost:11211', 'localhost:11212'],
  130. :namespace => 'my_namespace', :readonly => true
  131. assert_equal 'my_namespace', cache.namespace
  132. assert_equal true, cache.readonly?
  133. assert_equal false, cache.servers.empty?
  134. assert_equal true, cache.servers.first.tcp_nodelay
  135. end
  136. def test_initialize_compatible_no_hash
  137. cache = MemCache.new ['localhost:11211', 'localhost:11212']
  138. assert_equal nil, cache.namespace
  139. assert_equal false, cache.readonly?
  140. assert_equal false, cache.servers.empty?
  141. end
  142. def test_initialize_compatible_one_server
  143. cache = MemCache.new 'localhost:11211'
  144. assert_equal nil, cache.namespace
  145. assert_equal false, cache.readonly?
  146. assert_equal false, cache.servers.empty?
  147. end
  148. def test_initialize_compatible_bad_arg
  149. e = assert_raise ArgumentError do
  150. cache = MemCache.new Object.new
  151. end
  152. assert_equal 'first argument must be Array, Hash or String', e.message
  153. end
  154. def test_initialize_multiple_servers
  155. cache = MemCache.new %w[localhost:11211 localhost:11212],
  156. :namespace => 'my_namespace', :readonly => true
  157. assert_equal 'my_namespace', cache.namespace
  158. assert_equal true, cache.readonly?
  159. assert_equal false, cache.servers.empty?
  160. deny_empty cache.instance_variable_get(:@buckets)
  161. end
  162. def test_initialize_with_server_options
  163. cache = MemCache.new %w[localhost:11211 localhost:11212],
  164. :namespace => 'my_namespace', :retry_delay => 15.0,
  165. :connect_timeout => 5.0
  166. assert_equal 'my_namespace', cache.namespace
  167. assert_equal false, cache.servers.empty?
  168. cache.servers.each do |s|
  169. assert_equal 5.0, s.connect_timeout
  170. assert_equal 15.0, s.retry_delay
  171. end
  172. end
  173. def test_initialize_too_many_args
  174. assert_raises ArgumentError do
  175. MemCache.new 1, 2, 3
  176. end
  177. end
  178. def test_decr
  179. server = FakeServer.new
  180. server.socket.data.write "5\r\n"
  181. server.socket.data.rewind
  182. @cache.servers = []
  183. @cache.servers << server
  184. value = @cache.decr 'key'
  185. assert_equal "decr my_namespace:key 1\r\n",
  186. @cache.servers.first.socket.written.string
  187. assert_equal 5, value
  188. end
  189. def test_decr_not_found
  190. server = FakeServer.new
  191. server.socket.data.write "NOT_FOUND\r\n"
  192. server.socket.data.rewind
  193. @cache.servers = []
  194. @cache.servers << server
  195. value = @cache.decr 'key'
  196. assert_equal "decr my_namespace:key 1\r\n",
  197. @cache.servers.first.socket.written.string
  198. assert_equal nil, value
  199. end
  200. def test_decr_space_padding
  201. server = FakeServer.new
  202. server.socket.data.write "5 \r\n"
  203. server.socket.data.rewind
  204. @cache.servers = []
  205. @cache.servers << server
  206. value = @cache.decr 'key'
  207. assert_equal "decr my_namespace:key 1\r\n",
  208. @cache.servers.first.socket.written.string
  209. assert_equal 5, value
  210. end
  211. def test_get
  212. util_setup_fake_server
  213. value = @cache.get 'key'
  214. assert_equal "get my_namespace:key\r\n",
  215. @cache.servers.first.socket.written.string
  216. assert_equal '0123456789', value
  217. end
  218. def test_get_bad_key
  219. util_setup_fake_server
  220. assert_raise ArgumentError do @cache.get 'k y' end
  221. util_setup_fake_server
  222. assert_raise ArgumentError do @cache.get 'k' * 250 end
  223. end
  224. def test_get_cache_get_IOError
  225. socket = Object.new
  226. def socket.write(arg) raise IOError, 'some io error'; end
  227. server = FakeServer.new socket
  228. @cache.servers = []
  229. @cache.servers << server
  230. e = assert_raise MemCache::MemCacheError do
  231. @cache.get 'my_namespace:key'
  232. end
  233. assert_equal 'some io error', e.message
  234. end
  235. def test_get_cache_get_SystemCallError
  236. socket = Object.new
  237. def socket.write(arg) raise SystemCallError, 'some syscall error'; end
  238. server = FakeServer.new socket
  239. @cache.servers = []
  240. @cache.servers << server
  241. e = assert_raise MemCache::MemCacheError do
  242. @cache.get 'my_namespace:key'
  243. end
  244. assert_equal 'unknown error - some syscall error', e.message
  245. end
  246. def test_get_no_connection
  247. @cache.servers = 'localhost:1'
  248. e = assert_raise MemCache::MemCacheError do
  249. @cache.get 'key'
  250. end
  251. assert_match /^No connection to server/, e.message
  252. end
  253. def test_get_no_servers
  254. @cache.servers = []
  255. e = assert_raise MemCache::MemCacheError do
  256. @cache.get 'key'
  257. end
  258. assert_equal 'No active servers', e.message
  259. end
  260. def test_get_multi
  261. server = FakeServer.new
  262. server.socket.data.write "VALUE my_namespace:key 0 14\r\n"
  263. server.socket.data.write "\004\b\"\0170123456789\r\n"
  264. server.socket.data.write "VALUE my_namespace:keyb 0 14\r\n"
  265. server.socket.data.write "\004\b\"\0179876543210\r\n"
  266. server.socket.data.write "END\r\n"
  267. server.socket.data.rewind
  268. @cache.servers = []
  269. @cache.servers << server
  270. values = @cache.get_multi 'key', 'keyb'
  271. assert_equal "get my_namespace:key my_namespace:keyb\r\n",
  272. server.socket.written.string
  273. expected = { 'key' => '0123456789', 'keyb' => '9876543210' }
  274. assert_equal expected.sort, values.sort
  275. end
  276. def test_get_raw
  277. server = FakeServer.new
  278. server.socket.data.write "VALUE my_namespace:key 0 10\r\n"
  279. server.socket.data.write "0123456789\r\n"
  280. server.socket.data.write "END\r\n"
  281. server.socket.data.rewind
  282. @cache.servers = []
  283. @cache.servers << server
  284. value = @cache.get 'key', true
  285. assert_equal "get my_namespace:key\r\n",
  286. @cache.servers.first.socket.written.string
  287. assert_equal '0123456789', value
  288. end
  289. def test_get_server_for_key
  290. server = @cache.get_server_for_key 'key'
  291. assert_equal 'localhost', server.host
  292. assert_equal 1, server.port
  293. end
  294. def test_get_server_for_key_multiple
  295. s1 = util_setup_server @cache, 'one.example.com', ''
  296. s2 = util_setup_server @cache, 'two.example.com', ''
  297. @cache.instance_variable_set :@servers, [s1, s2]
  298. @cache.instance_variable_set :@buckets, [s1, s2]
  299. server = @cache.get_server_for_key 'keya'
  300. assert_equal 'two.example.com', server.host
  301. server = @cache.get_server_for_key 'keyb'
  302. assert_equal 'one.example.com', server.host
  303. end
  304. def test_get_server_for_key_no_servers
  305. @cache.servers = []
  306. e = assert_raise MemCache::MemCacheError do
  307. @cache.get_server_for_key 'key'
  308. end
  309. assert_equal 'No servers available', e.message
  310. end
  311. def test_get_server_for_key_spaces
  312. e = assert_raise ArgumentError do
  313. @cache.get_server_for_key 'space key'
  314. end
  315. assert_equal 'illegal character in key "space key"', e.message
  316. end
  317. def test_get_server_for_key_length
  318. @cache.get_server_for_key 'x' * 250
  319. long_key = 'x' * 251
  320. e = assert_raise ArgumentError do
  321. @cache.get_server_for_key long_key
  322. end
  323. assert_equal "key too long #{long_key.inspect}", e.message
  324. end
  325. def test_incr
  326. server = FakeServer.new
  327. server.socket.data.write "5\r\n"
  328. server.socket.data.rewind
  329. @cache.servers = []
  330. @cache.servers << server
  331. value = @cache.incr 'key'
  332. assert_equal "incr my_namespace:key 1\r\n",
  333. @cache.servers.first.socket.written.string
  334. assert_equal 5, value
  335. end
  336. def test_incr_not_found
  337. server = FakeServer.new
  338. server.socket.data.write "NOT_FOUND\r\n"
  339. server.socket.data.rewind
  340. @cache.servers = []
  341. @cache.servers << server
  342. value = @cache.incr 'key'
  343. assert_equal "incr my_namespace:key 1\r\n",
  344. @cache.servers.first.socket.written.string
  345. assert_equal nil, value
  346. end
  347. def test_incr_space_padding
  348. server = FakeServer.new
  349. server.socket.data.write "5 \r\n"
  350. server.socket.data.rewind
  351. @cache.servers = []
  352. @cache.servers << server
  353. value = @cache.incr 'key'
  354. assert_equal "incr my_namespace:key 1\r\n",
  355. @cache.servers.first.socket.written.string
  356. assert_equal 5, value
  357. end
  358. def test_make_cache_key
  359. assert_equal 'my_namespace:key', @cache.make_cache_key('key')
  360. @cache.namespace = nil
  361. assert_equal 'key', @cache.make_cache_key('key')
  362. end
  363. def test_servers
  364. server = FakeServer.new
  365. @cache.servers = []
  366. @cache.servers << server
  367. assert_equal [server], @cache.servers
  368. end
  369. def test_servers_equals_type_error
  370. e = assert_raise TypeError do
  371. @cache.servers = [Object.new]
  372. end
  373. assert_equal 'cannot convert Object into MemCache::Server', e.message
  374. end
  375. def test_set
  376. server = FakeServer.new
  377. server.socket.data.write "STORED\r\n"
  378. server.socket.data.rewind
  379. @cache.servers = []
  380. @cache.servers << server
  381. @cache.set 'key', 'value'
  382. expected = "set my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
  383. assert_equal expected, server.socket.written.string
  384. end
  385. def test_set_expiry
  386. server = FakeServer.new
  387. server.socket.data.write "STORED\r\n"
  388. server.socket.data.rewind
  389. @cache.servers = []
  390. @cache.servers << server
  391. @cache.set 'key', 'value', 5
  392. expected = "set my_namespace:key 0 5 9\r\n\004\b\"\nvalue\r\n"
  393. assert_equal expected, server.socket.written.string
  394. end
  395. def test_set_raw
  396. server = FakeServer.new
  397. server.socket.data.write "STORED\r\n"
  398. server.socket.data.rewind
  399. @cache.servers = []
  400. @cache.servers << server
  401. @cache.set 'key', 'value', 0, true
  402. expected = "set my_namespace:key 0 0 5\r\nvalue\r\n"
  403. assert_equal expected, server.socket.written.string
  404. end
  405. def test_set_readonly
  406. cache = MemCache.new :readonly => true
  407. e = assert_raise MemCache::MemCacheError do
  408. cache.set 'key', 'value'
  409. end
  410. assert_equal 'Update of readonly cache', e.message
  411. end
  412. def test_set_too_big
  413. server = FakeServer.new
  414. server.socket.data.write "SERVER_ERROR object too large for cache\r\n"
  415. server.socket.data.rewind
  416. @cache.servers = []
  417. @cache.servers << server
  418. e = assert_raise MemCache::MemCacheError do
  419. @cache.set 'key', 'v'
  420. end
  421. assert_equal 'object too large for cache', e.message
  422. end
  423. def test_add
  424. server = FakeServer.new
  425. server.socket.data.write "STORED\r\n"
  426. server.socket.data.rewind
  427. @cache.servers = []
  428. @cache.servers << server
  429. @cache.add 'key', 'value'
  430. expected = "add my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
  431. assert_equal expected, server.socket.written.string
  432. end
  433. def test_add_exists
  434. server = FakeServer.new
  435. server.socket.data.write "NOT_STORED\r\n"
  436. server.socket.data.rewind
  437. @cache.servers = []
  438. @cache.servers << server
  439. @cache.add 'key', 'value'
  440. expected = "add my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
  441. assert_equal expected, server.socket.written.string
  442. end
  443. def test_add_expiry
  444. server = FakeServer.new
  445. server.socket.data.write "STORED\r\n"
  446. server.socket.data.rewind
  447. @cache.servers = []
  448. @cache.servers << server
  449. @cache.add 'key', 'value', 5
  450. expected = "add my_namespace:key 0 5 9\r\n\004\b\"\nvalue\r\n"
  451. assert_equal expected, server.socket.written.string
  452. end
  453. def test_add_raw
  454. server = FakeServer.new
  455. server.socket.data.write "STORED\r\n"
  456. server.socket.data.rewind
  457. @cache.servers = []
  458. @cache.servers << server
  459. @cache.add 'key', 'value', 0, true
  460. expected = "add my_namespace:key 0 0 5\r\nvalue\r\n"
  461. assert_equal expected, server.socket.written.string
  462. end
  463. def test_add_readonly
  464. cache = MemCache.new :readonly => true
  465. e = assert_raise MemCache::MemCacheError do
  466. cache.add 'key', 'value'
  467. end
  468. assert_equal 'Update of readonly cache', e.message
  469. end
  470. def test_delete
  471. server = FakeServer.new
  472. @cache.servers = []
  473. @cache.servers << server
  474. @cache.delete 'key'
  475. expected = "delete my_namespace:key 0\r\n"
  476. assert_equal expected, server.socket.written.string
  477. end
  478. def test_delete_with_expiry
  479. server = FakeServer.new
  480. @cache.servers = []
  481. @cache.servers << server
  482. @cache.delete 'key', 300
  483. expected = "delete my_namespace:key 300\r\n"
  484. assert_equal expected, server.socket.written.string
  485. end
  486. def test_flush_all
  487. @cache.servers = []
  488. 3.times { @cache.servers << FakeServer.new }
  489. @cache.flush_all
  490. expected = "flush_all\r\n"
  491. @cache.servers.each do |server|
  492. assert_equal expected, server.socket.written.string
  493. end
  494. end
  495. def test_flush_all_failure
  496. socket = FakeSocket.new
  497. socket.data.write "ERROR\r\n"
  498. socket.data.rewind
  499. server = FakeServer.new socket
  500. def server.host() "localhost"; end
  501. def server.port() 11211; end
  502. @cache.servers = []
  503. @cache.servers << server
  504. assert_raise MemCache::MemCacheError do
  505. @cache.flush_all
  506. end
  507. assert_equal "flush_all\r\n", socket.written.string
  508. end
  509. def test_stats
  510. socket = FakeSocket.new
  511. socket.data.write "STAT pid 20188\r\nSTAT total_items 32\r\nSTAT version 1.2.3\r\nSTAT rusage_user 1:300\r\nSTAT dummy ok\r\nEND\r\n"
  512. socket.data.rewind
  513. server = FakeServer.new socket
  514. def server.host() 'localhost'; end
  515. def server.port() 11211; end
  516. @cache.servers = []
  517. @cache.servers << server
  518. expected = {
  519. 'localhost:11211' => {
  520. 'pid' => 20188, 'total_items' => 32, 'version' => '1.2.3',
  521. 'rusage_user' => 1.0003, 'dummy' => 'ok'
  522. }
  523. }
  524. assert_equal expected, @cache.stats
  525. assert_equal "stats\r\n", socket.written.string
  526. end
  527. def test_basic_threaded_operations_should_work
  528. cache = MemCache.new :multithread => true,
  529. :namespace => 'my_namespace',
  530. :readonly => false
  531. server = util_setup_server cache, 'example.com', "OK\r\n"
  532. cache.instance_variable_set :@servers, [server]
  533. assert_nothing_raised do
  534. cache.set "test", "test value"
  535. end
  536. end
  537. def test_basic_unthreaded_operations_should_work
  538. cache = MemCache.new :multithread => false,
  539. :namespace => 'my_namespace',
  540. :readonly => false
  541. server = util_setup_server cache, 'example.com', "OK\r\n"
  542. cache.instance_variable_set :@servers, [server]
  543. assert_nothing_raised do
  544. cache.set "test", "test value"
  545. end
  546. end
  547. def util_setup_fake_server
  548. server = FakeServer.new
  549. server.socket.data.write "VALUE my_namespace:key 0 14\r\n"
  550. server.socket.data.write "\004\b\"\0170123456789\r\n"
  551. server.socket.data.write "END\r\n"
  552. server.socket.data.rewind
  553. @cache.servers = []
  554. @cache.servers << server
  555. return server
  556. end
  557. def util_setup_server(memcache, host, responses)
  558. server = MemCache::Server.new memcache, host
  559. server.instance_variable_set :@sock, StringIO.new(responses)
  560. @cache.servers = []
  561. @cache.servers << server
  562. return server
  563. end
  564. end