Index: /trunk/Nebulous-Server/Changes
===================================================================
--- /trunk/Nebulous-Server/Changes	(revision 13172)
+++ /trunk/Nebulous-Server/Changes	(revision 13173)
@@ -2,4 +2,9 @@
 
 0.05
+    - better paramter checking
+    - overhaul instance table
+    - add ->_is_valid_object_key() method
+    - change ->find_instances() to check it's params and only return instances
+      on mounted & available volumes
     - add volume.available field and logic to use it
     - add volume.allocate field and logic to use it
Index: /trunk/Nebulous-Server/MANIFEST
===================================================================
--- /trunk/Nebulous-Server/MANIFEST	(revision 13172)
+++ /trunk/Nebulous-Server/MANIFEST	(revision 13173)
@@ -87,4 +87,5 @@
 t/09_server_stat_object.t
 t/10_server_is_valid_volume_name.t
+t/11_server_is_valid_object_key.t
 t/12_server_find_objects.t
 t/13_server_rename_object.t
Index: /trunk/Nebulous-Server/lib/Nebulous/Server.pm
===================================================================
--- /trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 13172)
+++ /trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 13173)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.31 2007-05-02 20:53:42 jhoblitt Exp $
+# $Id: Server.pm,v 1.32 2007-05-03 01:44:23 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -283,10 +283,17 @@
     my $self = shift;
 
