Index: trunk/Nebulous-Server/t/01_load.t
===================================================================
--- trunk/Nebulous-Server/t/01_load.t	(revision 22718)
+++ trunk/Nebulous-Server/t/01_load.t	(revision 23932)
@@ -12,5 +12,5 @@
 use Test::More tests => 5;
 
-BEGIN { use_ok( 'Nebulous::Keys' ); }
+BEGIN { use_ok( 'Nebulous::Key' ); }
 BEGIN { use_ok( 'Nebulous::Server' ); }
 BEGIN { use_ok( 'Nebulous::Server::Log' ); }
Index: trunk/Nebulous-Server/t/02_config.t
===================================================================
--- trunk/Nebulous-Server/t/02_config.t	(revision 22718)
+++ trunk/Nebulous-Server/t/02_config.t	(revision 23932)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 02_config.t,v 1.1 2008-12-12 21:13:41 jhoblitt Exp $
+# $Id: 02_config.t,v 1.1.2.2 2008-12-14 22:52:37 eugene Exp $
 
 use strict;
Index: trunk/Nebulous-Server/t/02_server_setup.t
===================================================================
--- trunk/Nebulous-Server/t/02_server_setup.t	(revision 22718)
+++ trunk/Nebulous-Server/t/02_server_setup.t	(revision 23932)
@@ -8,5 +8,5 @@
 use warnings;
 
-use Test::More tests => 2;
+use Test::More tests => 6;
 
 use lib qw( ./t ./lib );
@@ -17,23 +17,49 @@
 Test::Nebulous->setup;
 
-isa_ok(
-    Nebulous::Server->new(
-        dsn         => $NEB_DB,
-        dbuser      => $NEB_USER,
-        dbpasswd    => $NEB_PASS,
-    ),
-    "Nebulous::Server"
-);
+isa_ok(Nebulous::Server->new(), "Nebulous::Server");
 
 Test::Nebulous->setup;
 
-eval {
-    Nebulous::Server->new(
+# ->new()
+{
+    my $neb = Nebulous::Server->new( trace => 'off' );
+
+    ok($neb, "set log level");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Server->new(
         dsn         => "DBI:mysql:database=foobar:host=localhost",
         dbuser      => "baz",
         dbpasswd    =>"boo",
     );
-};
-like( $@, qr/DBI connect.*? failed/, "bad dsn/user/pass" );
+
+    ok($neb, "set database");
+}
+
+Test::Nebulous->setup;
+
+# add dbs after ->new()
+{
+    my $neb = Nebulous::Server->new;
+
+    ok($neb->config->add_db(
+        dbindex    => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    =>"boo",
+    ), "add db");
+    
+    ok($neb->config->add_db(
+        dbindex    => 1,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    =>"boo",
+    ), "add dbs");
+
+    is($neb->config->n_db, 2, "n dbs")
+}
 
 Test::Nebulous->cleanup;
Index: trunk/Nebulous-Server/t/03_server_create_object.t
===================================================================
--- trunk/Nebulous-Server/t/03_server_create_object.t	(revision 22718)
+++ trunk/Nebulous-Server/t/03_server_create_object.t	(revision 23932)
@@ -8,8 +8,9 @@
 use warnings FATAL => qw( all );
 
-use Test::More tests => 89;
+use Test::More tests => 99;
 
 use lib qw( ./t ./lib );
 
+use File::Basename qw( basename );
 use File::ExtAttr qw( getfattr );
 use Nebulous::Server;
@@ -26,4 +27,6 @@
 );
 
+use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
+
 Test::Nebulous->setup;
 
@@ -334,4 +337,174 @@
 }
 
+# test for properly row creation in the directories table
+
+Test::Nebulous->setup;
+
+{
+    my $key = "foo";
+    $neb->create_object($key);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key, dir_id => 1],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = "a/foo";
+    $neb->create_object($key);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 2],
+    );
+
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = "a/b/foo";
+    $neb->create_object($key);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 3],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = "a/b/c/foo";
+    $neb->create_object($key);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 4],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "a/b/c/foo";
+    my $key2 = "foo";
+    $neb->create_object($key1);
+    $neb->create_object($key2);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "a/b/c/foo";
+    my $key2 = "a/foo";
+    $neb->create_object($key1);
+    $neb->create_object($key2);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 2],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "a/b/c/foo";
+    my $key2 = "d/foo";
+    $neb->create_object($key1);
+    $neb->create_object($key2);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
+        directory       => [dir_id => 5, dirname => 'd', parent_id => 1],
+        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 5],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "a/b/c/foo";
+    my $key2 = "a/d/foo";
+    $neb->create_object($key1);
+    $neb->create_object($key2);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
+        directory       => [dir_id => 5, dirname => 'd', parent_id => 2],
+        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 5],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "a/b/c/foo";
+    my $key2 = "d/a/foo";
+    $neb->create_object($key1);
+    $neb->create_object($key2);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
+        directory       => [dir_id => 5, dirname => 'd', parent_id => 1],
+        directory       => [dir_id => 6, dirname => 'a', parent_id => 5],
+        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 6],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "a/b/c/foo";
+    my $key2 = "a/b/c/d/foo";
+    $neb->create_object($key1);
+    $neb->create_object($key2);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
+        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
+        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
+        directory       => [dir_id => 5, dirname => 'd', parent_id => 4],
+        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 5],
+    );
+}
+
 Test::Nebulous->setup;
 
