The JavaScript Database, for Node.js, nw.js, electron and the browser
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nedb/test_lac/loadAndCrash.test.js

122 lines
3.3 KiB

/* eslint-env mocha */
/* global DEBUG */
/**
* Load and modify part of fs to ensure writeFile will crash after writing 5000 bytes
*/
const fs = require('fs')
function rethrow () {
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
// is fairly slow to generate.
if (DEBUG) {
const backtrace = new Error()
return function (err) {
if (err) {
backtrace.stack = err.name + ': ' + err.message +
backtrace.stack.substr(backtrace.name.length)
throw backtrace
}
}
}
return function (err) {
if (err) {
throw err // Forgot a callback but don't know where? Use NODE_DEBUG=fs
}
}
}
function maybeCallback (cb) {
return typeof cb === 'function' ? cb : rethrow()
}
function isFd (path) {
return (path >>> 0) === path
}
function assertEncoding (encoding) {
if (encoding && !Buffer.isEncoding(encoding)) {
throw new Error('Unknown encoding: ' + encoding)
}
}
let onePassDone = false
function writeAll (fd, isUserFd, buffer, offset, length, position, callback_) {
const callback = maybeCallback(arguments[arguments.length - 1])
if (onePassDone) { process.exit(1) } // Crash on purpose before rewrite done
const l = Math.min(5000, length) // Force write by chunks of 5000 bytes to ensure data will be incomplete on crash
// write(fd, buffer, offset, length, position, callback)
fs.write(fd, buffer, offset, l, position, function (writeErr, written) {
if (writeErr) {
if (isUserFd) {
if (callback) callback(writeErr)
} else {
fs.close(fd, function () {
if (callback) callback(writeErr)
})
}
} else {
onePassDone = true
if (written === length) {
if (isUserFd) {
if (callback) callback(null)
} else {
fs.close(fd, callback)
}
} else {
offset += written
length -= written
if (position !== null) {
position += written
}
writeAll(fd, isUserFd, buffer, offset, length, position, callback)
}
}
})
}
fs.writeFile = function (path, data, options, callback_) {
const callback = maybeCallback(arguments[arguments.length - 1])
if (!options || typeof options === 'function') {
options = { encoding: 'utf8', mode: 438, flag: 'w' } // Mode 438 == 0o666 (compatibility with older Node releases)
} else if (typeof options === 'string') {
options = { encoding: options, mode: 438, flag: 'w' } // Mode 438 == 0o666 (compatibility with older Node releases)
} else if (typeof options !== 'object') {
throw new Error(`throwOptionsError${options}`)
}
assertEncoding(options.encoding)
const flag = options.flag || 'w'
if (isFd(path)) {
writeFd(path, true)
return
}
fs.open(path, flag, options.mode, function (openErr, fd) {
if (openErr) {
if (callback) callback(openErr)
} else {
writeFd(fd, false)
}
})
function writeFd (fd, isUserFd) {
const buffer = (data instanceof Buffer) ? data : Buffer.from('' + data, options.encoding || 'utf8')
const position = /a/.test(flag) ? null : 0
writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback)
}
}
// End of fs modification
const Nedb = require('../lib/datastore.js')
const db = new Nedb({ filename: 'workspace/lac.db' })
db.loadDatabase()