-    my ($key, $volume) = validate_pos(@_,
-        {
-            type        => SCALAR,
-        },
-        {
-            type        => SCALAR,
+    my ($key, $vol_name) = validate_pos(@_,
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+            },
+        },
+        {
+            type        => SCALAR,
+            callbacks   => {
+                # check that the volume name requested is valid
+                'is valid volume name' => sub { $self->_is_valid_volume_name($_[0]) },
+            },
             optional    => 1,
         },
@@ -301,5 +308,5 @@
     my ($vol_id, $vol_path);
     eval {
-        ($vol_id, $vol_path) = $self->_get_storage_volume($volume);
+        ($vol_id, $vol_path) = $self->_get_storage_volume($vol_name);
     };
     if ($@) {
@@ -312,5 +319,5 @@
         {
             my $query = $db->prepare_cached( $sql->get_object_instances );
-            my $rows = $query->execute( $key );
+            my $rows = $query->execute($key, 1);
 
             unless ( $rows > 0 ) {
@@ -866,10 +873,17 @@
     my $self = shift;
 
-    my ( $key, $volume ) = validate_pos( @_,
-        {
-            type        => SCALAR,
-        },
-        {
-            type        => SCALAR,
+    my ($key, $vol_name) = validate_pos(@_,
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+            },
+        },
+        {
+            type        => SCALAR,
+            callbacks   => {
+                # check that the volume name requested is valid
+                'is valid volume name' => sub { $self->_is_valid_volume_name($_[0]) },
+            },
             optional    => 1,
         },
@@ -880,26 +894,45 @@
     my $db  =$self->db;
 
-    $log->debug( "entered - @_" );
-
-    # TODO restrict search to a volume
+    $log->debug("entered - @_");
 
     my $query;
-
-    eval {
-        $query = $db->prepare_cached( $sql->get_object_instances );
-        $query->execute( $key );
-    };
-    $log->logdie( "database error: $@" ) if $@;
+    eval {
+        {
+            # ask the db to generate the table of mounted Nebulous volume 
+            my $query = $db->prepare_cached("call getmountedvol()");
+            $query->execute();
+        }
+
+        if ($vol_name) {
+            $query = $db->prepare_cached( $sql->get_object_instances_by_vol_name );
+            # ext_id, name, available
+            my $rows = $query->execute($key, $vol_name, 1);
+            unless ($rows > 0) {
+                $query->finish;
+                $log->logdie("no instances on storage volume: $vol_name or volume is not available");
+            }
+        } else {
+            $query = $db->prepare_cached( $sql->get_object_instances );
+            # ext_id, available
+            my $rows = $query->execute($key, 1);
+            unless ($rows > 0) {
+                $query->finish;
+                $log->logdie("no instances available");
+            }
+        }
+    };
+    $log->logdie("database error: $@") if $@;
 
     my @locations;
 
-    while ( my $row = $query->fetchrow_hashref ) {
+    while (my $row = $query->fetchrow_hashref) {
         my $instance = $row->{ 'uri' };
         push @locations, $instance if $instance;
     }
 
-    $log->logdie( "no instances found" ) unless ( scalar @locations );
-
-    $log->debug( "leaving" );
+    # XXX remove this?
+    $log->logdie("no instances found") unless (scalar @locations);
+
+    $log->debug("leaving");
 
     return \@locations;
@@ -1089,4 +1122,30 @@
 }
 
+sub _is_valid_object_key  {
+    my ($self, $key) = @_;
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    my $ext_id;
+    eval {
+        my $query = $db->prepare_cached( $sql->get_object ); 
+        $query->execute($key);
+        ($ext_id) = $query->fetchrow_array;
+        $query->finish;
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie( "database error: $@" );
+    }
+
+    if (defined $ext_id) {
+        return 1;
+    } 
+
+    return;
+}
+
 sub _is_valid_volume_name  {
     my ($self, $vol_name) = @_;
Index: /trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm
===================================================================
--- /trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 13172)
+++ /trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 13173)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: SQL.pm,v 1.33 2007-05-02 20:53:42 jhoblitt Exp $
+# $Id: SQL.pm,v 1.34 2007-05-03 01:44:24 jhoblitt Exp $
 
 package Nebulous::Server::SQL;
@@ -144,11 +144,30 @@
         WHERE so_id = ?
     },
-    get_object_instances        => qq{
-        SELECT storage_object.so_id,
-            uri, assigned_location
-        FROM storage_object
-        LEFT JOIN instance
-        USING (so_id)
-        WHERE ext_id = ?
+    get_object_instances    => qq{
+        SELECT
+            storage_object.so_id,
+            uri,
+            assigned_vol_id
+        FROM storage_object
+        JOIN instance
+            USING (so_id)
+        JOIN mountedvol
+            USING(vol_id)
+        WHERE ext_id = ?
+            AND available = ?
+    },
+    get_object_instances_by_vol_name => qq{
+        SELECT
+            storage_object.so_id,
+            uri,
+            assigned_vol_id
+        FROM storage_object
+        JOIN instance
+            USING (so_id)
+        JOIN mountedvol
+            USING(vol_id)
+        WHERE ext_id = ?
+            AND name = ?
+            AND available = ?
     },
     get_storage_volume_byname   => qq{
@@ -284,5 +303,5 @@
     uri VARCHAR(255) NOT NULL,
     sha1sum CHAR(40) ASCII,
-    assigned_location BOOL,
+    assigned_vol_id INT,
     epoch TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     mtime TIMESTAMP,
Index: /trunk/Nebulous-Server/t/04_server_replicate_object.t
===================================================================
--- /trunk/Nebulous-Server/t/04_server_replicate_object.t	(revision 13172)
+++ /trunk/Nebulous-Server/t/04_server_replicate_object.t	(revision 13173)
@@ -3,10 +3,10 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 04_server_replicate_object.t,v 1.7 2007-04-23 20:42:29 jhoblitt Exp $
+# $Id: 04_server_replicate_object.t,v 1.8 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
 use warnings FATAL => qw( all );
 
-use Test::More tests => 11;
+use Test::More tests => 12;
 
 use lib qw( ./t ./lib );
@@ -72,7 +72,15 @@
 
 eval {
-    $neb->replicate_object("foo");
+    $neb->replicate_object('foo');
 };
-like($@, qr/storage object does not exist/, "storage object does not exist");
+like($@, qr/is valid object key/, 'storage object does not exist');
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create_object('foo');
+    $neb->replicate_object('foo', 'bar');
+};
+like($@, qr/is valid volume name/, 'storage volume does not exist');
 
 Test::Nebulous->setup;
@@ -81,12 +89,13 @@
     $neb->replicate_object();
 };
-like($@, qr/1 - 2 were expected/, "no params");
+like($@, qr/1 - 2 were expected/, 'no params');
 
 Test::Nebulous->setup;
 
 eval {
-    $neb->replicate_object(1, 2, 3);
+    $neb->create_object('foo');
+    $neb->replicate_object('foo', 'node01', 3);
 };
-like($@, qr/1 - 2 were expected/, "too many params");
+like($@, qr/1 - 2 were expected/, 'too many params');
 
 Test::Nebulous->cleanup;
Index: /trunk/Nebulous-Server/t/07_server_find_instances.t
===================================================================
--- /trunk/Nebulous-Server/t/07_server_find_instances.t	(revision 13172)
+++ /trunk/Nebulous-Server/t/07_server_find_instances.t	(revision 13173)
@@ -3,10 +3,10 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 07_server_find_instances.t,v 1.7 2007-03-28 21:48:24 jhoblitt Exp $
+# $Id: 07_server_find_instances.t,v 1.8 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
 use warnings FATAL => qw( all );
 
-use Test::More tests => 13;
+use Test::More tests => 15;
 
 use lib qw( ./t ./lib );
@@ -53,7 +53,7 @@
 {
     # key, volume
-    my $uri = $neb->create_object("foo");
+    my $uri = $neb->create_object('foo', 'node01');
 
-    my $locations = $neb->find_instances("foo", "node01");
+    my $locations = $neb->find_instances('foo', 'node01');
 
     uri_scheme_ok($locations->[0], 'file');
@@ -75,11 +75,30 @@
 }
 
+# object exists but instance is on a different volume
+Test::Nebulous->setup;
+
+eval {
+    # key, volume
+    my $uri = $neb->create_object('foo', 'node01');
+
+    my $locations = $neb->find_instances('foo', 'node02');
+};
+like($@, qr/no instances on storage volume/, 'instances on a different volume');
+
 
 Test::Nebulous->setup;
 
 eval {
-    $neb->find_instances("foo");
+    $neb->find_instances('foo');
 };
-like($@, qr/no instances found/, "storage object does not exist");
+like($@, qr/is valid object key/, "storage object does not exist");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create_object('foo');
+    $neb->find_instances('foo', 'bar');
+};
+like($@, qr/is valid volume name/, "storage volume does not exist");
 
 Test::Nebulous->setup;
@@ -93,5 +112,6 @@
 
 eval {
-    $neb->find_instances("foo", 'read', 3);
+    $neb->create_object('foo');
+    $neb->find_instances('foo', 'node01', 3);
 };
 like($@, qr/1 - 2 were expected/, "too many params");
Index: /trunk/Nebulous-Server/t/08_server_delete_instance.t
===================================================================
--- /trunk/Nebulous-Server/t/08_server_delete_instance.t	(revision 13172)
+++ /trunk/Nebulous-Server/t/08_server_delete_instance.t	(revision 13173)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 08_server_delete_instance.t,v 1.7 2007-03-28 21:50:26 jhoblitt Exp $
+# $Id: 08_server_delete_instance.t,v 1.8 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
@@ -47,5 +47,5 @@
         $neb->find_instances("foo");
     };
-    like($@, qr/no instances found/, "storage object was deleted");
+    like($@, qr/is valid object key/, "storage object was deleted");
 }
 