Index: trunk/Nebulous-Server/t/08_server_delete_instance.t
===================================================================
--- trunk/Nebulous-Server/t/08_server_delete_instance.t	(revision 22718)
+++ trunk/Nebulous-Server/t/08_server_delete_instance.t	(revision 23932)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 08_server_delete_instance.t,v 1.12 2008-12-14 22:54:25 eugene Exp $
+# $Id: 08_server_delete_instance.t,v 1.10.22.1 2008-12-14 22:52:37 eugene Exp $
 
 use strict;
@@ -24,7 +24,8 @@
 
 {
-    my $uri = $neb->create_object("foo");
+    my $key = "foo";
+    my $uri = $neb->create_object($key);
 
-    ok($neb->delete_instance($uri), "delete instance");
+    ok($neb->delete_instance($key, $uri), "delete instance");
 }
 
@@ -32,17 +33,18 @@
 
 {
-    my $uri1 = $neb->create_object("foo");
-    my $uri2 = $neb->replicate_object("foo");
+    my $key = "foo";
+    my $uri1 = $neb->create_object($key);
+    my $uri2 = $neb->replicate_object($key);
 
-    ok($neb->delete_instance($uri1), "delete instance");
+    ok($neb->delete_instance($key, $uri1), "delete instance");
 
-    my $locations = $neb->find_instances("foo");
+    my $locations = $neb->find_instances($key);
 
     is($locations->[0], $uri2, "instance remains");
 
-    ok($neb->delete_instance( $uri2 ), "delete instance");
+    ok($neb->delete_instance($key, $uri2), "delete instance");
 
     eval {
-        $neb->find_instances("foo");
+        $neb->find_instances($key);
     };
     like($@, qr/is valid object key/, "storage object was deleted");
@@ -52,5 +54,8 @@
 
 eval {
-    $neb->delete_instance("file:/foo");
+    my $key = "foo";
+    my $uri1 = $neb->create_object($key);
+
+    $neb->delete_instance($key, "file:/foo");
 };
 like($@, qr/no instance is associated with uri/, "uri does not exist");
@@ -61,12 +66,15 @@
     $neb->delete_instance();
 };
-like($@, qr/1 was expected/, "no params");
+like($@, qr/2 were expected/, "no params");
 
 Test::Nebulous->setup;
 
 eval {
-    $neb->delete_instance("foo", 2);
+    my $key = "foo";
+    my $uri1 = $neb->create_object($key);
+
+    $neb->delete_instance("foo", 2, 3);
 };
-like($@, qr/1 was expected/, "too many params");
+like($@, qr/2 were expected/, "too many params");
 
 Test::Nebulous->cleanup;
Index: trunk/Nebulous-Server/t/10_server_is_valid_volume_name.t
===================================================================
--- trunk/Nebulous-Server/t/10_server_is_valid_volume_name.t	(revision 22718)
+++ trunk/Nebulous-Server/t/10_server_is_valid_volume_name.t	(revision 23932)
@@ -23,13 +23,13 @@
 Test::Nebulous->setup;
 
-ok($neb->_is_valid_volume_name('node01'), "valid volume name");
+ok($neb->_is_valid_volume_name('foo', 'node01'), "valid volume name");
 
 Test::Nebulous->setup;
 
-ok($neb->_is_valid_volume_name('node02'), "valid volume name");
+ok($neb->_is_valid_volume_name('foo', 'node02'), "valid volume name");
 
 Test::Nebulous->setup;
 
-is($neb->_is_valid_volume_name('node99'), undef, "invalid volume name");
+is($neb->_is_valid_volume_name('foo', 'node99'), undef, "invalid volume name");
 
 Test::Nebulous->cleanup;
Index: trunk/Nebulous-Server/t/12_server_find_objects.t
===================================================================
--- trunk/Nebulous-Server/t/12_server_find_objects.t	(revision 22718)
+++ trunk/Nebulous-Server/t/12_server_find_objects.t	(revision 23932)
@@ -8,5 +8,5 @@
 use warnings FATAL => qw( all );
 
-use Test::More tests => 6;
+use Test::More tests => 28;
 
 use lib qw( ./t ./lib );
