@ -554,16 +554,16 @@ describe('Persistence', function () {
var p = new Persistence ( { db : { inMemoryOnly : false , filename : 'workspace/it.db' } } ) ;
var p = new Persistence ( { db : { inMemoryOnly : false , filename : 'workspace/it.db' } } ) ;
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db~~ ' ) ) { fs . unlinkSync ( 'workspace/it.db~ ~' ) ; }
if ( fs . existsSync ( 'workspace/it.db~' ) ) { fs . unlinkSync ( 'workspace/it.db~' ) ; }
fs . existsSync ( 'workspace/it.db' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( false ) ;
storage . ensureDatafileIntegrity ( p . filename , function ( err ) {
storage . ensureDatafileIntegrity ( p . filename , function ( err ) {
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( false ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( '' ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( '' ) ;
@ -575,18 +575,18 @@ describe('Persistence', function () {
var p = new Persistence ( { db : { inMemoryOnly : false , filename : 'workspace/it.db' } } ) ;
var p = new Persistence ( { db : { inMemoryOnly : false , filename : 'workspace/it.db' } } ) ;
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db~~ ' ) ) { fs . unlinkSync ( 'workspace/it.db~ ~' ) ; }
if ( fs . existsSync ( 'workspace/it.db~' ) ) { fs . unlinkSync ( 'workspace/it.db~' ) ; }
fs . writeFileSync ( 'workspace/it.db' , 'something' , 'utf8' ) ;
fs . writeFileSync ( 'workspace/it.db' , 'something' , 'utf8' ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( false ) ;
storage . ensureDatafileIntegrity ( p . filename , function ( err ) {
storage . ensureDatafileIntegrity ( p . filename , function ( err ) {
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( false ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( 'something' ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( 'something' ) ;
@ -594,22 +594,22 @@ describe('Persistence', function () {
} ) ;
} ) ;
} ) ;
} ) ;
it ( 'If old datafile exists and datafile doesnt, ensureDatafileIntegrity will use it' , function ( done ) {
it ( 'If temp datafile exists and datafile doesnt, ensureDatafileIntegrity will use it (cannot happen except upon first use) ' , function ( done ) {
var p = new Persistence ( { db : { inMemoryOnly : false , filename : 'workspace/it.db' } } ) ;
var p = new Persistence ( { db : { inMemoryOnly : false , filename : 'workspace/it.db' } } ) ;
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db~~ ' ) ) { fs . unlinkSync ( 'workspace/it.db~~' ) ; }
if ( fs . existsSync ( 'workspace/it.db~' ) ) { fs . unlinkSync ( 'workspace/it.db~~' ) ; }
fs . writeFileSync ( 'workspace/it.db~~ ' , 'something' , 'utf8' ) ;
fs . writeFileSync ( 'workspace/it.db~' , 'something' , 'utf8' ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( true ) ;
storage . ensureDatafileIntegrity ( p . filename , function ( err ) {
storage . ensureDatafileIntegrity ( p . filename , function ( err ) {
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( false ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( false ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( 'something' ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( 'something' ) ;
@ -617,23 +617,24 @@ describe('Persistence', function () {
} ) ;
} ) ;
} ) ;
} ) ;
it ( 'If both old and current datafiles exist, ensureDatafileIntegrity will use the datafile, it means step 4 of persistence failed' , function ( done ) {
// Technically it could also mean the write was successful but the rename wasn't, but there is in any case no guarantee that the data in the temp file is whole so we have to discard the whole file
it ( 'If both temp and current datafiles exist, ensureDatafileIntegrity will use the datafile, as it means that the write of the temp file failed' , function ( done ) {
var theDb = new Datastore ( { filename : 'workspace/it.db' } ) ;
var theDb = new Datastore ( { filename : 'workspace/it.db' } ) ;
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db' ) ) { fs . unlinkSync ( 'workspace/it.db' ) ; }
if ( fs . existsSync ( 'workspace/it.db~~ ' ) ) { fs . unlinkSync ( 'workspace/it.db~ ~' ) ; }
if ( fs . existsSync ( 'workspace/it.db~' ) ) { fs . unlinkSync ( 'workspace/it.db~' ) ; }
fs . writeFileSync ( 'workspace/it.db' , '{"_id":"0","hello":"world"}' , 'utf8' ) ;
fs . writeFileSync ( 'workspace/it.db' , '{"_id":"0","hello":"world"}' , 'utf8' ) ;
fs . writeFileSync ( 'workspace/it.db~~ ' , '{"_id":"0","hello":"other"}' , 'utf8' ) ;
fs . writeFileSync ( 'workspace/it.db~' , '{"_id":"0","hello":"other"}' , 'utf8' ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( true ) ;
storage . ensureDatafileIntegrity ( theDb . persistence . filename , function ( err ) {
storage . ensureDatafileIntegrity ( theDb . persistence . filename , function ( err ) {
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~~ ' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( true ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( '{"_id":"0","hello":"world"}' ) ;
fs . readFileSync ( 'workspace/it.db' , 'utf8' ) . should . equal ( '{"_id":"0","hello":"world"}' ) ;
@ -643,6 +644,8 @@ describe('Persistence', function () {
assert . isNull ( err ) ;
assert . isNull ( err ) ;
docs . length . should . equal ( 1 ) ;
docs . length . should . equal ( 1 ) ;
docs [ 0 ] . hello . should . equal ( "world" ) ;
docs [ 0 ] . hello . should . equal ( "world" ) ;
fs . existsSync ( 'workspace/it.db' ) . should . equal ( true ) ;
fs . existsSync ( 'workspace/it.db~' ) . should . equal ( false ) ;
done ( ) ;
done ( ) ;
} ) ;
} ) ;
} ) ;
} ) ;
@ -656,20 +659,16 @@ describe('Persistence', function () {
if ( fs . existsSync ( testDb ) ) { fs . unlinkSync ( testDb ) ; }
if ( fs . existsSync ( testDb ) ) { fs . unlinkSync ( testDb ) ; }
if ( fs . existsSync ( testDb + '~' ) ) { fs . unlinkSync ( testDb + '~' ) ; }
if ( fs . existsSync ( testDb + '~' ) ) { fs . unlinkSync ( testDb + '~' ) ; }
if ( fs . existsSync ( testDb + '~~' ) ) { fs . unlinkSync ( testDb + '~~' ) ; }
fs . existsSync ( testDb ) . should . equal ( false ) ;
fs . existsSync ( testDb ) . should . equal ( false ) ;
fs . writeFileSync ( testDb + '~' , 'something' , 'utf8' ) ;
fs . writeFileSync ( testDb + '~' , 'something' , 'utf8' ) ;
fs . writeFileSync ( testDb + '~~' , 'something else' , 'utf8' ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~~' ) . should . equal ( true ) ;
d . persistence . persistCachedDatabase ( function ( err ) {
d . persistence . persistCachedDatabase ( function ( err ) {
var contents = fs . readFileSync ( testDb , 'utf8' ) ;
var contents = fs . readFileSync ( testDb , 'utf8' ) ;
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( testDb ) . should . equal ( true ) ;
fs . existsSync ( testDb ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~~' ) . should . equal ( false ) ;
if ( ! contents . match ( /^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/ ) ) {
if ( ! contents . match ( /^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/ ) ) {
throw "Datafile contents not as expected" ;
throw "Datafile contents not as expected" ;
}
}
@ -686,20 +685,17 @@ describe('Persistence', function () {
if ( fs . existsSync ( testDb ) ) { fs . unlinkSync ( testDb ) ; }
if ( fs . existsSync ( testDb ) ) { fs . unlinkSync ( testDb ) ; }
if ( fs . existsSync ( testDb + '~' ) ) { fs . unlinkSync ( testDb + '~' ) ; }
if ( fs . existsSync ( testDb + '~' ) ) { fs . unlinkSync ( testDb + '~' ) ; }
if ( fs . existsSync ( testDb + '~~' ) ) { fs . unlinkSync ( testDb + '~~' ) ; }
fs . existsSync ( testDb ) . should . equal ( false ) ;
fs . existsSync ( testDb ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . writeFileSync ( testDb + '~' , 'bloup' , 'utf8' ) ;
fs . writeFileSync ( testDb + '~' , 'bloup' , 'utf8' ) ;
fs . writeFileSync ( testDb + '~~' , 'blap' , 'utf8' ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~~' ) . should . equal ( true ) ;
d . persistence . persistCachedDatabase ( function ( err ) {
d . persistence . persistCachedDatabase ( function ( err ) {
var contents = fs . readFileSync ( testDb , 'utf8' ) ;
var contents = fs . readFileSync ( testDb , 'utf8' ) ;
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( testDb ) . should . equal ( true ) ;
fs . existsSync ( testDb ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~~' ) . should . equal ( false ) ;
if ( ! contents . match ( /^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/ ) ) {
if ( ! contents . match ( /^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/ ) ) {
throw "Datafile contents not as expected" ;
throw "Datafile contents not as expected" ;
}
}
@ -709,24 +705,21 @@ describe('Persistence', function () {
} ) ;
} ) ;
} ) ;
} ) ;
it ( 'persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp or old datafile' , function ( done ) {
it ( 'persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp datafile' , function ( done ) {
d . insert ( { hello : 'world' } , function ( ) {
d . insert ( { hello : 'world' } , function ( ) {
d . find ( { } , function ( err , docs ) {
d . find ( { } , function ( err , docs ) {
docs . length . should . equal ( 1 ) ;
docs . length . should . equal ( 1 ) ;
if ( fs . existsSync ( testDb ) ) { fs . unlinkSync ( testDb ) ; }
if ( fs . existsSync ( testDb ) ) { fs . unlinkSync ( testDb ) ; }
fs . writeFileSync ( testDb + '~' , 'blabla' , 'utf8' ) ;
fs . writeFileSync ( testDb + '~' , 'blabla' , 'utf8' ) ;
fs . writeFileSync ( testDb + '~~' , 'bloblo' , 'utf8' ) ;
fs . existsSync ( testDb ) . should . equal ( false ) ;
fs . existsSync ( testDb ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~~' ) . should . equal ( true ) ;
d . persistence . persistCachedDatabase ( function ( err ) {
d . persistence . persistCachedDatabase ( function ( err ) {
var contents = fs . readFileSync ( testDb , 'utf8' ) ;
var contents = fs . readFileSync ( testDb , 'utf8' ) ;
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( testDb ) . should . equal ( true ) ;
fs . existsSync ( testDb ) . should . equal ( true ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~' ) . should . equal ( false ) ;
fs . existsSync ( testDb + '~~' ) . should . equal ( false ) ;
if ( ! contents . match ( /^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/ ) ) {
if ( ! contents . match ( /^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/ ) ) {
throw "Datafile contents not as expected" ;
throw "Datafile contents not as expected" ;
}
}
@ -736,12 +729,11 @@ describe('Persistence', function () {
} ) ;
} ) ;
} ) ;
} ) ;
it ( 'persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp or old datafile' , function ( done ) {
it ( 'persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp datafile' , function ( done ) {
var dbFile = 'workspace/test2.db' , theDb ;
var dbFile = 'workspace/test2.db' , theDb ;
if ( fs . existsSync ( dbFile ) ) { fs . unlinkSync ( dbFile ) ; }
if ( fs . existsSync ( dbFile ) ) { fs . unlinkSync ( dbFile ) ; }
if ( fs . existsSync ( dbFile + '~' ) ) { fs . unlinkSync ( dbFile + '~' ) ; }
if ( fs . existsSync ( dbFile + '~' ) ) { fs . unlinkSync ( dbFile + '~' ) ; }
if ( fs . existsSync ( dbFile + '~~' ) ) { fs . unlinkSync ( dbFile + '~~' ) ; }
theDb = new Datastore ( { filename : dbFile } ) ;
theDb = new Datastore ( { filename : dbFile } ) ;
@ -750,7 +742,6 @@ describe('Persistence', function () {
assert . isNull ( err ) ;
assert . isNull ( err ) ;
fs . existsSync ( dbFile ) . should . equal ( true ) ;
fs . existsSync ( dbFile ) . should . equal ( true ) ;
fs . existsSync ( dbFile + '~' ) . should . equal ( false ) ;
fs . existsSync ( dbFile + '~' ) . should . equal ( false ) ;
fs . existsSync ( dbFile + '~~' ) . should . equal ( false ) ;
if ( contents != "" ) {
if ( contents != "" ) {
throw "Datafile contents not as expected" ;
throw "Datafile contents not as expected" ;
}
}
@ -764,7 +755,6 @@ describe('Persistence', function () {
async . waterfall ( [
async . waterfall ( [
async . apply ( storage . ensureFileDoesntExist , dbFile )
async . apply ( storage . ensureFileDoesntExist , dbFile )
, async . apply ( storage . ensureFileDoesntExist , dbFile + '~' )
, async . apply ( storage . ensureFileDoesntExist , dbFile + '~' )
, async . apply ( storage . ensureFileDoesntExist , dbFile + '~~' )
, function ( cb ) {
, function ( cb ) {
theDb = new Datastore ( { filename : dbFile } ) ;
theDb = new Datastore ( { filename : dbFile } ) ;
theDb . loadDatabase ( cb ) ;
theDb . loadDatabase ( cb ) ;
@ -811,7 +801,6 @@ describe('Persistence', function () {
, function ( cb ) {
, function ( cb ) {
fs . existsSync ( dbFile ) . should . equal ( true ) ;
fs . existsSync ( dbFile ) . should . equal ( true ) ;
fs . existsSync ( dbFile + '~' ) . should . equal ( false ) ;
fs . existsSync ( dbFile + '~' ) . should . equal ( false ) ;
fs . existsSync ( dbFile + '~~' ) . should . equal ( false ) ;
return cb ( ) ;
return cb ( ) ;
}
}
, function ( cb ) {
, function ( cb ) {
@ -830,17 +819,13 @@ describe('Persistence', function () {
, function ( cb ) {
, function ( cb ) {
fs . existsSync ( dbFile ) . should . equal ( true ) ;
fs . existsSync ( dbFile ) . should . equal ( true ) ;
fs . existsSync ( dbFile + '~' ) . should . equal ( false ) ;
fs . existsSync ( dbFile + '~' ) . should . equal ( false ) ;
fs . existsSync ( dbFile + '~~' ) . should . equal ( false ) ;
return cb ( ) ;
return cb ( ) ;
}
}
] , done ) ;
] , done ) ;
} ) ;
} ) ;
// This test needs to be rewritten. The goal is to check what happens when the system crashes during a writeFile, so this test
// This test is a bit complicated since it depends on the time I/O actions take to execute
// must rewrite a custom and buggy writeFile that will be used by the child process and crash in the midst of writing the file
// That depends on the machine and the load on the machine when the tests are run
// It is timed for my machine with nothing else running but may not work as expected on others (it will not fail but may not be a proof)
// Every new version of NeDB passes it on my machine before rtelease
it ( 'If system crashes during a loadDatabase, the former version is not lost' , function ( done ) {
it ( 'If system crashes during a loadDatabase, the former version is not lost' , function ( done ) {
var cp , N = 150000 , toWrite = "" , i ;
var cp , N = 150000 , toWrite = "" , i ;