Skip to content

Commit 959a821

Browse files
authored
Merge pull request #1144 from strongloop/feature/parameterize-kvao-tests-2x
test/kvao: add connectorCapabilities options [2.x]
2 parents 459fc93 + 70a1552 commit 959a821

File tree

7 files changed

+83
-26
lines changed

7 files changed

+83
-26
lines changed

test/helpers/bdd-if.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright IBM Corp. 2016. All Rights Reserved.
2+
// Node module: loopback-datasource-juggler
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
'use strict';
6+
7+
exports.describeIf = function describeIf(cond, name, fn) {
8+
if (cond)
9+
describe(name, fn);
10+
else
11+
describe.skip(name, fn);
12+
};
13+
14+
exports.itIf = function itIf(cond, name, fn) {
15+
if (cond)
16+
it(name, fn);
17+
else
18+
it.skip(name, fn);
19+
};

test/kvao.suite.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
'use strict';
22

33
var debug = require('debug')('test');
4+
var extend = require('util')._extend;
45
var fs = require('fs');
56
var path = require('path');
67

78
if (!global.Promise)
89
global.Promise = require('bluebird');
910

1011
module.exports = function(dataSourceFactory, connectorCapabilities) {
12+
connectorCapabilities = extend({
13+
// Even when the backend supports millisecond precision,
14+
// it's better to use intervals at least 10ms long in the tests
15+
ttlPrecision: 10,
16+
}, connectorCapabilities);
17+
1118
describe('KeyValue API', function loadAllTestFiles() {
1219
var testRoot = path.resolve(__dirname, 'kvao');
1320
var testFiles = fs.readdirSync(testRoot);

test/kvao/expire.suite.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
'use strict';
22

3+
var bdd = require('../helpers/bdd-if');
34
var should = require('should');
45
var helpers = require('./_helpers');
56
var Promise = require('bluebird');
67

78
module.exports = function(dataSourceFactory, connectorCapabilities) {
8-
describe('expire', function() {
9+
// While we support millisecond precision, for the purpose of tests
10+
// it's better to use intervals at least 10ms long.
11+
var ttlPrecision = connectorCapabilities.ttlPrecision || 10;
12+
13+
var canExpire = connectorCapabilities.canExpire !== false;
14+
15+
bdd.describeIf(canExpire, 'expire', function() {
916
var CacheItem;
1017
beforeEach(function unpackContext() {
1118
CacheItem = helpers.givenCacheItem(dataSourceFactory);
@@ -14,30 +21,30 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
1421
it('sets key ttl - Callback API', function(done) {
1522
CacheItem.set('a-key', 'a-value', function(err) {
1623
if (err) return done(err);
17-
CacheItem.expire('a-key', 1, function(err) {
24+
CacheItem.expire('a-key', ttlPrecision, function(err) {
1825
if (err) return done(err);
1926
setTimeout(function() {
2027
CacheItem.get('a-key', function(err, value) {
2128
if (err) return done(err);
2229
should.equal(value, null);
2330
done();
2431
});
25-
}, 20);
32+
}, 2 * ttlPrecision);
2633
});
2734
});
2835
});
2936

3037
it('sets key ttl - Promise API', function() {
3138
return Promise.resolve(CacheItem.set('a-key', 'a-value'))
32-
.then(function() { return CacheItem.expire('a-key', 1); })
33-
.delay(20)
39+
.then(function() { return CacheItem.expire('a-key', ttlPrecision); })
40+
.delay(2 * ttlPrecision)
3441
.then(function() { return CacheItem.get('a-key'); })
3542
.then(function(value) { should.equal(value, null); });
3643
});
3744

3845
it('returns error when expiring a key that has expired', function() {
39-
return Promise.resolve(CacheItem.set('expired-key', 'a-value', 1))
40-
.delay(20)
46+
return Promise.resolve(CacheItem.set('expired-key', 'a-value', ttlPrecision))
47+
.delay(2 * ttlPrecision)
4148
.then(function() { return CacheItem.expire('expired-key', 1000); })
4249
.then(
4350
function() { throw new Error('expire() should have failed'); },
@@ -48,7 +55,7 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
4855
});
4956

5057
it('returns error when key does not exist', function() {
51-
return CacheItem.expire('key-does-not-exist', 1).then(
58+
return CacheItem.expire('key-does-not-exist', ttlPrecision).then(
5259
function() { throw new Error('expire() should have failed'); },
5360
function(err) {
5461
err.message.should.match(/key-does-not-exist/);

test/kvao/get-set.suite.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ var helpers = require('./_helpers');
55
var Promise = require('bluebird');
66

77
module.exports = function(dataSourceFactory, connectorCapabilities) {
8+
var TTL_PRECISION = connectorCapabilities.ttlPrecision;
9+
810
describe('get/set', function() {
911
var CacheItem;
1012
beforeEach(function unpackContext() {
@@ -68,8 +70,8 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
6870
});
6971

7072
it('honours options.ttl', function() {
71-
return Promise.resolve(CacheItem.set('a-key', 'a-value', { ttl: 10 }))
72-
.delay(20)
73+
return Promise.resolve(CacheItem.set('a-key', 'a-value', { ttl: TTL_PRECISION }))
74+
.delay(2 * TTL_PRECISION)
7375
.then(function() { return CacheItem.get('a-key'); })
7476
.then(function(value) { should.equal(value, null); });
7577
});
@@ -79,22 +81,22 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
7981
return CacheItem.get('key-does-not-exist')
8082
.then(function(value) { should.equal(value, null); });
8183
});
84+
});
8285

86+
describe('set', function() {
8387
it('converts numeric options arg to options.ttl', function() {
84-
return Promise.resolve(CacheItem.set('a-key', 'a-value', 10))
85-
.delay(20)
88+
return Promise.resolve(CacheItem.set('a-key', 'a-value', TTL_PRECISION))
89+
.delay(2 * TTL_PRECISION)
8690
.then(function() { return CacheItem.get('a-key'); })
8791
.then(function(value) { should.equal(value, null); });
8892
});
89-
});
9093

91-
describe('set', function() {
9294
it('resets TTL timer', function() {
93-
return Promise.resolve(CacheItem.set('a-key', 'a-value', { ttl: 10 }))
95+
return Promise.resolve(CacheItem.set('a-key', 'a-value', { ttl: TTL_PRECISION }))
9496
.then(function() {
9597
return CacheItem.set('a-key', 'another-value'); // no TTL
9698
})
97-
.delay(20)
99+
.delay(2 * TTL_PRECISION)
98100
.then(function() { return CacheItem.get('a-key'); })
99101
.then(function(value) { should.equal(value, 'another-value'); });
100102
});

test/kvao/iterate-keys.suite.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
'use strict';
22

33
var asyncIterators = require('async-iterators');
4+
var bdd = require('../helpers/bdd-if');
45
var helpers = require('./_helpers');
56
var Promise = require('bluebird');
67
var should = require('should');
78
var toArray = Promise.promisify(asyncIterators.toArray);
89

910
module.exports = function(dataSourceFactory, connectorCapabilities) {
10-
describe('iterateKeys', function() {
11+
var canIterateKeys = connectorCapabilities.canIterateKeys !== false;
12+
13+
bdd.describeIf(canIterateKeys, 'iterateKeys', function() {
1114
var CacheItem;
1215
beforeEach(function unpackContext() {
1316
CacheItem = helpers.givenCacheItem(dataSourceFactory);

test/kvao/keys.suite.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
'use strict';
22

3+
var bdd = require('../helpers/bdd-if');
34
var helpers = require('./_helpers');
45
var Promise = require('bluebird');
56
var should = require('should');
67

78
module.exports = function(dataSourceFactory, connectorCapabilities) {
8-
describe('keys', function() {
9+
var canIterateKeys = connectorCapabilities.canIterateKeys !== false;
10+
11+
bdd.describeIf(canIterateKeys, 'keys', function() {
912
var CacheItem;
1013
beforeEach(function unpackContext() {
1114
CacheItem = helpers.givenCacheItem(dataSourceFactory);
@@ -54,7 +57,8 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
5457
});
5558
});
5659

57-
it('handles large key set', function() {
60+
var largeKeySets = connectorCapabilities.canIterateLargeKeySets !== false;
61+
bdd.itIf(largeKeySets, 'handles large key set', function() {
5862
var expectedKeys = [];
5963
for (var ix = 0; ix < 1000; ix++)
6064
expectedKeys.push('key-' + ix);

test/kvao/ttl.suite.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
'use strict';
22

3+
var bdd = require('../helpers/bdd-if');
34
var should = require('should');
45
var helpers = require('./_helpers');
56
var Promise = require('bluebird');
67

78
module.exports = function(dataSourceFactory, connectorCapabilities) {
8-
describe('ttl', function() {
9+
var TTL_PRECISION = connectorCapabilities.ttlPrecision;
10+
11+
// Use ~1s for stores with precision of 1 ms,
12+
// about 3s for stores with precision of 1s.
13+
var INITIAL_TTL = Math.max(TTL_PRECISION + 1000, TTL_PRECISION * 3);
14+
15+
// A small delay to allow the backend to process the request, run any
16+
// TTL/expire checks, etc. Use 1ms for backends supporting sub-10ms
17+
// resolution to ensure the delay is not too short..
18+
var SMALL_DELAY = Math.max(1, Math.floor(TTL_PRECISION / 10));
19+
20+
var canQueryTtl = connectorCapabilities.canQueryTtl !== false;
21+
22+
bdd.describeIf(canQueryTtl, 'ttl', function() {
923
var CacheItem;
1024
beforeEach(function unpackContext() {
1125
CacheItem = helpers.givenCacheItem(dataSourceFactory);
@@ -14,19 +28,19 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
1428
it('gets TTL when key with unexpired TTL exists - Promise API',
1529
function() {
1630
return Promise.resolve(
17-
CacheItem.set('a-key', 'a-value', { ttl: 1000 }))
18-
.delay(1)
31+
CacheItem.set('a-key', 'a-value', { ttl: INITIAL_TTL }))
32+
.delay(SMALL_DELAY)
1933
.then(function() { return CacheItem.ttl('a-key'); })
20-
.then(function(ttl) { ttl.should.be.within(1, 1000); });
34+
.then(function(ttl) { ttl.should.be.within(1, INITIAL_TTL); });
2135
});
2236

2337
it('gets TTL when key with unexpired TTL exists - Callback API',
2438
function(done) {
25-
CacheItem.set('a-key', 'a-value', { ttl: 1000 }, function(err) {
39+
CacheItem.set('a-key', 'a-value', { ttl: INITIAL_TTL }, function(err) {
2640
if (err) return done(err);
2741
CacheItem.ttl('a-key', function(err, ttl) {
2842
if (err) return done(err);
29-
ttl.should.be.within(1, 1000);
43+
ttl.should.be.within(1, INITIAL_TTL);
3044
done();
3145
});
3246
});
@@ -40,7 +54,8 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
4054

4155
it('fails when getting TTL for a key with expired TTL', function() {
4256
return Promise.resolve(
43-
CacheItem.set('expired-key', 'a-value', { ttl: 10 })).delay(20)
57+
CacheItem.set('expired-key', 'a-value', { ttl: TTL_PRECISION }))
58+
.delay(2 * TTL_PRECISION)
4459
.then(function() {
4560
return CacheItem.ttl('expired-key');
4661
})

0 commit comments

Comments
 (0)