tests for simple query queue scenarios

This commit is contained in:
brianc 2010-10-24 22:52:12 -05:00
parent d927e7e3f5
commit 59aed65b78
5 changed files with 160 additions and 58 deletions

View File

@ -16,8 +16,7 @@ var Client = function(config) {
this.host = config.host; this.host = config.host;
this.queryQueue = []; this.queryQueue = [];
this.stream = config.stream || new net.Stream(); this.connection = config.connection || new Connection({stream: config.stream || new net.Stream()});
this.connection = new Connection({stream: this.stream});
this.queryQueue = []; this.queryQueue = [];
this.password = config.password || ''; this.password = config.password || '';
this.lastBuffer = false; this.lastBuffer = false;
@ -36,6 +35,7 @@ p.connect = function() {
var con = this.connection; var con = this.connection;
con.connect(this.port, this.host); con.connect(this.port, this.host);
//once connection is established send startup message
con.on('connect', function() { con.on('connect', function() {
con.startup({ con.startup({
user: self.user, user: self.user,
@ -43,78 +43,102 @@ p.connect = function() {
}); });
}); });
//password request handling
con.on('authenticationCleartextPassword', function() { con.on('authenticationCleartextPassword', function() {
con.password(self.password); con.password(self.password);
}); });
//password request handling
con.on('authenticationMD5Password', function(msg) { con.on('authenticationMD5Password', function(msg) {
var inner = Client.md5(self.password + self.user); var inner = Client.md5(self.password + self.user);
var outer = Client.md5(inner + msg.salt.toString('binary')); var outer = Client.md5(inner + msg.salt.toString('binary'));
var md5password = "md5" + outer; var md5password = "md5" + outer;
con.password(md5password); con.password(md5password);
}); });
con.on('readyForQuery', function() {
self.readyForQuery = true;
self.pulseQueryQueue();
});
};
p.pulseQueryQueue = function() {
if(this.readyForQuery===true && this.queryQueue.length > 0) {
this.readyForQuery = false;
var query = this.queryQueue.shift();
if(typeof query === 'string') {
this.connection.query(query);
}
}
};
p.query = function(config) {
this.queryQueue.push(config);
this.pulseQueryQueue();
}; };
Client.md5 = function(string) { Client.md5 = function(string) {
return crypto.createHash('md5').update(string).digest('hex'); return crypto.createHash('md5').update(string).digest('hex');
}; };
var intParser = { // var intParser = {
fromDbValue: parseInt // fromDbValue: parseInt
}; // };
var floatParser = { // var floatParser = {
fromDbValue: parseFloat // fromDbValue: parseFloat
}; // };
var timeParser = { // var timeParser = {
fromDbValue: function(isoTime) { // fromDbValue: function(isoTime) {
var when = new Date(); // var when = new Date();
var split = isoTime.split(':'); // var split = isoTime.split(':');
when.setHours(split[0]); // when.setHours(split[0]);
when.setMinutes(split[1]); // when.setMinutes(split[1]);
when.setSeconds(split[2].split('-') [0]); // when.setSeconds(split[2].split('-') [0]);
return when; // return when;
} // }
}; // };
var dateParser = { // var dateParser = {
fromDbValue: function(isoDate) { // fromDbValue: function(isoDate) {
return Date.parse(isoDate); // return Date.parse(isoDate);
} // }
}; // };
Client.dataTypes = { // Client.dataTypes = {
20: intParser, // 20: intParser,
21: intParser, // 21: intParser,
23: intParser, // 23: intParser,
26: intParser, // 26: intParser,
1700: floatParser, // 1700: floatParser,
700: floatParser, // 700: floatParser,
701: floatParser, // 701: floatParser,
1083: timeParser, // 1083: timeParser,
1266: timeParser, // 1266: timeParser,
1114: dateParser, // 1114: dateParser,
1184: dateParser // 1184: dateParser
}; // };
p.processRowDescription = function(description) { // p.processRowDescription = function(description) {
this.fields = description.fields; // this.fields = description.fields;
}; // };
p.processDataRow = function(dataRow) { // p.processDataRow = function(dataRow) {
var row = dataRow.fields; // var row = dataRow.fields;
var fields = this.fields || []; // var fields = this.fields || [];
var field, dataType; // var field, dataType;
for(var i = 0, len = row.length; i < len; i++) { // for(var i = 0, len = row.length; i < len; i++) {
field = fields[i] || 0 // field = fields[i] || 0
var dataType = Client.dataTypes[field.dataTypeID]; // var dataType = Client.dataTypes[field.dataTypeID];
if(dataType) { // if(dataType) {
row[i] = dataType.fromDbValue(row[i]); // row[i] = dataType.fromDbValue(row[i]);
} // }
} // }
this.emit('row',row); // this.emit('row',row);
}; // };
//end parsing methods //end parsing methods
module.exports = Client; module.exports = Client;

View File

@ -4,11 +4,12 @@ test('cleartext password authentication', function(){
var client = createClient(); var client = createClient();
client.password = "!"; client.password = "!";
client.stream.packets = []; client.connection.stream.packets = [];
client.connection.emit('authenticationCleartextPassword'); client.connection.emit('authenticationCleartextPassword');
test('responds with password', function() { test('responds with password', function() {
assert.length(client.stream.packets, 1); var packets = client.connection.stream.packets;
var packet = client.stream.packets[0]; assert.length(packets, 1);
var packet = packets[0];
assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0]); assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0]);
}); });

