You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm not sure whether to classify this as a bug because I don't know what the official rule is on modules being reloaded. But I ran into this issue jestjs/jest#2826 when using Jest to test my database code so hopefully this will help anyone else that runs into it and perhaps the owners could implement a work-around or at least document it.
odbc.js overwrites the prototype of several of the native driver functions, such as prepare and execute. The section looks like this:
Later, the prepare function itself is defined to call the original prepare, now called _prepare. That works fine, but when Jest uncaches and then reloads the module, those prototypes aren't reset to the native functions. So the second module load sets _prepare to the previously overwritten version and the native version is lost. When prepare tries to call _prepare, it is calling itself so it stops processing because the queue appears to be executing already. For execute, a stack overflow occurs because it just keeps calling itself. This happens whether I run the tests sequentially using --runInBand or the normal way. To reproduce, create two identical tests as follows:
import ibmdb from 'ibm_db';
const cs = ...; // connection string
test('Something works', (done) => {
ibmdb.open(cs, (err, conn) => {
conn.prepare('select count(*) from sysibm.sysdummy1', (err, stmt) => {
// this is never run in the second test
expect(stmt).toBeDefined();
// rest of the code omitted because it never gets here,
// but to fully test, do execute, fetch, etc
done();
});
});
}
Running each test individually works fine. But run both tests in the same session and the second one will time out. Note: the done method is required or the tests will finish "successfully" before they hit the problem.
One suggested workaround was to use --no-cache --max-workers=n where n is 1 more then number of tests. That seems to help but would be inefficient with a lot of tests.
My workaround is to save off the original native functions and then export a function that can set them back at the end of the test. It looks something like this:
// in odbc.js, after module.exports = function (options) ...
var original_odbc = odbc;
var original_prepare = odbc.ODBCStatement.prototype.prepare;
// ... other functions
module.exports.resetLibrary = function() {
original_odbc.ODBCStatement.prototype.prepare = original_prepare;
// ...other functions
}
Then, in my test:
afterAll(() => {
imbdb.resetLibrary();
});
Sorry for the long-winded issue, but hopefully this will save someone else the time that it took me to figure it out.
The text was updated successfully, but these errors were encountered:
* fix: update binaries for windows and vscode (Bimal Jha)
* fix: Reloading driver causes failures on async functions #514 (Bimal Jha)
* fea: Convert the library to support Promises for all methods. #715 (Bimal Jha)
* fea: add result.close API (Bimal Jha)
* promisify describe related methods (Bimal Jha)
* update mac binaries for vscode ibmdb/vscode-extension#50 (Bimal Jha)
* test: update test files (Bimal Jha)
* fix: Empty Strings in Batch inserts result in corrupt values being inserted #875 (Bimal Jha)
* fea: Add support for Buffer() for insert and select for binary data. #702, #859, #860, #862, #864 (Bimal Jha)
* fea: allow installation using specific version of clidriver (Bimal Jha)
I'm not sure whether to classify this as a bug because I don't know what the official rule is on modules being reloaded. But I ran into this issue jestjs/jest#2826 when using Jest to test my database code so hopefully this will help anyone else that runs into it and perhaps the owners could implement a work-around or at least document it.
odbc.js overwrites the prototype of several of the native driver functions, such as prepare and execute. The section looks like this:
Later, the prepare function itself is defined to call the original prepare, now called _prepare. That works fine, but when Jest uncaches and then reloads the module, those prototypes aren't reset to the native functions. So the second module load sets _prepare to the previously overwritten version and the native version is lost. When prepare tries to call _prepare, it is calling itself so it stops processing because the queue appears to be executing already. For execute, a stack overflow occurs because it just keeps calling itself. This happens whether I run the tests sequentially using --runInBand or the normal way. To reproduce, create two identical tests as follows:
Running each test individually works fine. But run both tests in the same session and the second one will time out. Note: the done method is required or the tests will finish "successfully" before they hit the problem.
One suggested workaround was to use --no-cache --max-workers=n where n is 1 more then number of tests. That seems to help but would be inefficient with a lot of tests.
My workaround is to save off the original native functions and then export a function that can set them back at the end of the test. It looks something like this:
Then, in my test:
Sorry for the long-winded issue, but hopefully this will save someone else the time that it took me to figure it out.
The text was updated successfully, but these errors were encountered: