Jest + knex 'Unable to acquire a connection' during integration tests (sequelize works fine) - express

I have both sequelize and knex in my project (node.js, express, using TypeScript). Just introduced knex as I don't like sequelize and just want a light-weight query builder.
In non-test environments both sequelize and knex work fine, however when running tests (using jest) knex is, apparently, not able to connect to the database. They both use the same databaseUrl, though sequelize has a few more options configured. When running my tests under jest I can't figure out why I am getting
Error: Unable to acquire a connection\n at
Client_PG.acquireConnection
When NODE_ENV is set to 'test', the express app uses a postgres database on my local machine.
Here is the configuration code
const _sqlz = new Sequelize(
config.dbConString,
{
logging: config.nodeEnv === 'test' ? false : false,
define: { freezeTableName: true },
dialect: 'postgres',
...config.sslDB === 'true'
? {
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false
}
}
}
: {}
}
);
const knexConfig = {
client: 'postgres',
connection: config.dbConString,
pool: {
min: 0,
max: 15
}
};
const _knex = knex(knexConfig)
When running jest it will give me a Unable to acquire a connection when trying to execute a simple knex query like so
await _knex('myTable').select('*');
To figure out what's happening I configured things such that jest would use the same test database when I set my node environment to be development, i.e. NODE_ENV=development. Interestingly now that development and test point to the same local database, if I run jest, it still gives me the same error about not being able to acquire a connection. So me setting NODE_ENV=test in of itself is not the issue. If I run the app (npm run start) while pointing to my local database, knex works fine, which leads me to think something about jest + knex isn't meshing well. jest + sequelize is working fine.
I tried playing around with the SSL settings but to no avail (I did see some knex + heroku blog posts needing ssl to be explicitly set), e.g.:
const knexConfig = {
client: 'pg',
connection: {
connectionString: config.databaseUrl,
ssl: {
require: true,
rejectUnauthorized: false
}
},
pool: {
min: 0,
max: 15
}
};
Hoping someone with more experience might have some ideas.
Thanks

Related

Trying to connect to on-prem SQL Server using ntlm and nodejs

