Skip to content

Commit

Permalink
Create DBUpgrade Fail Tests
Browse files Browse the repository at this point in the history
Create tests to show that DBEngine should not open unless it has
the correct version.

Issue #1230
Issue #1248

Change-Id: I410e1c5d35a3a7b9e91afdd247f06ffac8d5a86d
  • Loading branch information
vaage authored and joeyparrish committed Jan 30, 2018
1 parent 9c2ba23 commit cf5ed33
Show file tree
Hide file tree
Showing 2 changed files with 296 additions and 130 deletions.
299 changes: 169 additions & 130 deletions test/offline/db_engine_unit.js
Expand Up @@ -16,184 +16,223 @@
*/

describe('DBEngine', function() {
const UNSUPPORTED_UPGRADE_REQUEST =
shaka.util.Error.Code.UNSUPPORTED_UPGRADE_REQUEST;

const OfflineUtils = shaka.test.OfflineUtils;

/** @const {string} */
var dbName = 'shaka-player-test-db';

/** @const {number} */
var dbUpdateRetries = 5;

/** @type {!shaka.offline.DBEngine} */
var db;

beforeEach(function(done) {
if (shaka.offline.DBEngine.isSupported()) {
shaka.offline.DBEngine.deleteDatabase(dbName).then(function() {
db = new shaka.offline.DBEngine(dbName);
return db.init(dbUpdateRetries);
}).catch(fail).then(done);
} else {
done();
}
});
const dbName = 'shaka-player-test-db';

function deleteOld() {
return shaka.offline.DBEngine.deleteDatabase(dbName);
}

function openDB() {
const dbUpdateRetries = 5;
let db = new shaka.offline.DBEngine(dbName);
return db.init(dbUpdateRetries)
.then(() => db)
.catch((e) => {
// Make sure that if there is an error, that the db engine is
// destroyed or else we may not be able to delete it later.
return db.destroy().then(() => { throw e; });
});
}

afterEach(function(done) {
if (shaka.offline.DBEngine.isSupported()) {
db.destroy().catch(fail).then(done);
} else {
done();
}
describe('upgrade failures', function() {
it('fails to open with old version', checkAndRun((done) => {
// Create a mock old database with the manifest tables.
deleteOld()
.then(() => {
return shaka.test.SimpleIDB.open(dbName, 1, []);
})
.then((sdb) => sdb.close())
.then(openDB)
// We expect a failure because the other database should keep the db
// engine from starting easily.
.then(fail)
.catch((e) => {
expect(e.code).toBe(UNSUPPORTED_UPGRADE_REQUEST);
done();
});
}));

it('opens if we delete the old database', checkAndRun((done) => {
// Create a mock old database with the manifest table.
deleteOld()
.then(() => {
return shaka.test.SimpleIDB.open(dbName, 1, ['manifest']);
})
.then((sdb) => sdb.close())
.then(openDB)
// We expect a failure because the other database should keep the db
// engine from starting easily.
.then(fail)
.catch((e) => {
expect(e.code).toBe(UNSUPPORTED_UPGRADE_REQUEST);
})
.then(deleteOld)
.then(openDB)
// We should have been able to open the database as we deleted the
// old version.
.then((db) => db.destroy())
.catch(fail)
.then(done);
}));

it('can add to database after delete', checkAndRun((done) => {
const manifest = OfflineUtils.createManifest('original manifest');

// Create a mock old database with the manifest table.
deleteOld()
.then(() => {
return shaka.test.SimpleIDB.open(dbName, 1, ['manifest']);
})
.then((sdb) => sdb.close())
.then(openDB)
// We expect a failure because the other database should keep the db
// engine from starting easily.
.then(fail)
.catch((e) => {
expect(e.code).toBe(UNSUPPORTED_UPGRADE_REQUEST);
})
.then(deleteOld)
.then(openDB)
// We should have been able to open the database as we deleted the
// old version.
.then((db) => {
return db.addManifest(manifest).then(() => db.destroy());
})
.catch(fail)
.then(done);
}));
});

it('stores and retrieves a manifest', checkAndRun(function(done) {
/** @type {shakaExtern.ManifestDB} */
var original = shaka.test.OfflineUtils.createManifest('original manifest');

Promise.resolve()
.then(function() {
return db.addManifest(original);
})
.then(function(id) {
return db.getManifest(id);
})
.then(function(copy) {
expect(copy).toEqual(original);
})
.then(done).catch(fail);
var original = OfflineUtils.createManifest('original manifest');

deleteOld().then(openDB).then((db) => {
return db.addManifest(original)
.then((id) => db.getManifest(id))
.then((copy) => {
expect(copy).toEqual(original);
return db.destroy();
});
}).catch(fail).then(done);
}));

it('stores and retrieves many manifest', checkAndRun(function(done) {
/** @type {!Array<shakaExtern.ManifestDB>} */
var originals = [
shaka.test.OfflineUtils.createManifest('original manifest 1'),
shaka.test.OfflineUtils.createManifest('original manifest 2'),
shaka.test.OfflineUtils.createManifest('original manifest 3'),
shaka.test.OfflineUtils.createManifest('original manifest 4')
OfflineUtils.createManifest('original manifest 1'),
OfflineUtils.createManifest('original manifest 2'),
OfflineUtils.createManifest('original manifest 3'),
OfflineUtils.createManifest('original manifest 4')
];

/** @type {!Array<shakaExtern.ManifestDB>} */
var copies = [];

Promise.resolve()
.then(function() {
return Promise.all(originals.map(function(original) {
return db.addManifest(original);
}));
})
.then(function() {
return db.forEachManifest(function(id, manifest) {
copies.push(manifest);
deleteOld().then(openDB).then((db) => {
return Promise.all(originals.map((original) => db.addManifest(original)))
.then(() => {
return db.forEachManifest((id, manifest) => copies.push(manifest));
})
.then(() => {
originals.forEach((original) => expect(copies).toContain(original));
return db.destroy();
});
})
.then(function() {
originals.forEach(function(original) {
expect(copies).toContain(original);
});
})
.then(done).catch(fail);
}).catch(fail).then(done);
}));

it('stores and removes a manifest', checkAndRun(function(done) {
/** @type {shakaExtern.ManifestDB} */
var original = shaka.test.OfflineUtils.createManifest('original manifest');
var original = OfflineUtils.createManifest('original manifest');

/** @type {number} */
var id;

Promise.resolve()
.then(function() {
return db.addManifest(original);
})
.then(function(newId) {
id = newId;
return db.getManifest(id);
})
.then(function(value) {
expect(value).toEqual(original);
return db.removeManifests([id], null);
})
.then(function() {
return db.getManifest(id);
})
.then(function(copy) {
expect(copy).toBeFalsy();
})
.then(done).catch(fail);
deleteOld().then(openDB).then((db) => {
return db.addManifest(original)
.then((newId) => {
id = newId;
return db.getManifest(id);
})
.then((value) => {
expect(value).toEqual(original);
return db.removeManifests([id], null);
})
.then(() => {
return db.getManifest(id);
})
.then((copy) => {
expect(copy).toBeFalsy();
return db.destroy();
});
}).catch(fail).then(done);
}));

it('stores and retrieves a segment', checkAndRun(function(done) {
/** @type {shakaExtern.SegmentDataDB} */
var original = shaka.test.OfflineUtils.createSegmentData([0, 1, 2]);

Promise.resolve()
.then(function() {
return db.addSegment(original);
})
.then(function(id) {
return db.getSegment(id);
})
.then(function(copy) {
shaka.test.OfflineUtils.expectSegmentToEqual(copy, original);
})
.then(done).catch(fail);
var original = OfflineUtils.createSegmentData([0, 1, 2]);

deleteOld().then(openDB).then((db) => {
return db.addSegment(original)
.then((id) => db.getSegment(id))
.then((copy) => OfflineUtils.expectSegmentToEqual(copy, original))
.then(() => db.destroy());
}).catch(fail).then(done);
}));

it('stores and retrieves many segments', checkAndRun(function(done) {
/** @type {!Array<shakaExtern.SegmentDataDB>} */
var originals = [
shaka.test.OfflineUtils.createSegmentData([0]),
shaka.test.OfflineUtils.createSegmentData([1, 2]),
shaka.test.OfflineUtils.createSegmentData([3, 4, 5]),
shaka.test.OfflineUtils.createSegmentData([6, 7, 8, 9])
OfflineUtils.createSegmentData([0]),
OfflineUtils.createSegmentData([1, 2]),
OfflineUtils.createSegmentData([3, 4, 5]),
OfflineUtils.createSegmentData([6, 7, 8, 9])
];

/** @type {!Array<shakaExtern.SegmentDataDB>} */
var copies = [];

Promise.resolve()
.then(function() {
return Promise.all(originals.map(function(original) {
return db.addSegment(original);
deleteOld().then(openDB).then((db) => {
return Promise.all(originals.map((original) => db.addSegment(original)))
.then(() => db.forEachSegment((id, segment) => copies.push(segment)))
.then(() => originals.forEach((original) => {
OfflineUtils.expectSegmentsToContain(copies, original);
return db.destroy();
}));
})
.then(function() {
return db.forEachSegment(function(id, segment) {
copies.push(segment);
});
})
.then(function() {
originals.forEach(function(original) {
shaka.test.OfflineUtils.expectSegmentsToContain(copies, original);
});
})
.then(done).catch(fail);
}).catch(fail).then(done);
}));

it('stores and removes a segment', checkAndRun(function(done) {
/** @type {shakaExtern.SegmentDataDB} */
var original = shaka.test.OfflineUtils.createSegmentData([0, 1, 2]);
var original = OfflineUtils.createSegmentData([0, 1, 2]);

/** @type {number} */
var id;

Promise.resolve()
.then(function() {
return db.addSegment(original);
})
.then(function(newId) {
id = newId;
return db.getSegment(id);
})
.then(function(value) {
shaka.test.OfflineUtils.expectSegmentToEqual(value, original);
return db.removeSegments([id], null);
})
.then(function() {
return db.getSegment(id);
})
.then(function(copy) {
expect(copy).toBeFalsy();
})
.then(done).catch(fail);
deleteOld().then(openDB).then((db) => {
return db.addSegment(original)
.then((newId) => {
id = newId;
return db.getSegment(id);
})
.then((value) => {
OfflineUtils.expectSegmentToEqual(value, original);
return db.removeSegments([id], null);
})
.then(() => {
return db.getSegment(id);
})
.then((copy) => {
expect(copy).toBeFalsy();
return db.destroy();
});
}).catch(fail).then(done);
}));

/**
Expand Down

0 comments on commit cf5ed33

Please sign in to comment.