blockstore: tests and fixes for blockstore error cases
This commit is contained in:
parent
0f0cb00c54
commit
747a8e707b
@ -47,6 +47,9 @@ class FileBlockStore extends AbstractBlockStore {
|
|||||||
|
|
||||||
this.maxFileLength = options.maxFileLength || 128 * 1024 * 1024;
|
this.maxFileLength = options.maxFileLength || 128 * 1024 * 1024;
|
||||||
|
|
||||||
|
assert(Number.isSafeInteger(this.maxFileLength),
|
||||||
|
'Invalid max file length.');
|
||||||
|
|
||||||
this.network = Network.primary;
|
this.network = Network.primary;
|
||||||
|
|
||||||
if (options.network != null)
|
if (options.network != null)
|
||||||
@ -319,11 +322,15 @@ class FileBlockStore extends AbstractBlockStore {
|
|||||||
|
|
||||||
await fs.close(fd);
|
await fs.close(fd);
|
||||||
|
|
||||||
if (mwritten !== mlength)
|
if (mwritten !== mlength) {
|
||||||
|
this.writing = false;
|
||||||
throw new Error('Could not write block magic.');
|
throw new Error('Could not write block magic.');
|
||||||
|
}
|
||||||
|
|
||||||
if (bwritten !== blength)
|
if (bwritten !== blength) {
|
||||||
|
this.writing = false;
|
||||||
throw new Error('Could not write block.');
|
throw new Error('Could not write block.');
|
||||||
|
}
|
||||||
|
|
||||||
filerecord.blocks += 1;
|
filerecord.blocks += 1;
|
||||||
filerecord.used += length;
|
filerecord.used += length;
|
||||||
|
|||||||
@ -64,8 +64,9 @@ describe('BlockStore', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('has unimplemented base methods', async () => {
|
it('has unimplemented base methods', async () => {
|
||||||
const methods = ['open', 'close', 'write', 'read',
|
const methods = ['open', 'close', 'write', 'writeUndo',
|
||||||
'prune', 'has'];
|
'read', 'readUndo', 'prune', 'pruneUndo',
|
||||||
|
'has', 'hasUndo', 'ensure'];
|
||||||
|
|
||||||
const store = new AbstractBlockStore();
|
const store = new AbstractBlockStore();
|
||||||
|
|
||||||
@ -277,6 +278,40 @@ describe('BlockStore', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('constructor', function() {
|
||||||
|
it('will error with invalid location', () => {
|
||||||
|
let err = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
new FileBlockStore({
|
||||||
|
location: 'tmp/.bcoin/blocks',
|
||||||
|
maxFileLength: 1024
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(err);
|
||||||
|
assert.equal(err.message, 'Location not absolute.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will error with invalid max file length', () => {
|
||||||
|
let err = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
new FileBlockStore({
|
||||||
|
location: location,
|
||||||
|
maxFileLength: 'notanumber'
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(err);
|
||||||
|
assert.equal(err.message, 'Invalid max file length.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('allocate', function() {
|
describe('allocate', function() {
|
||||||
it('will fail with length above file max', async () => {
|
it('will fail with length above file max', async () => {
|
||||||
let err = null;
|
let err = null;
|
||||||
@ -337,6 +372,103 @@ describe('BlockStore', function() {
|
|||||||
const filepath = store.filepath(types.UNDO, 99999);
|
const filepath = store.filepath(types.UNDO, 99999);
|
||||||
assert.equal(filepath, '/tmp/.bcoin/blocks/blu99999.dat');
|
assert.equal(filepath, '/tmp/.bcoin/blocks/blu99999.dat');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('will fail for unknown prefix', () => {
|
||||||
|
let err = null;
|
||||||
|
try {
|
||||||
|
store.filepath(0, 1234);
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(err);
|
||||||
|
assert.equal(err.message, 'Unknown file prefix.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('write', function() {
|
||||||
|
const write = fs.write;
|
||||||
|
const open = fs.open;
|
||||||
|
const close = fs.close;
|
||||||
|
let allocate = null;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
allocate = store.allocate;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// Restore stubbed methods.
|
||||||
|
fs.write = write;
|
||||||
|
fs.open = open;
|
||||||
|
fs.close = close;
|
||||||
|
store.allocate = allocate;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will error if total magic bytes not written', async () => {
|
||||||
|
let err = null;
|
||||||
|
|
||||||
|
store.allocate = () => {
|
||||||
|
return {
|
||||||
|
fileno: 20,
|
||||||
|
filerecord: {
|
||||||
|
used: 0
|
||||||
|
},
|
||||||
|
filepath: '/tmp/.bcoin/blocks/blk00020.dat'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fs.open = () => 7;
|
||||||
|
fs.close = () => undefined;
|
||||||
|
fs.write = () => 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const hash = random.randomBytes(128);
|
||||||
|
const block = random.randomBytes(32);
|
||||||
|
await store.write(hash, block);
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(err, 'Expected error.');
|
||||||
|
assert.equal(err.message, 'Could not write block magic.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will error if total block bytes not written', async () => {
|
||||||
|
let err = 0;
|
||||||
|
|
||||||
|
let called = 0;
|
||||||
|
store.allocate = () => {
|
||||||
|
return {
|
||||||
|
fileno: 20,
|
||||||
|
filerecord: {
|
||||||
|
used: 0
|
||||||
|
},
|
||||||
|
filepath: '/tmp/.bcoin/blocks/blk00020.dat'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fs.open = () => 7;
|
||||||
|
fs.close = () => undefined;
|
||||||
|
fs.write = (fd, buffer, offset, length, position) => {
|
||||||
|
let written = 0;
|
||||||
|
|
||||||
|
if (called === 0)
|
||||||
|
written = length;
|
||||||
|
|
||||||
|
called += 1;
|
||||||
|
|
||||||
|
return written;
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const hash = random.randomBytes(128);
|
||||||
|
const block = random.randomBytes(32);
|
||||||
|
await store.write(hash, block);
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(err, 'Expected error.');
|
||||||
|
assert.equal(err.message, 'Could not write block.');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user