Index: /trunk/Nebulous-Server/t/11_server_is_valid_object_key.t
===================================================================
--- /trunk/Nebulous-Server/t/11_server_is_valid_object_key.t	(revision 13173)
+++ /trunk/Nebulous-Server/t/11_server_is_valid_object_key.t	(revision 13173)
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2005  Joshua Hoblitt
+#
+# $Id: 11_server_is_valid_object_key.t,v 1.1 2007-05-03 01:44:24 jhoblitt Exp $
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Test::More tests => 2;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Server;
+use Nebulous::Util qw( :standard );
+use Test::Nebulous;
+
+my $neb = Nebulous::Server->new(
+    dsn         => "DBI:mysql:database=test:host=localhost",
+    dbuser      => "test",
+    dbpasswd    => "",
+);
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object('foo');
+
+    ok($neb->_is_valid_object_key('foo'), "valid object key");
+}
+
+Test::Nebulous->setup;
+
+{
+    ok(!$neb->_is_valid_object_key('foo'), "invalid object key");
+}
+
+Test::Nebulous->cleanup;
Index: /trunk/Nebulous/Changes
===================================================================
--- /trunk/Nebulous/Changes	(revision 13172)
+++ /trunk/Nebulous/Changes	(revision 13173)
@@ -2,4 +2,9 @@
 
 0.05
+    - better paramter checking
+    - overhaul instance table
+    - add ->_is_valid_object_key() method
+    - change ->find_instances() to check it's params and only return instances
+      on mounted & available volumes
     - add volume.available field and logic to use it
     - add volume.allocate field and logic to use it