@@ -25,6 +25,5 @@
 # search for a regex of '' should match nothing
 eval {
-    # key
-    my $uri = $neb->create_object("foo");
+    $neb->create_object("foo");
 
     my $keys = $neb->find_objects();
@@ -35,6 +34,5 @@
 
 {
-    # key
-    my $uri = $neb->create_object("foo");
+    $neb->create_object("foo");
 
     my $keys = $neb->find_objects("foo");
@@ -48,6 +46,6 @@
 {
     # key
-    my $uri1 = $neb->create_object("foo");
-    my $uri2 = $neb->replicate_object("foo");
+    $neb->create_object("foo");
+    $neb->replicate_object("foo");
 
     my $keys = $neb->find_objects("foo");
@@ -55,4 +53,120 @@
     is(scalar @$keys, 1, 'number of keys found');
     is($keys->[0], "foo", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    # key
+    $neb->create_object("foo");
+    $neb->create_object("bar");
+
+    my $keys = $neb->find_objects("foo");
+
+    is(scalar @$keys, 1, 'number of keys found');
+    is($keys->[0], "foo", "key name");
+}
+
+# test recursive dir searching
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+
+    my $keys = $neb->find_objects("a");
+
+    is(scalar @$keys, 1, 'number of keys found');
+    is($keys->[0], "a/foo", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("b/foo");
+
+    my $keys = $neb->find_objects("a");
+
+    is(scalar @$keys, 1, 'number of keys found');
+    is($keys->[0], "a/foo", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("a/b/foo");
+
+    my $keys = $neb->find_objects("a");
+
+    is(scalar @$keys, 1, 'number of keys found');
+    is($keys->[0], "a/foo", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("a/bar");
+
+    my $keys = $neb->find_objects("a");
+
+    is(scalar @$keys, 2, 'number of keys found');
+    is($keys->[0], "a/foo", "key name");
+    is($keys->[1], "a/bar", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("bar");
+
+    my $keys = $neb->find_objects("a");
+
+    is(scalar @$keys, 1, 'number of keys found');
+    is($keys->[0], "a/foo", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("foo");
+    $neb->create_object("bar");
+
+    my $keys = $neb->find_objects("/");
+
+    is(scalar @$keys, 2, 'number of keys found');
+    is($keys->[0], "foo", "key name");
+    is($keys->[1], "bar", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("foo");
+    $neb->create_object("bar");
+
+    my $keys = $neb->find_objects(".");
+
+    is(scalar @$keys, 2, 'number of keys found');
+    is($keys->[0], "foo", "key name");
+    is($keys->[1], "bar", "key name");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object("a/foo");
+    $neb->create_object("foo");
+    $neb->create_object("bar");
+
+    my $keys = $neb->find_objects("..");
+
+    is(scalar @$keys, 2, 'number of keys found');
+    is($keys->[0], "foo", "key name");
+    is($keys->[1], "bar", "key name");
 }
 
Index: trunk/Nebulous-Server/t/13_server_rename_object.t
===================================================================
--- trunk/Nebulous-Server/t/13_server_rename_object.t	(revision 22718)
+++ trunk/Nebulous-Server/t/13_server_rename_object.t	(revision 23932)
@@ -8,8 +8,9 @@
 use warnings FATAL => qw( all );
 
-use Test::More tests => 6;
+use Test::More tests => 8;
 
 use lib qw( ./t ./lib );
 
+use File::Basename qw( basename );
 use Nebulous::Server;
 use Test::Nebulous;
@@ -21,18 +22,48 @@
 );
 
+use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
+
 Test::Nebulous->setup;
 
 {
+    my $key = "bar";
     my $uri = $neb->create_object("foo");
 
-    $neb->rename_object("foo", "bar");
+    $neb->rename_object("foo", $key);
 
-    eval {
-        $neb->find_objects('^foo$');
-    };
-    like($@, qr/no keys found/, "old key name");
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 1],
+    );
+}
 
-    my $keys = $neb->find_objects('^bar$');
-    is(scalar @$keys, 1, 'number of keys found');
+Test::Nebulous->setup;
+
+{
+    my $key = "a/bar";
+    my $uri = $neb->create_object("foo");
+
+    $neb->rename_object("foo", $key);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 2],
+    );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = "bar";
+    my $uri = $neb->create_object("a/foo");
+
+    $neb->rename_object("a/foo", $key);
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 1],
+    );
 }
 
@@ -73,3 +104,19 @@
 like($@, qr/2 were expected/, "too many params");
 
+# test attempting to rename a key in such a way to cause the distributed
+# storage db to change
+# this must be the last test as we're messing with the $neb object
+eval {
+    $neb->config->add_db(
+        dbindex     => 1,
+        dsn         => $NEB_DB,
+        dbuser      => $NEB_USER,
+        dbpasswd    => $NEB_PASS,
+    );
+
+    $neb->create_object("a/foo");
+    $neb->rename_object("a/foo", "g/bar");
+};
+like($@, qr/rename objects across distributed database boundaries/, "rename between databases");
+
 Test::Nebulous->cleanup;
Index: trunk/Nebulous-Server/t/16_server_swap_objects.t
===================================================================
--- trunk/Nebulous-Server/t/16_server_swap_objects.t	(revision 22718)
+++ trunk/Nebulous-Server/t/16_server_swap_objects.t	(revision 23932)
@@ -8,8 +8,9 @@
 use warnings FATAL => qw( all );
 
-use Test::More tests => 8;
+use Test::More tests => 13;
 
 use lib qw( ./t ./lib );
 
+use File::Basename qw( basename );
 use Nebulous::Server;
 use Test::Nebulous;
@@ -21,14 +22,48 @@
 );
 