View File

@ -6,13 +6,13 @@ test('md5 authentication', function() {
client.connection.emit('authenticationMD5Password', {salt: salt}); client.connection.emit('authenticationMD5Password', {salt: salt});
test('responds', function() { test('responds', function() {
assert.length(client.stream.packets, 1); assert.length(client.connection.stream.packets, 1);
test('should have correct encrypted data', function() { test('should have correct encrypted data', function() {
var encrypted = Client.md5(client.password + client.user); var encrypted = Client.md5(client.password + client.user);
encrypted = Client.md5(encrypted + salt.toString('binary')); encrypted = Client.md5(encrypted + salt.toString('binary'));
var password = "md5" + encrypted var password = "md5" + encrypted
//how do we want to test this? //how do we want to test this?
assert.equalBuffers(client.stream.packets[0], new BufferList() assert.equalBuffers(client.connection.stream.packets[0], new BufferList()
.addCString(password).join(true,'p')) .addCString(password).join(true,'p'))
}); });
}); });

View File

@ -0,0 +1,77 @@
require(__dirname + "/test-helper");
var makeClient = function() {
var connection = new Connection({stream: "no"});
connection.startup = function() {};
connection.connect = function() {};
connection.query = function(text) {
this.queries.push(text);
};
connection.queries = [];
var client = new Client({connection: connection});
client.connect();
client.connection.emit('connect');
return client;
};
test('executing query', function() {
test("queing query", function() {
test('when connection is ready', function() {
var client = makeClient();
assert.empty(client.connection.queries);
client.connection.emit('readyForQuery');
client.query('yes');
assert.length(client.connection.queries, 1);
assert.equal(client.connection.queries, 'yes');
});
test('when connection is not ready', function() {
var client = makeClient();
test('query is not sent', function() {
client.query('boom');
assert.empty(client.connection.queries);
});
test('sends query to connection once ready', function() {
assert.ok(client.connection.emit('readyForQuery'));
assert.length(client.connection.queries, 1);
assert.equal(client.connection.queries[0], "boom");
});
});
test("multiple in the queue", function() {
var client = makeClient();
var connection = client.connection;
var queries = connection.queries;
client.query('one');
client.query('two');
client.query('three');
assert.empty(queries);
test("after one ready for query",function() {
connection.emit('readyForQuery');
assert.length(queries, 1);
assert.equal(queries[0], "one");
});
test('after two ready for query', function() {
connection.emit('readyForQuery');
assert.length(queries, 2);
});
test("after a bunch more", function() {
connection.emit('readyForQuery');
connection.emit('readyForQuery');
connection.emit('readyForQuery');
assert.length(queries, 3);
assert.equal(queries[0], "one");
assert.equal(queries[1], 'two');
assert.equal(queries[2], 'three');
});
});
})
});

View File

@ -16,7 +16,7 @@ createClient = function() {
var stream = new MemoryStream(); var stream = new MemoryStream();
stream.readyState = "open"; stream.readyState = "open";
var client = new Client({ var client = new Client({
stream: stream connection: new Connection({stream: stream})
}); });
client.connect(); client.connect();
return client; return client;