OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:async'; |
| 6 import 'dart:convert'; |
| 7 |
| 8 import 'package:appengine/api/errors.dart'; |
| 9 import 'package:appengine/src/api_impl/raw_memcache_impl.dart'; |
| 10 import 'package:appengine/src/protobuf_api/internal/memcache_service.pb.dart'; |
| 11 import 'package:fixnum/fixnum.dart'; |
| 12 import 'package:memcache/src/memcache_impl.dart'; |
| 13 import 'package:unittest/unittest.dart'; |
| 14 |
| 15 import 'utils/mock_rpc.dart'; |
| 16 import 'utils/error_matchers.dart'; |
| 17 |
| 18 main() { |
| 19 const INVALID_PROTOBUF = const [1, 2, 3, 4, 5]; |
| 20 |
| 21 group('memcache', () { |
| 22 test('set', () { |
| 23 var mock = new MockRPCService('memcache'); |
| 24 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 25 |
| 26 // Tests NetworkError. |
| 27 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 28 return new Future.error(new NetworkError("")); |
| 29 })); |
| 30 expect(memcache.set('language', 'dart'), throwsA(isNetworkError)); |
| 31 |
| 32 // Tests ProtocolError. |
| 33 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 34 return new Future.value(INVALID_PROTOBUF); |
| 35 })); |
| 36 expect(memcache.set('language', 'dart'), throwsA(isProtocolError)); |
| 37 |
| 38 // Tests status error returned from memcache service. |
| 39 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 40 var response = new MemcacheSetResponse(); |
| 41 response.setStatus.add(MemcacheSetResponse_SetStatusCode.ERROR); |
| 42 return new Future.value(response.writeToBuffer()); |
| 43 })); |
| 44 expect(memcache.set('language', 'dart'), throwsA(isMemcacheError)); |
| 45 |
| 46 // Tests not stored. |
| 47 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 48 expect(request.item[0].key, equals(UTF8.encode('language'))); |
| 49 expect(request.item[0].value, equals(UTF8.encode('dart'))); |
| 50 |
| 51 var response = new MemcacheSetResponse(); |
| 52 response.setStatus.add(MemcacheSetResponse_SetStatusCode.NOT_STORED); |
| 53 return new Future.value(response.writeToBuffer()); |
| 54 })); |
| 55 expect(memcache.set('language', 'dart'), throwsA(isMemcacheNotStored)); |
| 56 |
| 57 // Tests sucessfull store |
| 58 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 59 expect(request.item[0].key, equals(UTF8.encode('language'))); |
| 60 expect(request.item[0].value, equals(UTF8.encode('dart'))); |
| 61 |
| 62 var response = new MemcacheSetResponse(); |
| 63 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 64 return new Future.value(response.writeToBuffer()); |
| 65 })); |
| 66 |
| 67 expect(memcache.set('language', 'dart'), completes); |
| 68 }); |
| 69 |
| 70 var setAllMap = { |
| 71 'language': 'dart', |
| 72 UTF8.encode('language'): 'dart', |
| 73 [1, 2, 3]: UTF8.encode('dart'), |
| 74 }; |
| 75 var setAllKeys = |
| 76 [UTF8.encode('language'), UTF8.encode('language'), [1, 2, 3]]; |
| 77 var setAllValues = |
| 78 [UTF8.encode('dart'), UTF8.encode('dart'), UTF8.encode('dart')]; |
| 79 |
| 80 checkSetAllRequest(request, setPolicy) { |
| 81 expect(request.item.length, setAllKeys.length); |
| 82 for (var i = 0; i < setAllKeys.length; i++) { |
| 83 expect(request.item[i].setPolicy, setPolicy); |
| 84 expect(request.item[i].key, setAllKeys[i]); |
| 85 expect(request.item[i].value, setAllValues[i]); |
| 86 } |
| 87 } |
| 88 |
| 89 test('setAll', () { |
| 90 var mock = new MockRPCService('memcache'); |
| 91 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 92 |
| 93 // Tests NetworkError. |
| 94 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 95 return new Future.error(new NetworkError("")); |
| 96 })); |
| 97 expect(memcache.setAll(setAllMap), throwsA(isNetworkError)); |
| 98 |
| 99 // Tests ProtocolError. |
| 100 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 101 return new Future.value(INVALID_PROTOBUF); |
| 102 })); |
| 103 expect(memcache.setAll(setAllMap), throwsA(isProtocolError)); |
| 104 |
| 105 // Tests status error returned from memcache service. |
| 106 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 107 var response = new MemcacheSetResponse(); |
| 108 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 109 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 110 response.setStatus.add(MemcacheSetResponse_SetStatusCode.ERROR); |
| 111 return new Future.value(response.writeToBuffer()); |
| 112 })); |
| 113 expect(memcache.setAll(setAllMap), throwsA(isMemcacheError)); |
| 114 |
| 115 // Tests not stored. |
| 116 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 117 checkSetAllRequest(request, MemcacheSetRequest_SetPolicy.SET); |
| 118 |
| 119 var response = new MemcacheSetResponse(); |
| 120 response.setStatus.add(MemcacheSetResponse_SetStatusCode.NOT_STORED); |
| 121 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 122 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 123 return new Future.value(response.writeToBuffer()); |
| 124 })); |
| 125 expect(memcache.setAll(setAllMap), throwsA(isMemcacheNotStored)); |
| 126 |
| 127 // Tests sucessfull store |
| 128 mock.register('Set', MemcacheSetRequest, expectAsync((request) { |
| 129 checkSetAllRequest(request, MemcacheSetRequest_SetPolicy.SET); |
| 130 |
| 131 var response = new MemcacheSetResponse(); |
| 132 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 133 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 134 response.setStatus.add(MemcacheSetResponse_SetStatusCode.STORED); |
| 135 return new Future.value(response.writeToBuffer()); |
| 136 })); |
| 137 |
| 138 expect(memcache.setAll(setAllMap), completes); |
| 139 }); |
| 140 |
| 141 test('get', () { |
| 142 var mock = new MockRPCService('memcache'); |
| 143 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 144 |
| 145 // Tests NetworkError. |
| 146 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 147 return new Future.error(new NetworkError("")); |
| 148 })); |
| 149 expect(memcache.get('language'), throwsA(isNetworkError)); |
| 150 |
| 151 // Tests ProtocolError. |
| 152 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 153 return new Future.value(INVALID_PROTOBUF); |
| 154 })); |
| 155 expect(memcache.get('language'), throwsA(isProtocolError)); |
| 156 |
| 157 // Tests key not found. |
| 158 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 159 var response = new MemcacheGetResponse(); |
| 160 return new Future.value(response.writeToBuffer()); |
| 161 })); |
| 162 expect(memcache.get('language'), completion(isNull)); |
| 163 |
| 164 // Tests sucessfull get |
| 165 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 166 var response = new MemcacheGetResponse(); |
| 167 var item = new MemcacheGetResponse_Item(); |
| 168 item.key = UTF8.encode('language'); |
| 169 item.value = UTF8.encode('dart'); |
| 170 response.item.add(item); |
| 171 return new Future.value(response.writeToBuffer()); |
| 172 })); |
| 173 expect(memcache.get('language'), completion('dart')); |
| 174 }); |
| 175 |
| 176 test('getAll', () { |
| 177 var mock = new MockRPCService('memcache'); |
| 178 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 179 |
| 180 var key1 = 'language'; |
| 181 var key2 = UTF8.encode('language'); |
| 182 var key3 = [1, 2, 3]; |
| 183 var keys = [key1, key2, key3]; |
| 184 var nothing = {key1: null, key2: null, key3: null}; |
| 185 var success = {key1: 'dart', key2: 'dart', key3: null}; |
| 186 |
| 187 // Tests NetworkError. |
| 188 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 189 return new Future.error(new NetworkError("")); |
| 190 })); |
| 191 expect(memcache.getAll(keys), throwsA(isNetworkError)); |
| 192 |
| 193 // Tests ProtocolError. |
| 194 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 195 return new Future.value(INVALID_PROTOBUF); |
| 196 })); |
| 197 expect(memcache.getAll(keys), throwsA(isProtocolError)); |
| 198 |
| 199 // Tests key not found. |
| 200 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 201 var response = new MemcacheGetResponse(); |
| 202 return new Future.value(response.writeToBuffer()); |
| 203 })); |
| 204 expect(memcache.getAll(keys), completion(nothing)); |
| 205 |
| 206 // Tests sucessfull get. |
| 207 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 208 expect(request.key.length, 3); |
| 209 expect(request.key[0], key2); // Key2 is the UTF-8 encoding of key1. |
| 210 expect(request.key[1], key2); |
| 211 expect(request.key[2], key3); |
| 212 var response = new MemcacheGetResponse(); |
| 213 var item1 = new MemcacheGetResponse_Item(); |
| 214 item1.key = key2; // Key2 is the UTF-8 encoding of key1 |
| 215 item1.value = UTF8.encode('dart'); |
| 216 response.item.add(item1); |
| 217 var item2 = new MemcacheGetResponse_Item(); |
| 218 item2.key = key2; |
| 219 item2.value = UTF8.encode('dart'); |
| 220 response.item.add(item2); |
| 221 return new Future.value(response.writeToBuffer()); |
| 222 })); |
| 223 expect(memcache.getAll(keys), completion(success)); |
| 224 |
| 225 // Tests sucessfull get with different ordered response. |
| 226 // The result of getAll should be ordered with respect to the |
| 227 // passed in keys. |
| 228 var successWithLast = {key1: 'dart', key2: 'dart', key3: 'lastElement'}; |
| 229 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 230 expect(request.key.length, 3); |
| 231 expect(request.key[0], key2); // Key2 is the UTF-8 encoding of key1. |
| 232 expect(request.key[1], key2); |
| 233 expect(request.key[2], key3); |
| 234 // Create a response where the resulting keys are in different order. |
| 235 var response = new MemcacheGetResponse(); |
| 236 var item1 = new MemcacheGetResponse_Item(); |
| 237 item1.key = key3; |
| 238 item1.value = UTF8.encode('lastElement'); |
| 239 response.item.add(item1); |
| 240 var item2 = new MemcacheGetResponse_Item(); |
| 241 item2.key = key2; |
| 242 item2.value = UTF8.encode('dart'); |
| 243 response.item.add(item2); |
| 244 var item3 = new MemcacheGetResponse_Item(); |
| 245 item3.key = key2; // key2 is the UTF-8 encoding of key1. |
| 246 item3.value = UTF8.encode('dart'); |
| 247 response.item.add(item3); |
| 248 return new Future.value(response.writeToBuffer()); |
| 249 })); |
| 250 expect(memcache.getAll(keys), completion(successWithLast)); |
| 251 |
| 252 // Tests sucessfull get with single value response for two keys. |
| 253 // The result of getAll should be ordered with respect to the |
| 254 // passed in keys. |
| 255 var twoKeys = [key3, key1]; |
| 256 var successWithOne = {key3: null, key1: 'dart'}; |
| 257 mock.register('Get', MemcacheGetRequest, expectAsync((request) { |
| 258 expect(request.key.length, 2); |
| 259 expect(request.key[0], key3); |
| 260 expect(request.key[1], key2); // Key2 is the UTF-8 encoding of key1. |
| 261 // Create a response with only key1 (aka. key2) having a value. |
| 262 var response = new MemcacheGetResponse(); |
| 263 var item1 = new MemcacheGetResponse_Item(); |
| 264 item1.key = key2; // key is the UTF-8 encoding of key1. |
| 265 item1.value = UTF8.encode('dart'); |
| 266 response.item.add(item1); |
| 267 return new Future.value(response.writeToBuffer()); |
| 268 })); |
| 269 expect(memcache.getAll(twoKeys), completion(successWithOne)); |
| 270 }); |
| 271 |
| 272 test('remove', () { |
| 273 var mock = new MockRPCService('memcache'); |
| 274 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 275 |
| 276 // Tests NetworkError |
| 277 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 278 return new Future.error(new NetworkError("")); |
| 279 })); |
| 280 expect(memcache.remove('language'), throwsA(isNetworkError)); |
| 281 |
| 282 // Tests ProtocolError |
| 283 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 284 return new Future.value(INVALID_PROTOBUF); |
| 285 })); |
| 286 expect(memcache.remove('language'), throwsA(isProtocolError)); |
| 287 |
| 288 // Tests not found |
| 289 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 290 var response = new MemcacheDeleteResponse(); |
| 291 response.deleteStatus.add( |
| 292 MemcacheDeleteResponse_DeleteStatusCode.NOT_FOUND); |
| 293 return new Future.value(response.writeToBuffer()); |
| 294 })); |
| 295 expect(memcache.remove('language'), completes); |
| 296 |
| 297 // Tests sucessfull delete |
| 298 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 299 var response = new MemcacheDeleteResponse(); |
| 300 response.deleteStatus.add( |
| 301 MemcacheDeleteResponse_DeleteStatusCode.DELETED); |
| 302 return new Future.value(response.writeToBuffer()); |
| 303 })); |
| 304 |
| 305 expect(memcache.remove('language'), completes); |
| 306 }); |
| 307 |
| 308 test('removeAll', () { |
| 309 var mock = new MockRPCService('memcache'); |
| 310 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 311 |
| 312 var key1 = 'language'; |
| 313 var key2 = UTF8.encode('language'); |
| 314 var key3 = [1, 2, 3]; |
| 315 var keys = [key1, key2, key3]; |
| 316 |
| 317 // Tests NetworkError. |
| 318 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 319 return new Future.error(new NetworkError("")); |
| 320 })); |
| 321 expect(memcache.removeAll(keys), throwsA(isNetworkError)); |
| 322 |
| 323 // Tests ProtocolError. |
| 324 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 325 return new Future.value(INVALID_PROTOBUF); |
| 326 })); |
| 327 expect(memcache.removeAll(keys), throwsA(isProtocolError)); |
| 328 |
| 329 // Tests invalid response. |
| 330 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 331 var response = new MemcacheDeleteResponse(); |
| 332 response.deleteStatus.add( |
| 333 MemcacheDeleteResponse_DeleteStatusCode.NOT_FOUND); |
| 334 return new Future.value(response.writeToBuffer()); |
| 335 })); |
| 336 expect(memcache.removeAll(keys), throwsA(isMemcacheError)); |
| 337 |
| 338 // Tests not found. |
| 339 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 340 expect(request.item.length, 3); |
| 341 // Key2 is the UTF-8 encoding of key1. |
| 342 expect(request.item[0].key, key2); |
| 343 expect(request.item[1].key, key2); |
| 344 expect(request.item[2].key, key3); |
| 345 |
| 346 var response = new MemcacheDeleteResponse(); |
| 347 response.deleteStatus.add( |
| 348 MemcacheDeleteResponse_DeleteStatusCode.NOT_FOUND); |
| 349 response.deleteStatus.add( |
| 350 MemcacheDeleteResponse_DeleteStatusCode.NOT_FOUND); |
| 351 response.deleteStatus.add( |
| 352 MemcacheDeleteResponse_DeleteStatusCode.NOT_FOUND); |
| 353 return new Future.value(response.writeToBuffer()); |
| 354 })); |
| 355 expect(memcache.removeAll(keys), completes); |
| 356 |
| 357 // Tests sucessfull delete. |
| 358 mock.register('Delete', MemcacheDeleteRequest, expectAsync((request) { |
| 359 expect(request.item.length, 3); |
| 360 // Key2 is the UTF-8 encoding of key1. |
| 361 expect(request.item[0].key, key2); |
| 362 expect(request.item[1].key, key2); |
| 363 expect(request.item[2].key, key3); |
| 364 |
| 365 var response = new MemcacheDeleteResponse(); |
| 366 response.deleteStatus.add( |
| 367 MemcacheDeleteResponse_DeleteStatusCode.DELETED); |
| 368 response.deleteStatus.add( |
| 369 MemcacheDeleteResponse_DeleteStatusCode.DELETED); |
| 370 response.deleteStatus.add( |
| 371 MemcacheDeleteResponse_DeleteStatusCode.DELETED); |
| 372 return new Future.value(response.writeToBuffer()); |
| 373 })); |
| 374 |
| 375 expect(memcache.removeAll(keys), completes); |
| 376 }); |
| 377 |
| 378 test('increment', () { |
| 379 var key1 = 'increment'; |
| 380 var key2 = UTF8.encode(key1); |
| 381 |
| 382 var mock = new MockRPCService('memcache'); |
| 383 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 384 |
| 385 // Tests sucessfull increment. |
| 386 mock.register( |
| 387 'Increment', MemcacheIncrementRequest, expectAsync((request) { |
| 388 expect(request.key, key2); |
| 389 expect(request.delta.toInt(), 1); |
| 390 expect(request.direction, MemcacheIncrementRequest_Direction.INCREMENT); |
| 391 expect(request.initialValue.toInt(), 0); |
| 392 expect(request.initialFlags, 0); |
| 393 |
| 394 var response = new MemcacheIncrementResponse(); |
| 395 response.incrementStatus = |
| 396 MemcacheIncrementResponse_IncrementStatusCode.OK; |
| 397 response.newValue = new Int64(42); |
| 398 return new Future.value(response.writeToBuffer()); |
| 399 })); |
| 400 expect(memcache.increment(key1), completion(42)); |
| 401 }); |
| 402 |
| 403 test('decrement', () { |
| 404 var key1 = 'decrement'; |
| 405 var key2 = UTF8.encode(key1); |
| 406 |
| 407 var mock = new MockRPCService('memcache'); |
| 408 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 409 |
| 410 // Tests sucessfull decrement. |
| 411 mock.register( |
| 412 'Increment', MemcacheIncrementRequest, expectAsync((request) { |
| 413 expect(request.key, key2); |
| 414 expect(request.delta.toInt(), 1); |
| 415 expect(request.direction, MemcacheIncrementRequest_Direction.DECREMENT); |
| 416 expect(request.initialValue.toInt(), 0); |
| 417 expect(request.initialFlags, 0); |
| 418 |
| 419 var response = new MemcacheIncrementResponse(); |
| 420 response.incrementStatus = |
| 421 MemcacheIncrementResponse_IncrementStatusCode.OK; |
| 422 response.newValue = new Int64(42); |
| 423 return new Future.value(response.writeToBuffer()); |
| 424 })); |
| 425 expect(memcache.decrement(key1), completion(42)); |
| 426 }); |
| 427 |
| 428 test('increment-decrement-errors', () { |
| 429 var key1 = 'key'; |
| 430 var key2 = UTF8.encode(key1); |
| 431 |
| 432 var mock = new MockRPCService('memcache'); |
| 433 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 434 |
| 435 // Tests NetworkError. |
| 436 mock.register( |
| 437 'Increment', MemcacheIncrementRequest, expectAsync((request) { |
| 438 return new Future.error(new NetworkError("")); |
| 439 }, count: 2)); |
| 440 expect(memcache.increment(key1), throwsA(isNetworkError)); |
| 441 expect(memcache.decrement(key1), throwsA(isNetworkError)); |
| 442 |
| 443 // Tests ProtocolError. |
| 444 mock.register( |
| 445 'Increment', MemcacheIncrementRequest, expectAsync((request) { |
| 446 return new Future.value(INVALID_PROTOBUF); |
| 447 }, count: 2)); |
| 448 expect(memcache.increment(key1), throwsA(isProtocolError)); |
| 449 expect(memcache.decrement(key1), throwsA(isProtocolError)); |
| 450 |
| 451 // Tests error response. |
| 452 mock.register( |
| 453 'Increment', MemcacheIncrementRequest, expectAsync((request) { |
| 454 var response = new MemcacheIncrementResponse(); |
| 455 response.incrementStatus = |
| 456 MemcacheIncrementResponse_IncrementStatusCode.ERROR; |
| 457 return new Future.value(response.writeToBuffer()); |
| 458 }, count: 2)); |
| 459 expect(memcache.increment(key1), throwsA(isMemcacheError)); |
| 460 expect(memcache.decrement(key1), throwsA(isMemcacheError)); |
| 461 }); |
| 462 |
| 463 test('clear', () { |
| 464 var mock = new MockRPCService('memcache'); |
| 465 var memcache = new MemCacheImpl(new RawMemcacheRpcImpl(mock, '')); |
| 466 |
| 467 // Tests NetworkError |
| 468 mock.register('FlushAll', MemcacheFlushRequest, expectAsync((request) { |
| 469 return new Future.error(new NetworkError("")); |
| 470 })); |
| 471 expect(memcache.clear(), throwsA(isNetworkError)); |
| 472 |
| 473 // Tests ProtocolError |
| 474 mock.register('FlushAll', MemcacheFlushRequest, expectAsync((request) { |
| 475 return new Future.value(INVALID_PROTOBUF); |
| 476 })); |
| 477 expect(memcache.clear(), throwsA(isProtocolError)); |
| 478 |
| 479 // Tests sucessfull clear |
| 480 mock.register('FlushAll', MemcacheFlushRequest, expectAsync((request) { |
| 481 return new Future.value(new MemcacheFlushResponse().writeToBuffer()); |
| 482 })); |
| 483 |
| 484 expect(memcache.clear(), completes); |
| 485 }); |
| 486 }); |
| 487 } |
OLD | NEW |