+use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
+
 Test::Nebulous->setup;
 
 {
-    my $uri1 = $neb->create_object("foo1");
-    my $uri2 = $neb->create_object("foo2");
+    my $key1 = "foo1";
+    my $key2 = "foo2";
+    my $uri1 = $neb->create_object($key1);
+    my $uri2 = $neb->create_object($key2);
 
-    ok($neb->swap_objects("foo1", "foo2"), "swap succeeded");
+    ok($neb->swap_objects($key1, $key2), "swap succeeded");
 
-    my $new_uri1 = ($neb->find_instances("foo1"))->[0];
-    my $new_uri2 = ($neb->find_instances("foo2"))->[0];
+    my $new_uri1 = ($neb->find_instances($key1))->[0];
+    my $new_uri2 = ($neb->find_instances($key2))->[0];
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 1],
+        storage_object  => [so_id => 2, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 1],
+    );
+
+    is($uri1, $new_uri2, "key1 -> key2");
+    is($uri2, $new_uri1, "key2 -> key1");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key1 = "foo1";
+    my $key2 = "a/foo2";
+    my $uri1 = $neb->create_object($key1);
+    my $uri2 = $neb->create_object($key2);
+
+    ok($neb->swap_objects($key1, $key2), "swap succeeded");
+
+    my $new_uri1 = ($neb->find_instances($key1))->[0];
+    my $new_uri2 = ($neb->find_instances($key2))->[0];
+
+    expected_dataset_ok(
+        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
+        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
+        storage_object  => [so_id => 1, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 2],
+        storage_object  => [so_id => 2, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 1],
+    );
 
     is($uri1, $new_uri2, "key1 -> key2");
Index: trunk/Nebulous-Server/t/75_parse_neb_key.t
===================================================================
--- trunk/Nebulous-Server/t/75_parse_neb_key.t	(revision 22718)
+++ trunk/Nebulous-Server/t/75_parse_neb_key.t	(revision 23932)
@@ -10,9 +10,9 @@
 use Test::More;
 
-plan tests => 80;
+plan tests => 99;
 
 use lib qw( ./t ./lib );
 
-use Nebulous::Keys qw( parse_neb_key );
+use Nebulous::Key qw( parse_neb_key );
 use Test::Nebulous;
 
@@ -224,4 +224,53 @@
 }
 
+# root volume references
+{
+    my $key = parse_neb_key('neb:///');
+
+    is($key->path, '', 'path');
+    is($key->volume, undef, 'volume name');
+    is($key->soft_volume, undef, 'soft volume name');
+}
+
+{
+    my $key = parse_neb_key('neb:///.');
+
+    is($key->path, '', 'path');
+    is($key->volume, undef, 'volume name');
+    is($key->soft_volume, undef, 'soft volume name');
+}
+
+{
+    my $key = parse_neb_key('neb:///..');
+
+    is($key->path, '', 'path');
+    is($key->volume, undef, 'volume name');
+    is($key->soft_volume, undef, 'soft volume name');
+}
+
+{
+    my $key = parse_neb_key('/');
+
+    is($key->path, '', 'path');
+    is($key->volume, undef, 'volume name');
+    is($key->soft_volume, undef, 'soft volume name');
+}
+
+{
+    my $key = parse_neb_key('.');
+
+    is($key->path, '', 'path');
+    is($key->volume, undef, 'volume name');
+    is($key->soft_volume, undef, 'soft volume name');
+}
+
+{
+    my $key = parse_neb_key('..');
+
+    is($key->path, '', 'path');
+    is($key->volume, undef, 'volume name');
+    is($key->soft_volume, undef, 'soft volume name');
+}
+
 # key w/ whitespace
 eval {
@@ -267,2 +316,8 @@
 };
 like( $@, qr/requires a leading slash/, "leading slash" );
+
+# URI w/ volume but w/o path
+eval {
+    my $key = parse_neb_key('neb://foo');
+};
+like( $@, qr/requires a path/, "no path" );
