test_integration.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. # Copyright 2012 Pinterest.com
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. from builtins import bytes as newbytes
  16. from collections import defaultdict
  17. import json
  18. import pytest
  19. import six
  20. from library.pymemcache.client.base import Client
  21. from library.pymemcache.exceptions import (
  22. MemcacheIllegalInputError,
  23. MemcacheClientError
  24. )
  25. from library.pymemcache.serde import (
  26. PickleSerde,
  27. pickle_serde
  28. )
  29. def get_set_helper(client, key, value, key2, value2):
  30. result = client.get(key)
  31. assert result is None
  32. client.set(key, value, noreply=False)
  33. result = client.get(key)
  34. assert result == value
  35. client.set(key2, value2, noreply=True)
  36. result = client.get(key2)
  37. assert result == value2
  38. result = client.get_many([key, key2])
  39. assert result == {key: value, key2: value2}
  40. result = client.get_many([])
  41. assert result == {}
  42. @pytest.mark.integration()
  43. def test_get_set(client_class, host, port, socket_module):
  44. client = client_class((host, port), socket_module=socket_module)
  45. client.flush_all()
  46. key = b'key'
  47. value = b'value'
  48. key2 = b'key2'
  49. value2 = b'value2'
  50. get_set_helper(client, key, value, key2, value2)
  51. @pytest.mark.integration()
  52. def test_get_set_newbytes(client_class, host, port, socket_module):
  53. client = client_class((host, port), socket_module=socket_module)
  54. client.flush_all()
  55. key = newbytes(b'key3')
  56. value = b'value3'
  57. key2 = newbytes(b'key4')
  58. value2 = b'value4'
  59. get_set_helper(client, key, value, key2, value2)
  60. @pytest.mark.integration()
  61. def test_get_set_unicode_key(client_class, host, port, socket_module):
  62. client = client_class((host, port), socket_module=socket_module,
  63. allow_unicode_keys=True)
  64. client.flush_all()
  65. key = u"こんにちは"
  66. value = b'hello'
  67. key2 = 'my☃'
  68. value2 = b'value2'
  69. get_set_helper(client, key, value, key2, value2)
  70. @pytest.mark.integration()
  71. def test_add_replace(client_class, host, port, socket_module):
  72. client = client_class((host, port), socket_module=socket_module)
  73. client.flush_all()
  74. result = client.add(b'key', b'value', noreply=False)
  75. assert result is True
  76. result = client.get(b'key')
  77. assert result == b'value'
  78. result = client.add(b'key', b'value2', noreply=False)
  79. assert result is False
  80. result = client.get(b'key')
  81. assert result == b'value'
  82. result = client.replace(b'key1', b'value1', noreply=False)
  83. assert result is False
  84. result = client.get(b'key1')
  85. assert result is None
  86. result = client.replace(b'key', b'value2', noreply=False)
  87. assert result is True
  88. result = client.get(b'key')
  89. assert result == b'value2'
  90. @pytest.mark.integration()
  91. def test_append_prepend(client_class, host, port, socket_module):
  92. client = client_class((host, port), socket_module=socket_module)
  93. client.flush_all()
  94. result = client.append(b'key', b'value', noreply=False)
  95. assert result is False
  96. result = client.get(b'key')
  97. assert result is None
  98. result = client.set(b'key', b'value', noreply=False)
  99. assert result is True
  100. result = client.append(b'key', b'after', noreply=False)
  101. assert result is True
  102. result = client.get(b'key')
  103. assert result == b'valueafter'
  104. result = client.prepend(b'key1', b'value', noreply=False)
  105. assert result is False
  106. result = client.get(b'key1')
  107. assert result is None
  108. result = client.prepend(b'key', b'before', noreply=False)
  109. assert result is True
  110. result = client.get(b'key')
  111. assert result == b'beforevalueafter'
  112. @pytest.mark.integration()
  113. def test_cas(client_class, host, port, socket_module):
  114. client = client_class((host, port), socket_module=socket_module)
  115. client.flush_all()
  116. result = client.cas(b'key', b'value', b'1', noreply=False)
  117. assert result is None
  118. result = client.set(b'key', b'value', noreply=False)
  119. assert result is True
  120. # binary, string, and raw int all match -- should all be encoded as b'1'
  121. result = client.cas(b'key', b'value', b'1', noreply=False)
  122. assert result is False
  123. result = client.cas(b'key', b'value', '1', noreply=False)
  124. assert result is False
  125. result = client.cas(b'key', b'value', 1, noreply=False)
  126. assert result is False
  127. result, cas = client.gets(b'key')
  128. assert result == b'value'
  129. result = client.cas(b'key', b'value1', cas, noreply=False)
  130. assert result is True
  131. result = client.cas(b'key', b'value2', cas, noreply=False)
  132. assert result is False
  133. @pytest.mark.integration()
  134. def test_gets(client_class, host, port, socket_module):
  135. client = client_class((host, port), socket_module=socket_module)
  136. client.flush_all()
  137. result = client.gets(b'key')
  138. assert result == (None, None)
  139. result = client.set(b'key', b'value', noreply=False)
  140. assert result is True
  141. result = client.gets(b'key')
  142. assert result[0] == b'value'
  143. @pytest.mark.integration()
  144. def test_delete(client_class, host, port, socket_module):
  145. client = client_class((host, port), socket_module=socket_module)
  146. client.flush_all()
  147. result = client.delete(b'key', noreply=False)
  148. assert result is False
  149. result = client.get(b'key')
  150. assert result is None
  151. result = client.set(b'key', b'value', noreply=False)
  152. assert result is True
  153. result = client.delete(b'key', noreply=False)
  154. assert result is True
  155. result = client.get(b'key')
  156. assert result is None
  157. @pytest.mark.integration()
  158. def test_incr_decr(client_class, host, port, socket_module):
  159. client = Client((host, port), socket_module=socket_module)
  160. client.flush_all()
  161. result = client.incr(b'key', 1, noreply=False)
  162. assert result is None
  163. result = client.set(b'key', b'0', noreply=False)
  164. assert result is True
  165. result = client.incr(b'key', 1, noreply=False)
  166. assert result == 1
  167. def _bad_int():
  168. client.incr(b'key', b'foobar')
  169. with pytest.raises(MemcacheClientError):
  170. _bad_int()
  171. result = client.decr(b'key1', 1, noreply=False)
  172. assert result is None
  173. result = client.decr(b'key', 1, noreply=False)
  174. assert result == 0
  175. result = client.get(b'key')
  176. assert result == b'0'
  177. @pytest.mark.integration()
  178. def test_touch(client_class, host, port, socket_module):
  179. client = client_class((host, port), socket_module=socket_module)
  180. client.flush_all()
  181. result = client.touch(b'key', noreply=False)
  182. assert result is False
  183. result = client.set(b'key', b'0', 1, noreply=False)
  184. assert result is True
  185. result = client.touch(b'key', noreply=False)
  186. assert result is True
  187. result = client.touch(b'key', 1, noreply=False)
  188. assert result is True
  189. @pytest.mark.integration()
  190. def test_misc(client_class, host, port, socket_module):
  191. client = Client((host, port), socket_module=socket_module)
  192. client.flush_all()
  193. @pytest.mark.integration()
  194. def test_serialization_deserialization(host, port, socket_module):
  195. class JsonSerde(object):
  196. def serialize(self, key, value):
  197. return json.dumps(value).encode('ascii'), 1
  198. def deserialize(self, key, value, flags):
  199. if flags == 1:
  200. return json.loads(value.decode('ascii'))
  201. return value
  202. client = Client((host, port), serde=JsonSerde(),
  203. socket_module=socket_module)
  204. client.flush_all()
  205. value = {'a': 'b', 'c': ['d']}
  206. client.set(b'key', value)
  207. result = client.get(b'key')
  208. assert result == value
  209. def serde_serialization_helper(client_class, host, port,
  210. socket_module, serde):
  211. def check(value):
  212. client.set(b'key', value, noreply=False)
  213. result = client.get(b'key')
  214. assert result == value
  215. assert type(result) is type(value)
  216. client = client_class((host, port), serde=serde,
  217. socket_module=socket_module)
  218. client.flush_all()
  219. check(b'byte string')
  220. check(u'unicode string')
  221. check('olé')
  222. check(u'olé')
  223. check(1)
  224. check(123123123123123123123)
  225. check({'a': 'pickle'})
  226. check([u'one pickle', u'two pickle'])
  227. testdict = defaultdict(int)
  228. testdict[u'one pickle']
  229. testdict[b'two pickle']
  230. check(testdict)
  231. @pytest.mark.integration()
  232. def test_serde_serialization(client_class, host, port, socket_module):
  233. serde_serialization_helper(client_class, host, port,
  234. socket_module, pickle_serde)
  235. @pytest.mark.integration()
  236. def test_serde_serialization0(client_class, host, port, socket_module):
  237. serde_serialization_helper(
  238. client_class, host, port,
  239. socket_module,
  240. PickleSerde(pickle_version=0))
  241. @pytest.mark.integration()
  242. def test_serde_serialization2(client_class, host, port, socket_module):
  243. serde_serialization_helper(
  244. client_class, host, port,
  245. socket_module,
  246. PickleSerde(pickle_version=2))
  247. @pytest.mark.integration()
  248. def test_errors(client_class, host, port, socket_module):
  249. client = client_class((host, port), socket_module=socket_module)
  250. client.flush_all()
  251. def _key_with_ws():
  252. client.set(b'key with spaces', b'value', noreply=False)
  253. with pytest.raises(MemcacheIllegalInputError):
  254. _key_with_ws()
  255. def _key_with_illegal_carriage_return():
  256. client.set(b'\r\nflush_all', b'value', noreply=False)
  257. with pytest.raises(MemcacheIllegalInputError):
  258. _key_with_illegal_carriage_return()
  259. def _key_too_long():
  260. client.set(b'x' * 1024, b'value', noreply=False)
  261. with pytest.raises(MemcacheClientError):
  262. _key_too_long()
  263. def _unicode_key_in_set():
  264. client.set(six.u('\u0FFF'), b'value', noreply=False)
  265. with pytest.raises(MemcacheClientError):
  266. _unicode_key_in_set()
  267. def _unicode_key_in_get():
  268. client.get(six.u('\u0FFF'))
  269. with pytest.raises(MemcacheClientError):
  270. _unicode_key_in_get()
  271. def _unicode_value_in_set():
  272. client.set(b'key', six.u('\u0FFF'), noreply=False)
  273. with pytest.raises(MemcacheClientError):
  274. _unicode_value_in_set()
  275. @pytest.mark.integration()
  276. def test_tls(client_class, tls_host, tls_port, socket_module, tls_context):
  277. client = client_class(
  278. (tls_host, tls_port),
  279. socket_module=socket_module,
  280. tls_context=tls_context
  281. )
  282. client.flush_all()
  283. key = b'key'
  284. value = b'value'
  285. key2 = b'key2'
  286. value2 = b'value2'
  287. get_set_helper(client, key, value, key2, value2)