Index: /trunk/Nebulous/MANIFEST
===================================================================
--- /trunk/Nebulous/MANIFEST	(revision 13172)
+++ /trunk/Nebulous/MANIFEST	(revision 13173)
@@ -87,4 +87,5 @@
 t/09_server_stat_object.t
 t/10_server_is_valid_volume_name.t
+t/11_server_is_valid_object_key.t
 t/12_server_find_objects.t
 t/13_server_rename_object.t
Index: /trunk/Nebulous/lib/Nebulous/Server.pm
===================================================================
--- /trunk/Nebulous/lib/Nebulous/Server.pm	(revision 13172)
+++ /trunk/Nebulous/lib/Nebulous/Server.pm	(revision 13173)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.31 2007-05-02 20:53:42 jhoblitt Exp $
+# $Id: Server.pm,v 1.32 2007-05-03 01:44:23 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -283,10 +283,17 @@
     my $self = shift;
 
-    my ($key, $volume) = validate_pos(@_,
-        {
-            type        => SCALAR,
-        },
-        {
-            type        => SCALAR,
+    my ($key, $vol_name) = validate_pos(@_,
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+            },
+        },
+        {
+            type        => SCALAR,
+            callbacks   => {
+                # check that the volume name requested is valid
+                'is valid volume name' => sub { $self->_is_valid_volume_name($_[0]) },
+            },
             optional    => 1,
         },
@@ -301,5 +308,5 @@
     my ($vol_id, $vol_path);
     eval {
-        ($vol_id, $vol_path) = $self->_get_storage_volume($volume);
+        ($vol_id, $vol_path) = $self->_get_storage_volume($vol_name);
     };
     if ($@) {
@@ -312,5 +319,5 @@
         {
             my $query = $db->prepare_cached( $sql->get_object_instances );
-            my $rows = $query->execute( $key );
+            my $rows = $query->execute($key, 1);
 
             unless ( $rows > 0 ) {
@@ -866,10 +873,17 @@
     my $self = shift;
 
-    my ( $key, $volume ) = validate_pos( @_,
-        {
-            type        => SCALAR,
-        },
-        {
-            type        => SCALAR,
+    my ($key, $vol_name) = validate_pos(@_,
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+            },
+        },
+        {
+            type        => SCALAR,
+            callbacks   => {
+                # check that the volume name requested is valid
+                'is valid volume name' => sub { $self->_is_valid_volume_name($_[0]) },
+            },
             optional    => 1,
         },
@@ -880,26 +894,45 @@
     my $db  =$self->db;
 
-    $log->debug( "entered - @_" );
-
-    # TODO restrict search to a volume
+    $log->debug("entered - @_");
 
     my $query;
-
-    eval {
-        $query = $db->prepare_cached( $sql->get_object_instances );
-        $query->execute( $key );
-    };
-    $log->logdie( "database error: $@" ) if $@;
+    eval {
+        {
+            # ask the db to generate the table of mounted Nebulous volume 
+            my $query = $db->prepare_cached("call getmountedvol()");
+            $query->execute();
+        }
+
+        if ($vol_name) {
+            $query = $db->prepare_cached( $sql->get_object_instances_by_vol_name );
+            # ext_id, name, available
+            my $rows = $query->execute($key, $vol_name, 1);
+            unless ($rows > 0) {
+                $query->finish;
+                $log->logdie("no instances on storage volume: $vol_name or volume is not available");
+            }
+        } else {
+            $query = $db->prepare_cached( $sql->get_object_instances );
+            # ext_id, available
+            my $rows = $query->execute($key, 1);
+            unless ($rows > 0) {
+                $query->finish;
+                $log->logdie("no instances available");
+            }
+        }
+    };
+    $log->logdie("database error: $@") if $@;
 
     my @locations;
 
-    while ( my $row = $query->fetchrow_hashref ) {
+    while (my $row = $query->fetchrow_hashref) {
         my $instance = $row->{ 'uri' };
         push @locations, $instance if $instance;
     }
 
-    $log->logdie( "no instances found" ) unless ( scalar @locations );
-
-    $log->debug( "leaving" );
+    # XXX remove this?
+    $log->logdie("no instances found") unless (scalar @locations);
+
+    $log->debug("leaving");
 
     return \@locations;
@@ -1089,4 +1122,30 @@
 }
 
+sub _is_valid_object_key  {
+    my ($self, $key) = @_;
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    my $ext_id;
+    eval {
+        my $query = $db->prepare_cached( $sql->get_object ); 
+        $query->execute($key);
+        ($ext_id) = $query->fetchrow_array;
+        $query->finish;
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie( "database error: $@" );
+    }
+
+    if (defined $ext_id) {
+        return 1;
+    } 
+
+    return;
+}
+
 sub _is_valid_volume_name  {
     my ($self, $vol_name) = @_;
Index: /trunk/Nebulous/lib/Nebulous/Server/SQL.pm
===================================================================
--- /trunk/Nebulous/lib/Nebulous/Server/SQL.pm	(revision 13172)
+++ /trunk/Nebulous/lib/Nebulous/Server/SQL.pm	(revision 13173)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: SQL.pm,v 1.33 2007-05-02 20:53:42 jhoblitt Exp $
+# $Id: SQL.pm,v 1.34 2007-05-03 01:44:24 jhoblitt Exp $
 
 package Nebulous::Server::SQL;
@@ -144,11 +144,30 @@
         WHERE so_id = ?
     },
-    get_object_instances        => qq{
-        SELECT storage_object.so_id,
-            uri, assigned_location
-        FROM storage_object
-        LEFT JOIN instance
-        USING (so_id)
-        WHERE ext_id = ?
+    get_object_instances    => qq{
+        SELECT
+            storage_object.so_id,
+            uri,
+            assigned_vol_id
+        FROM storage_object
+        JOIN instance
+            USING (so_id)
+        JOIN mountedvol
+            USING(vol_id)
+        WHERE ext_id = ?
+            AND available = ?
+    },
+    get_object_instances_by_vol_name => qq{
+        SELECT
+            storage_object.so_id,
+            uri,
+            assigned_vol_id
+        FROM storage_object
+        JOIN instance
+            USING (so_id)
+        JOIN mountedvol
+            USING(vol_id)
+        WHERE ext_id = ?
+            AND name = ?
+            AND available = ?
     },
     get_storage_volume_byname   => qq{
@@ -284,5 +303,5 @@
     uri VARCHAR(255) NOT NULL,
     sha1sum CHAR(40) ASCII,
-    assigned_location BOOL,
+    assigned_vol_id INT,
     epoch TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     mtime TIMESTAMP,
Index: /trunk/Nebulous/t/04_server_replicate_object.t
===================================================================
--- /trunk/Nebulous/t/04_server_replicate_object.t	(revision 13172)
+++ /trunk/Nebulous/t/04_server_replicate_object.t	(revision 13173)
@@ -3,10 +3,10 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 04_server_replicate_object.t,v 1.7 2007-04-23 20:42:29 jhoblitt Exp $
+# $Id: 04_server_replicate_object.t,v 1.8 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
 use warnings FATAL => qw( all );
 
-use Test::More tests => 11;
+use Test::More tests => 12;
 
 use lib qw( ./t ./lib );
@@ -72,7 +72,15 @@
 
 eval {
-    $neb->replicate_object("foo");
+    $neb->replicate_object('foo');
 };
-like($@, qr/storage object does not exist/, "storage object does not exist");
+like($@, qr/is valid object key/, 'storage object does not exist');
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create_object('foo');
+    $neb->replicate_object('foo', 'bar');
+};
+like($@, qr/is valid volume name/, 'storage volume does not exist');
 
 Test::Nebulous->setup;
@@ -81,12 +89,13 @@
     $neb->replicate_object();
 };
-like($@, qr/1 - 2 were expected/, "no params");
+like($@, qr/1 - 2 were expected/, 'no params');
 
 Test::Nebulous->setup;
 
 eval {
-    $neb->replicate_object(1, 2, 3);
+    $neb->create_object('foo');
+    $neb->replicate_object('foo', 'node01', 3);
 };
-like($@, qr/1 - 2 were expected/, "too many params");
+like($@, qr/1 - 2 were expected/, 'too many params');
 
 Test::Nebulous->cleanup;
Index: /trunk/Nebulous/t/07_server_find_instances.t
===================================================================
--- /trunk/Nebulous/t/07_server_find_instances.t	(revision 13172)
+++ /trunk/Nebulous/t/07_server_find_instances.t	(revision 13173)
@@ -3,10 +3,10 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 07_server_find_instances.t,v 1.7 2007-03-28 21:48:24 jhoblitt Exp $
+# $Id: 07_server_find_instances.t,v 1.8 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
 use warnings FATAL => qw( all );
 
-use Test::More tests => 13;
+use Test::More tests => 15;
 
 use lib qw( ./t ./lib );
@@ -53,7 +53,7 @@
 {
     # key, volume
-    my $uri = $neb->create_object("foo");
+    my $uri = $neb->create_object('foo', 'node01');
 
-    my $locations = $neb->find_instances("foo", "node01");
+    my $locations = $neb->find_instances('foo', 'node01');
 
     uri_scheme_ok($locations->[0], 'file');
@@ -75,11 +75,30 @@
 }
 
+# object exists but instance is on a different volume
+Test::Nebulous->setup;
+
+eval {
+    # key, volume
+    my $uri = $neb->create_object('foo', 'node01');
+
+    my $locations = $neb->find_instances('foo', 'node02');
+};
+like($@, qr/no instances on storage volume/, 'instances on a different volume');
+
 
 Test::Nebulous->setup;
 
 eval {
-    $neb->find_instances("foo");
+    $neb->find_instances('foo');
 };
-like($@, qr/no instances found/, "storage object does not exist");
+like($@, qr/is valid object key/, "storage object does not exist");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create_object('foo');
+    $neb->find_instances('foo', 'bar');
+};
+like($@, qr/is valid volume name/, "storage volume does not exist");
 
 Test::Nebulous->setup;
@@ -93,5 +112,6 @@
 
 eval {
-    $neb->find_instances("foo", 'read', 3);
+    $neb->create_object('foo');
+    $neb->find_instances('foo', 'node01', 3);
 };
 like($@, qr/1 - 2 were expected/, "too many params");
Index: /trunk/Nebulous/t/08_server_delete_instance.t
===================================================================
--- /trunk/Nebulous/t/08_server_delete_instance.t	(revision 13172)
+++ /trunk/Nebulous/t/08_server_delete_instance.t	(revision 13173)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 08_server_delete_instance.t,v 1.7 2007-03-28 21:50:26 jhoblitt Exp $
+# $Id: 08_server_delete_instance.t,v 1.8 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
@@ -47,5 +47,5 @@
         $neb->find_instances("foo");
     };
-    like($@, qr/no instances found/, "storage object was deleted");
+    like($@, qr/is valid object key/, "storage object was deleted");
 }
 
Index: /trunk/Nebulous/t/11_server_is_valid_object_key.t
===================================================================
--- /trunk/Nebulous/t/11_server_is_valid_object_key.t	(revision 13173)
+++ /trunk/Nebulous/t/11_server_is_valid_object_key.t	(revision 13173)
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2005  Joshua Hoblitt
+#
+# $Id: 11_server_is_valid_object_key.t,v 1.1 2007-05-03 01:44:24 jhoblitt Exp $
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Test::More tests => 2;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Server;
+use Nebulous::Util qw( :standard );
+use Test::Nebulous;
+
+my $neb = Nebulous::Server->new(
+    dsn         => "DBI:mysql:database=test:host=localhost",
+    dbuser      => "test",
+    dbpasswd    => "",
+);
+
+Test::Nebulous->setup;
+
+{
+    $neb->create_object('foo');
+
+    ok($neb->_is_valid_object_key('foo'), "valid object key");
+}
+
+Test::Nebulous->setup;
+
+{
+    ok(!$neb->_is_valid_object_key('foo'), "invalid object key");
+}
+
+Test::Nebulous->cleanup;
Index: /trunk/Nebulous/t/53_client_cull.t
===================================================================
--- /trunk/Nebulous/t/53_client_cull.t	(revision 13172)
+++ /trunk/Nebulous/t/53_client_cull.t	(revision 13173)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 53_client_cull.t,v 1.2 2007-04-27 21:36:20 jhoblitt Exp $
+# $Id: 53_client_cull.t,v 1.3 2007-05-03 01:44:24 jhoblitt Exp $
 
 use strict;
@@ -14,5 +14,5 @@
 use lib qw( ./t ./lib );
 
-use Nebulous::Client;
+use Nebulous::Client trace => 'debug';
 use Nebulous::Util qw( :standard );
 use Test::Nebulous;
@@ -96,4 +96,5 @@
 }
 
+die;
 Test::Nebulous->setup;
 
