Monday, March 7, 2011

What The Sugar Mountain Has Taught Us: 2. It's The People, Not The Garden

As we continue to interact with friends, family and strangers on Facebook and Twitter, it's useful to take a break and consider what is important and what is not.

Remember that in Facebook, an important aspect to why we share our real lives is the feeling of being in a trusted garden with just the people we know. But is it the garden that Facebook provides, or sharing with just the people we know that is more important?

If we had a way of connecting with the people from our real lives on the open Internet (i.e., outside of Facebook), we would share the same content, knowing that we were sharing only with them.

Friday, January 28, 2011

What The Sugar Mountain Has Taught Us: 1. The Khala

On earlier social networks like Friendster and Myspace, identity was malleable and playful, but Facebook was and is different. “We're trying to map out what exists in the world,” [Zuckerberg] says. “In the world, there's trust. I think as humans we fundamentally parse the world through the people and relationships we have around us.


The above quote from the Time article on Facebook’s founder Mark Zuckerberg captures an incredibly important aspect of what set Facebook apart from the social networks that came before it: unlike Friendster or MySpace, Facebook was where we put our real selves online. Everything from our birth dates, to our sexual preferences, to our interests, to our intimate thoughts, on Facebook, we shared who we really were, and we shared it mostly with our real life friends. And we had good reason: back in the day, Facebook was just for college students and it felt like a safe and trusted place - a private walled garden where you could share your life with the people who went to the same school as you.

Fast forward a few years to today. Facebook is no longer restricted to colleges but we are still divulging personal details and the minutia of our daily lives on it. To be fair, our Facebook friends are still mostly the people we know in real life and so a certain sense of trust still exists. But venture outside of Facebook and you will notice that something more fundamental has happened: we have slowly become accustomed to sharing our life online everywhere - and not just with the people we know. Consider Twitter: we share what shows we are watching, what recipes we are cooking up, and what events we are attending; on Foursquare, we broadcast our exact location; on Justin.tv, we broadcast live video; and all of this using our real name and identity. These days, even on forums, mailing lists and comment threads, posts made using our real life identity carry much more weight than anonymous posts.

Forgive the platitude but: humans are fundamentally social beings and will always strive to become more socially connected. We want to see what our friends, colleagues and family are up to, and we want support, recognition and company in the things we do. But as we continue to put more and more of our life online, we are also demanding more control: we want to be able to say that certain aspects get shared only with those closest to us. Other parts of our life - for example, events we want everyone to partake in, opinions we want feedback on - can be available for all to see.

Wednesday, December 5, 2007

SWTBot

For those who have tried to test GUI-based Eclipse plug-ins - i.e., Wizards, Dialogs, Editors, and a lot of other useful things in Eclipse, you know that there is a scarcity of options - and especially non-commercial ones. So, when it came time to write functional tests for the Eclipse-based toolset that the team I am part of is developing, it was really a matter of choosing one among a few frameworks that are still in the early stages - meaning minimal documentation, and constant changes.

Though the situation was less than ideal, I decided to go with one that looked promising - SWTBot. Although the documentation is almost non-existent as of yet, you will still be able to pick it up quickly after going through the samples and the code. You start with a SWTBot and use its various methods to locate the controls you want to test, and then use custom bots to manipulate (simulating clicks, key-presses, etc) and verify (testing value of label, etc.) aspects of those controls. Its trivial to include the SWTBot testing code within JUnit test cases and run it using the Eclipse JUnit runners. By the end of day one with SWTBot, I had tests for some dialogs and preference pages, and was well on my way to satisfying my testing requirements.

Now this is great and all but be aware that this framework is still in a relatively early stage of development: expect to go through the framework code to fix issues you encounter. In fact, I had several issues related to getting the appropriate timeouts (especially with the editor content-assist tests), making sure my event listeners were fired, etc. But the guy behind the framework - Ketan Padegaonkar is very committed to the project and is very approachable - he has already addressed the issues I have brought up. If you need to do functional testing of your SWT and Eclipse applications, SWTBot is definitely worth considering.

Tuesday, July 3, 2007

Mechanizations - Towards an ActiveRecord for Gears

With the recent hoopla over ECMA/JavaScript on Rails, and the advent of Google Gears (albeit beta), there is definitely a potential bubble waiting to happen. It's reasonable to expect a lot of APIs and frameworks to appear around Gears, and around the idea of making the browser an even thicker client in general.

Towards that end, I started Mechanizations to ease development of Gears, and JavaScript applications in general. While it is very rudimentary at the moment, supporting only a basic RoR ActiveRecord's ConnectionAdapter-style API, I think it can still help others working with Gears. Eventually, I hope to evolve it into an ActiveRecord for Gears (who didn't think of how great it would be to have a JavaScript ActiveRecord when they first saw Gears?), and a more generic framework beyond that.

As an introduction, I think the following snippet from the tests for the GearsConnector object is useful:


testMigrate: function() {
var migrations = [
{ // version 0
up: function(c) {
c.createTable('test_table', {id: 'INTEGER', name: 'TEXT'});
},
down: function(c) {
c.dropTable('test_table');
}
},
{ // version 1
up: function(c) {
c.createTable('test_table1', {id: 'INTEGER'});
},
down: function(c) {
c.dropTable('test_table1');
}
},
{ // version 2
up: function(c) {
c.dropTable('test_table');
c.dropTable('test_table1');
},
down: function(c) {
c.createTable('test_table', {id: 'INTEGER', name: 'TEXT'});
c.createTable('test_table1', {id: 'INTEGER'});
}
},
{ // version 3
up: function(c) {
c.renameTable('test_table', 'test_table1');
},
down: function(c) {
c.renameTable('test_table1', 'test_table');
}
}
];

this.connector.migrate(migrations, 0);
assertEquals(this.connector.tables(), ['_migrations','test_table']);

this.connector.migrate(migrations, 2);
assertEquals(this.connector.tables(), ['_migrations']);

this.connector.migrate(migrations, -1);
assertEquals(this.connector.tables(), ['_migrations']);

// This migrations fails, so we remain at version -1
this.connector.migrate(migrations, 3);
assertEquals(this.connector.tables(), ['_migrations']);
}

Just a bit more from the test for select:

testSelect: function() {
this.connector.createTable('test_table', {id: 'INTEGER', name: 'TEXT'});
this.connector.insert('test_table', [0, 'R1']);
this.connector.insert('test_table', [1, 'R2']);
this.connector.insert('test_table', [2, 'R3']);
assertEquals(this.connector.select('test_table').length, 3);
assertEquals($.keys(this.connector.select('test_table', [])[0]).length, 2);
assertEquals($.keys(this.connector.select('test_table', ['*'])[0]).length, 2);
assertEquals(this.connector.select('test_table', {headers: true}).length, 4);
assertEquals(this.connector.select('test_table', {where: ['id=?', 0]}).length, 1);
assertEquals(this.connector.select(
'test_table', ['id'], {where: ['id>?', 0], limit: 1})[0]['test_table_id'], 1);
assertEquals(this.connector.select(
'test_table', {where: ['id>?', 0], limit: 1, offset: 1})[0]['id'], 2);
assertEquals(this.connector.select(
'test_table', ['id'], {orderBy: 'id DESC'})[0]['test_table_id'], 2);
this.connector.dropTable('test_table');
}

Thursday, June 14, 2007

Getting through that damn proxy! (using Java)

If you are on a corporate network, you know how annoying it can be to try and get through the proxy. And if you are a developer, it can be even more frustrating because you can't even test your networked application until you first get through the proxy.

Sun has a great article on what is built in to Java to handle network proxies. This one covers the latest features available since Java 1.5 that let you control use of a proxy at a per-socket and per-connection level. Check it out first:

Java Networking and Proxies

Now, that article is pretty good but it doesn't cover how to do proxy authentication. Thankfully, there is another article from Sun which covers how to use java.net.Authenticator. This class, and its related classes, is how you will be doing authentication. How you go about doing authentication with these classes is covered here:

Http Authentication

But wait! There is one prominent piece missing from what's built in to Java for dealing with proxies. And this is that it cannot make regular TCP tunnels through a HTTP proxy (using a Proxy.Type.HTTP Proxy with a Socket won't work). This support is provided in HTTP & HTTP proxies through the CONNECT method. Before getting into how to handle this in Java, let me just give a quick overview of how the process works:


  • First, the client starts a socket and sends out a HTTP CONNECT request to the HTTP proxy. This request indicates what host and port we are actually interested in connecting to through the proxy.

  • The proxy establishes a connection to the host and port we request.

  • The proxy then sets up a tunnel which allows data we send to the proxy to pass through to the actual host, and vice-versa.

  • Now, the proxy sends back a HTTP OK response on the socket we used to send it the request (if everything goes right - if not, you'll get a response with a HTTP error code).

  • Right after the HTTP OK response, the same socket is now what we use to do all communications with the actual host we wanted to connect to. The proxy will tunnel data between us and that remote host.



Now, this HTTP CONNECT method for establishing a tunnel through a HTTP proxy is typically used for establishing SSL connections through the proxy. This means the proxy is usually not going to monitor the actual traffic that goes out once the tunnel is established (if it were SSL traffic, it would be encrypted anyway). But the typical use of this method for SSL tunnels means that HTTP proxies are most likely going to have the following restriction: If you try to establish a tunnel through the proxy to a remote port other than 443 (the SSL port), the proxy is probably going to reject your request. That is, you couldn't use the CONNECT method to connect to somehost.com:3001 because 3001 is not the SSL port.

So, keeping all that in mind, do you have to write your own implementation for dealing with HTTP proxy tunneling? Nope - luckily, there is the Jakarta Commons HttpClient. It has a ProxyClient class which can set all this up for you and return the socket which is ready to have actual data sent over it (that is, after the HTTP OK response has been received from the proxy). For a quick start, check out the ProxyTunnelDemo sample.