looking for an example or code that allows to connect a very simple node.js console application to a SQL Server Instance (2019) using ntlm and no name and password, using tedious and/or mssql.
For tedious, the code below works fine:
but I cannot seem to get the code to use ntlm without providing a name and password.
//
var Connection = require('tedious').Connection;
var config = {
server: '(local)',
authentication: {
type: 'default',
options: {
userName: 'sa',
password: 'your_sa_password' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: 'master',
trustServerCertificate: true
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
console.log("Connected");
});
connection.connect();
//
(I have tried the above with and without the trustServerCertificate, it seems necessary)
For mssql, I am using the first example on this page:
https://tediousjs.github.io/node-mssql/#connect-callback
And it returns nothing - nothing at all, whether I use sql auth or ntlm. Not sure what is going on there - I have edited the catch block to have an error output, nothing happens.
The Instance is up, the code above runs, I have nothing special or unusual about the SQL Server that I know of at all.
Thoughts? Pointers? Any help deeply appreciated. I

I can't run the node.js server using keystone.js framework

I have source code using keystone.js, and I can't run it because of a Mongodb connection error.
This is the code creating Keystone.
const keystone = new Keystone({
name: process.env.PROJECT_NAME,
adapter: new Adapter({dbName}),
mongo: 'mongodb://127.0.0.1:27017/',
sessionStore: new MongoStore({ url: 'mongodb://localhost/' }),
cookieSecret: 'process.env.COOKIE_SECRET',
appVersion: {
version: '1.0.0',
addVersionToHttpHeaders: false,
access: false,
},
cookie: {
secure: false,
maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days
sameSite: false
}
});
...
await keystone.connect()
Here are the error details:
(node:9928) UnhandledPromiseRejectionWarning: Error: No MongoDB connection URI specified.
at resolveAllKeys (E:\Node.JS\frostbets-master-2-20210809T155720Z-001\frostbets-master-2\keystone\node_modules\#keystonejs\utils\dist\utils.cjs.dev.js:51:19)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Keystone.connect (E:\Node.JS\frostbets-master-2-20210809T155720Z-001\frostbets-master-2\keystone\node_modules\#keystonejs\keystone\lib\Keystone\index.js:450:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:9928) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:9928) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
------------------------------------------------------------------------------------------
You haven't specified but it looks like you're on Keystone 5 so I'm going with that assumption.
There are a number of issue in the code you've posted:
The main problem you have is you're passing dbName to init you Adapter but you should be passing the full mongoUri.
That's the source of the specific error you're getting.
Pretty sure dbName was an option at one point but not in the current release of KS5.
Again, not sure which version you're actually on but if you've updated some packages in an older project, that might be it.
I'm not sure what the mongo key being passed in the Keystone config but I don't think it's valid.
Any config for Mongo (for the main DB) should be passed to the adapter.
The syntax you're using to create your MongoStore instance has been deprecated for the current version of that package.
If it works for you leave it, but in the code below I've used the more recent MongoStore.create() syntax.
In your code you have mongodb://127.0.0.1:27017/ (under the mongo key, which I think is ignored) and mongodb://localhost/ for the sessionStore.
For most systems this will refer to the same DB though it's not clear if that's intentional in your case.
In my code I've put the sessions in a separate DB (my-app-sessions) but that's optional.
Your config uses the literal string 'process.env.COOKIE_SECRET' as the cookie secret, not the value in the COOKIE_SECRET environment var.
This is almost certainly not what you want.
To solve these problems, you probably want something close to this:
const { Keystone } = require('#keystonejs/keystone');
const { GraphQLApp } = require('#keystonejs/app-graphql');
const { AdminUIApp } = require('#keystonejs/app-admin-ui');
const MongoStore = require('connect-mongo');
const { MongooseAdapter: Adapter } = require('#keystonejs/adapter-mongoose');
const keystone = new Keystone({
name: process.env.PROJECT_NAME,
adapter: new Adapter({ mongoUri: 'mongodb://localhost/my-app' }),
sessionStore: MongoStore.create({ mongoUrl: 'mongodb://localhost/my-app-sessions' }),
cookieSecret: process.env.COOKIE_SECRET,
appVersion: {
version: '1.0.0',
addVersionToHttpHeaders: false,
access: false,
},
cookie: {
secure: false,
maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days
sameSite: false
}
});
// ...
module.exports = {
keystone,
apps: [new GraphQLApp(), new AdminUIApp({ name: process.env.PROJECT_NAME, enableDefaultRoute: true })],
};
In this code I've left the standard exports at the bottom rather than calling keystone.connect() directly so I can run it with yarn keystone dev.
Tested with..
"dependencies": {
"#keystonejs/adapter-mongoose": "^11.2.2",
"#keystonejs/app-admin-ui": "^7.5.2",
"#keystonejs/app-graphql": "^6.3.2",
"#keystonejs/keystone": "^19.3.3",
"connect-mongo": "^4.4.1"
}

pouchdb - secure replication with remote LevelDB

I am keen on using PouchDB in browser memory for an Angular application. This PouchDB will replicate from a remote LevelDB database that is fed key-value pairs from an algorithm. So, on the remote end, I would install PouchDB-Server. On the local end, I would do the following (as described here) on a node prompt.
var localDB = new PouchDB('mylocaldb')
var remoteDB = new PouchDB('https://remote-ip-address:5984/myremotedb')
localDB.sync(remoteDB, {
live: true
}).on('change', function (change) {
// yo, something changed!
}).on('error', function (err) {
// yo, we got an error! (maybe the user went offline?)
});
How do we start a PouchDB instance that supports TLS for live replication as described in the snippet above?
How do I start a PouchDB instance that supports TLS for live replication?
So after some more searching, it is clear from this topic, HTTPS is not supported for PocuhDB-Server.
Sorry, I misunderstood your question. I thought you intend to connect to a CouchDB server with PouchDB through HTTPS. Therefore, the following answer actually doesn't answer your question.
I created a server.js file like below to communicate with my CouchDB through HTTPS. Please note that the SSL certificate is (in my case) self-signed, and also CouchDB listens by default on port 6984 in the case of TLS:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; // Ignore rejection, becasue CouchDB SSL certificate is self-signed
//import PouchDB from 'pouchdb'
const PouchDB = require('pouchdb')
const db = new PouchDB('https://admin:****#192.168.1.106:6984/reproduce')
db.allDocs({
include_docs: true,
attachments: false
}).then(function (result) {
// handle result
console.log(result)
}).catch(function (err) {
console.log(err);
});
I'm running the above file with $ node server.js and I'm getting the expected results:
$ node server.js
{ total_rows: 3,
offset: 0,
rows:
[ { id: '5d6590d3-41c7-4011-be5d-b21f80079ae5',
key: '5d6590d3-41c7-4011-be5d-b21f80079ae5',
value: [Object],
doc: [Object] },
{ id: 'ec6a36d1-952e-4d86-9865-3587c6079fb5',
key: 'ec6a36d1-952e-4d86-9865-3587c6079fb5',
value: [Object],
doc: [Object] },
{ id: 'f508e7aa-b4dc-42fc-96be-b7c1ffa54172',
key: 'f508e7aa-b4dc-42fc-96be-b7c1ffa54172',
value: [Object],
doc: [Object] } ] }
I created the above code with NodeJS on server-side. However, if you want to communicate with CouchDB through HTTPS inside the browser, i.e. on client-side, you have to enable CORS on CouchDB.

Unable to connect Ganache with Truffle/Npm Dev server

I am able to work with Truffle and Ganache-cli. Have deployed the contract and can play with that using truffle console
truffle(development)>
Voting.deployed().then(function(contractInstance)
{contractInstance.voteForCandidate('Rama').then(function(v)
{console.log(v)})})
undefined
truffle(development)> { tx:
'0xe4f8d00f7732c09df9e832bba0be9f37c3e2f594d3fbb8aba93fcb7faa0f441d',
receipt:
{ transactionHash:
'0xe4f8d00f7732c09df9e832bba0be9f37c3e2f594d3fbb8aba93fcb7faa0f441d',
transactionIndex: 0,
blockHash:
'0x639482c03dba071973c162668903ab98fb6ba4dbd8878e15ec7539b83f0e888f',
blockNumber: 10,
gasUsed: 28387,
cumulativeGasUsed: 28387,
contractAddress: null,
logs: [],
status: '0x01',
logsBloom: ... }
Now when i started a server using "npm run dev". Server started fine but is not connecting with the Blockchain
i am getting the error
Uncaught (in promise) Error: Contract has not been deployed to detected network (network/artifact mismatch)
This is my truffle.js
// Allows us to use ES6 in our migrations and tests.
require('babel-register')
module.exports = {
networks: {
development: {
host: '127.0.0.1',
port: 8545,
network_id: '*', // Match any network id
gas: 1470000
}
}
}
Can you please guide me how i can connect ?
Solve the issue.
issue was at currentProvider, i gave the url of ganache blockchain provider and it worked.
if (typeof web3 !== 'undefined') {
console.warn("Using web3 detected from external source like Metamask")
// Use Mist/MetaMask's provider
// window.web3 = new Web3(web3.currentProvider);
window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
} else {
console.warn("No web3 detected. Falling back to http://localhost:8545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask");
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
In your truffle.js, change 8545 to 7545.
Or, in Ganache (GUI), click the gear in the upper right corner and change the port number from 7545 to 8545, then restart. With ganache-cli use -p 8545 option on startup to set 8545 as the port to listen on.
Either way, the mismatch seems to be the issue; these numbers should match. This is a common issue.
Also feel free to check out ethereum.stackexchange.com. If you want your question moved there, you can flag it and leave a message for a moderator to do that.

Recording video report for protractor execution on a remote environment

I am executing my protractor test suite from my desktop and I am using a remote selenium server. I have configured the 'protractor-video-reporter' to capture execution for my local windows environment (using ffmpeg codec) and when I execute using my local selenium server, the video capture works fine. But when I execute on remote VMs, it captures my desktop screen.
I understand that I need to provide the remote location path to ffmpeg codec, but I do not know how to provide appropriate user credentials so that my automation can invoke the remote plugin?
My present configuration is as follows:
const VideoReporter = require('protractor-video-reporter');
...
let config = {
...
onPrepare: () => {
...
VideoReporter.prototype.jasmineStarted = function () {
var self = this;
if (self.options.singleVideo) {
var videoPath = path.join(self.options.baseDirectory, 'protractor-specs.mpg');
self._startScreencast(videoPath);
if (self.options.createSubtitles) {
self._subtitles = [];
self._jasmineStartTime = new Date();
}
}
};
...
jasmine.getEnv().addReporter(new VideoReporter({
baseDirectory: './test-output/videoreport',
createSubtitles: false,
saveSuccessVideos: true,
singleVideo: true,
ffmpegCmd: "C:/FFmpeg/bin/ffmpeg.exe", /*Probably some changes needed here*/
ffmpegArgs: [
'-f', 'gdigrab',
'-framerate', '30',
'-video_size', 'wsxga',
'-i', 'desktop',
'-q:v', '10',
]
}));
...
}
...
}
export { config };
Considering that execution and video capture both has to happen in remote server, please suggest a suitable solution.