IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 41172


Ignore:
Timestamp:
Nov 27, 2019, 12:04:14 PM (7 years ago)
Author:
eugene
Message:

merging updates to Nebulous from EAM dev branch ipp-20191011

Location:
trunk
Files:
1 deleted
45 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/Nebulous-Server/Build.PL

    r39926 r41172  
    4343    },
    4444    script_files        => [qw(
    45         bin/neb-admin
    46         bin/neb-fsck
    4745        bin/neb-cabadd
    4846        bin/neb-voladd
     
    5452    )],
    5553)->create_build_script;
     54
     55# these scripts are no longer installed (2019.10.31)
     56#       bin/neb-admin
     57#       bin/neb-fsck
  • trunk/Nebulous-Server/MANIFEST

    r32383 r41172  
    44MANIFEST
    55README
    6 bin/neb-admin
    7 bin/neb-fsck
    8 bin/neb-initdb
    96bin/neb-voladd
    107bin/neb-cabadd
  • trunk/Nebulous-Server/bin/neb-voladd

    r28492 r41172  
    4343
    4444my $dbh = DBI->connect(
     45    # if you want to work with the localhost database but get socket path errors,
     46    # you should set the server host as 127.0.0.1 (not localhost)
     47
     48    # the following tells DBI to read the mysql/my.cnf files
     49    #  "DBI:mysql:database=$db:host=$dbhost:mysql_read_default_group=dbd_mysql",
     50
    4551    "DBI:mysql:database=$db:host=$dbhost",
    4652    $dbuser,
  • trunk/Nebulous-Server/docs/apache2-mod_perl-startup.pl

    r23687 r41172  
    2828use Nebulous::Server;
    2929
    30 my $dsn         = 'DBI:mysql:database=nebulous:host=ipp019.ifa.hawaii.edu';
     30my $dsn         = 'DBI:mysql:database=nebulous:host=nebulous.ipp.ifa.hawaii.edu';
    3131my $dbuser      = 'nebulous';
    32 my $dbpasswd    = '@neb@';
     32my $dbpasswd    = 'XXXX';
    3333
    3434#$Apache::DBI::DEBUG = 1;
    3535#Apache::DBI->connect_on_init( $dsn, $dbuser, $dbpasswd );
    3636Apache::DBI->setPingTimeOut($dsn, 10);
    37 Nebulous::Server::SOAP->new_on_init(
     37
     38my $config = Nebulous::Server::Config->new(
     39    trace       => 'warn',
     40                                           );
     41$config->add_db(
     42    dbindex     => 0,
    3843    dsn         => $dsn,
    3944    dbuser      => $dbuser,
    4045    dbpasswd    => $dbpasswd,
    41     log_level   => 'all',
    42 );
     46                );
     47
     48Nebulous::Server::SOAP->new_on_init($config);
     49
    4350
    44511;
  • trunk/Nebulous-Server/docs/install.txt

    r23687 r41172  
    5555    export NEB_PASS=@neb@
    5656
     57    *** this is very dangerous and should only be run in test examples:
    5758    neb-initdb
    5859
    59     neb-voladd --vhost ipp000 --vname ipp000.0 --uri file:///data/ipp000.0/nebulous
    60     neb-voladd --vhost ipp001 --vname ipp000.1 --uri file:///data/ipp000.1/nebulous
    61     neb-voladd --vhost ipp002 --vname ipp002.0 --uri file:///data/ipp002.0/nebulous
    62     neb-voladd --vhost ipp003 --vname ipp003.0 --uri file:///data/ipp003.0/nebulous
    63     neb-voladd --vhost ipp022 --vname ipp022.0 --uri file:///data/ipp022.0/nebulous
     60    neb-voladd --vhost ipp000 --vname ipp000.0 --uri file:///data/ipp000.0/nebulous --mountpoint /data/ipp000.0/nebulous
     61    neb-voladd --vhost ipp001 --vname ipp000.1 --uri file:///data/ipp000.1/nebulous --mountpoint /data/ipp000.1/nebulous
     62    neb-voladd --vhost ipp002 --vname ipp002.0 --uri file:///data/ipp002.0/nebulous --mountpoint /data/ipp002.0/nebulous
     63    neb-voladd --vhost ipp003 --vname ipp003.0 --uri file:///data/ipp003.0/nebulous --mountpoint /data/ipp003.0/nebulous
     64    neb-voladd --vhost ipp022 --vname ipp022.0 --uri file:///data/ipp022.0/nebulous --mountpoint /data/ipp022.0/nebulous
    6465
    6566    # or in bulk:
  • trunk/Nebulous-Server/lib/Nebulous/Server.pm

    r39926 r41172  
    1313use base qw( Class::Accessor::Fast );
    1414
     15use Carp;
     16
    1517use Cache::Memcached;
    1618use DBI;
     19
     20## for gentoo:
    1721use Digest::SHA1 qw( sha1_hex );
     22
     23## for ubuntu:
     24# use Digest::SHA qw( sha1_hex );
     25
    1826use Fcntl ':mode';
    1927use File::Basename qw( basename dirname fileparse );
     
    7785        Cache::Memcached->new({
    7886            servers => $config->memcached_servers,
    79        })
    80     );
     87                              })
     88        );
    8189#    $self->cache->set("foo", "bar") or die "set failed";
    8290#    $self->cache->get("foo") or die "get failed";
     
    215223}
    216224
     225my $get_storage_volume_calls = 0;
     226
    217227sub create_object
    218228{
     
    252262    # the key's volume can't be validiated on input for this method so we have
    253263    # to check it after parsing the key
    254     if (defined $vol_name
    255         and not $self->_is_valid_volume_name($key, $key->volume)) {
     264    if (defined $vol_name and not $self->_is_valid_volume_name($key, $key->volume)) {
    256265        unless ($key->hard_volume) {
    257266            $log->warn( "$vol_name is not a known volume name" );
     
    262271    }
    263272       
     273    $get_storage_volume_calls = 0;
     274
    264275    my ($vol_id, $vol_host, $vol_path, $vol_xattr)
    265276        = $self->_get_storage_volume($key, $vol_name, $key->hard_volume);
     
    273284                # create storage_object
    274285                my $query = $db->prepare_cached( $sql->new_object );
    275                 $query->execute('NULL', $key->path, basename($key->path), $parent_id);
     286# bad syntax    $query->execute('NULL', $key->path, basename($key->path), $parent_id);
     287                $query->execute(0, $key->path, basename($key->path), $parent_id);
     288                $query->finish;
    276289            }
    277290
     
    292305                my $query = $db->prepare_cached( $sql->new_object_attr );
    293306                $query->execute($so_id);
     307                $query->finish;
    294308            }
    295309
     
    300314                my $query = $db->prepare_cached( $sql->new_object_instance );
    301315                $query->execute($vol_id);
     316                $query->finish;
    302317            }
    303318
     
    327342                # vol_id, uri, ins_id
    328343                $query->execute($vol_id, "$uri", $ins_id);
     344                $query->finish;
    329345            }
    330346
     
    421437                    }
    422438                    $query->finish;
     439                    $db->commit;
    423440                }
    424441
     
    441458                    my $query = $db->prepare_cached($sql->new_directory);
    442459                    $query->execute($dir, $parent_id);
     460                    $query->finish;
     461                    $db->commit;
    443462                }
    444463
     
    452471                    ($parent_id) = $query->fetchrow_array;
    453472                    $query->finish;
     473                    $db->commit;
    454474                }
    455475                die("failed to get LAST_INSERT_ID()")
    456476                    unless $parent_id;
    457 
    458                 $db->commit;
    459477            }
    460478        };
     
    712730        {
    713731            type        => SCALAR|UNDEF,
    714 #            callbacks   => {
    715 #                # check that the volume name requested is valid
    716 #                'is valid volume name' => sub {
    717 #                    return 1 if not defined $_[0];
    718 #                    $self->_is_valid_volume_name($_[0])
    719 #                },
    720 #            },
    721732            optional    => 1,
    722733        },
     
    726737
    727738    # if a volume name is explicity specified then we should make the
    728     # replication onto that volume (even if there is alread an instance on that
     739    # replication onto that volume (even if there is already an instance on that
    729740    # volume) if at all possible and throw an error if we can not.
     741
    730742    # if a volume name IS NOT specified then we should make the replication
    731743    # onto any (hopefully the best) volume that DOES NOT already have an
    732     # instance on it.  If all avilable volume already have an instance on them
     744    # instance on it.  If all available volumes already have an instance on them
    733745    # then we should throw an error
     746
    734747    # volume names implied as part of the key are *IGNORED* as the source and
    735748    # *SHOULD NOT* be used as the destination either
    736749
    737750    eval {
    738         $key = parse_neb_key($key);
     751        # EAM 2019.10.31 : if I supply dest_vol_name here, then
     752        # $key->volume will point at that volume and the section below
     753        # will correctly be testing the validity of dest_vol_name
     754        $key = parse_neb_key($key, $dest_vol_name);
    739755    };
    740756    $log->logdie("$@") if $@;
     
    742758    my $db  = $self->db($key);
    743759
     760    ## Old comment:
    744761    # puke if the source volume is bogus, we may want to actually use this as
    745762    # the instance to be copied later
    746     if (defined $key->volume
    747         and not $self->_is_valid_volume_name($key, $key->volume)) {
     763
     764    # EAM 2019.10.31 : in the past, the key-implied volume was
     765    # supplied here, which was inconsistent since above it says the
     766    # key-implied volume is ignored. By supplying $dest_vol_name to
     767    # parse_neb_key above, the key->volume now refers to the
     768    # dest_volume
     769    if (defined $key->volume and not $self->_is_valid_volume_name($key, $key->volume)) {
    748770        unless ($key->hard_volume) {
    749771            $log->warn($key->volume . " not a known volume name");
     
    752774        }
    753775    }
    754     # puke if the source volume is bogus, we may want to actually use this as
    755     # the instance to be copied later
    756     if (defined $dest_vol_name
    757         and not $self->_is_valid_volume_name($key, $dest_vol_name)) {
    758            $log->logdie($key->volume . " is not a valid volume name");
    759     }
    760        
     776
     777    # puke if the destination volume is bogus
     778    ## XXX if I supply dest_vol_name to parse_neb_key above, this section below is redundant with the above
     779    ## if (defined $dest_vol_name
     780    ##     and not $self->_is_valid_volume_name($key, $dest_vol_name)) {
     781    ##        $log->logdie($key->volume . " is not a valid volume name");
     782    ## }
     783
     784    $get_storage_volume_calls = 0;
     785
    761786    my ($vol_id, $vol_host, $vol_path, $vol_xattr);
    762787    if (defined $dest_vol_name) {
     788        # if we supplied dest_vol_name, then the call to parse_neb_key above
     789        # will have set $key->volume to that value and hard_volume to match
    763790        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    764             = $self->_get_storage_volume($key, $dest_vol_name);
     791            = $self->_get_storage_volume($key, $key->volume, $key->hard_volume);
    765792    } else {
    766793        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    767794            = $self->_get_replication_volume($key);
    768795    }
     796
     797    # print "selected target: $vol_id, $vol_host\n";
    769798
    770799    my $uri;
     
    784813                $so_id = $query->fetchrow_hashref->{ 'so_id' };
    785814                $query->finish;
     815                $db->commit;
    786816            }
    787817
     
    800830                # time LAST_INSERT_ID() is invoked
    801831                $query->finish;
     832                $db->commit;
    802833            }
    803834
     
    841872    eval {
    842873        my $mode = $self->getxattr_object("$key", 'user.mode');
    843         if (defined $mode) {
    844             $self->chmod_object("$key", $mode);
     874        if (defined $mode && $mode ne "") {
     875            $self->chmod_object("$key", $mode);
    845876        }
    846877    };
     
    852883
    853884    $log->debug("leaving");
    854 
    855885    return "$uri";
    856886}
     
    13231353            die( "xattr $key:$name does not exist" );
    13241354        }
     1355
    13251356        # if we go more then one row bad something very bad has happened.
    13261357        unless ($rows == 1) {
     
    13351366        $value = $row->{ 'value' };
    13361367    };
     1368    $db->commit;
     1369
    13371370    if ($@) {
    13381371        if ($@ =~ /user\..*? does not exist/) {
    13391372            # do not log xattr does not exist messages
     1373            # NOTE: the client is using the reported message to interpret the errors
    13401374            die $@;
    13411375        }
     
    13861420    };
    13871421    $log->logdie("database error: $@") if $@;
     1422    $db->commit;
    13881423
    13891424    $log->debug("leaving");
     
    14421477                die( "affected row count is $rows instead of 1" );
    14431478            }
    1444 
    14451479            $db->commit;
    14461480            $log->debug("commit");
     
    15451579        $work_dir = $pattern;
    15461580        $file_pattern = '%';
    1547     }
    1548     else {
     1581    } else {
    15491582        my $dir_plain = dirname($pattern);
    15501583        if ($dir_plain eq 'neb:') {
     
    15751608        my $query = $db->prepare_cached( $sql->find_dir_by_parent_id . " AND dirname LIKE ? ");
    15761609        $query->execute( $dir_id, $file_pattern );
     1610        $db->commit;
    15771611
    15781612        while ( my $row = $query->fetchrow_hashref ) {
     
    15951629        my $query = $db->prepare_cached( $sql->find_object_by_dir_id . " AND ext_id_basename LIKE ? ");
    15961630        $query->execute( $dir_id , $file_pattern);
     1631        $db->commit;
    15971632
    15981633        while ( my $row = $query->fetchrow_hashref ) {
     
    16241659    my $sql = $self->sql;
    16251660    my $db  = $self->_db_for_index($index);
    1626 
    16271661
    16281662    # first check to see if the key is an exact match
     
    16451679        $log->logdie("database error: $@");
    16461680    }
     1681    $db->commit;
    16471682
    16481683    if (scalar @keys) {
     
    16781713    };
    16791714    $log->logdie("database error: $@") if $@;
     1715    $db->commit;
    16801716
    16811717    # find files under dir
     
    16921728    };
    16931729    $log->logdie("database error: $@") if $@;
     1730    $db->commit;
    16941731
    16951732    $log->debug( "leaving" );
     
    17531790}
    17541791
     1792# sub find_instances
    17551793sub find_instances_old
    17561794{
     
    17691807        {
    17701808            type        => SCALAR|UNDEF,
    1771 #            callbacks   => {
    1772 #                # check that the volume name requested is valid
    1773 #                'is valid volume name' => sub {
    1774 #                    return 1 if not defined $_[0];
    1775 #                    $self->_is_valid_volume_name($_[0])
    1776 #                },
    1777 #            },
    17781809            optional    => 1,
    17791810        },
     
    17871818    my $sql = $self->sql;
    17881819
    1789 #    unless ($key) {
    1790 #        $log->warn("key was undefined after validate_pos(), trying again...");
    1791 #        return $self->find_instances(@_);
    1792 #    }
     1820    # default value for find_invalid is false
     1821    if (not defined $find_invalid) { $find_invalid = 0; }
    17931822
    17941823    # vol_name overrides the key implied volume
     
    18281857            my $rows;
    18291858            # ext_id, available
    1830             if (defined($find_invalid)) {
     1859            if (defined($find_invalid) and $find_invalid) {
     1860                # XXX returns instances which are NOT available
    18311861                $rows = $query->execute($key->path, 0);
    18321862            }
     
    18651895}
    18661896
    1867 #sub find_instances_by_proximity
     1897# sub find_instances_by_proximity
    18681898sub find_instances
    18691899{
     
    18821912        {
    18831913            type        => SCALAR|UNDEF,
    1884 #            callbacks   => {
    1885 #                # check that the volume name requested is valid
    1886 #                'is valid volume name' => sub {
    1887 #                    return 1 if not defined $_[0];
    1888 #                    $self->_is_valid_volume_name($_[0])
    1889 #                },
    1890 #            },
    18911914            optional    => 1,
    18921915        },
     
    18971920        },
    18981921    );
    1899 
    19001922    my $sql = $self->sql;
    19011923
    1902 #    unless ($key) {
    1903 #        $log->warn("key was undefined after validate_pos(), trying again...");
    1904 #        return $self->find_instances(@_);
    1905 #    }
     1924    if (not defined $find_invalid) { $find_invalid = 0; }
     1925
     1926    if ($find_invalid eq "find them all") {
     1927        $log->logdie("old neb-cull --one_only, neb-rm --invalid both disabled by new Server.pm");
     1928    }
    19061929
    19071930    # vol_name overrides the key implied volume
     
    19321955            }
    19331956        }
    1934 
    1935 
    19361957    }
    19371958
     
    19721993            # ext_id, name, available
    19731994            # host_vol_id host_cab_id host_site_id ext_id available
    1974             my $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 1);
     1995
     1996            my $rows;
     1997            if (defined($find_invalid) and $find_invalid) {
     1998                # returns instances which are NOT available (volume not available)
     1999                $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 0);
     2000            } else {
     2001                $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 1);
     2002            }           
    19752003            unless ($rows > 0) {
    19762004                $query->finish;
    1977                 die("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
     2005                die("no instances on storage volume or volume is not available for key: $key volume: $vol_name");
    19782006            }
    19792007        } else {
    19802008            $query = $db->prepare_cached( $sql->get_object_instances );
     2009            # ext_id, available
     2010
    19812011            my $rows;
    1982             # ext_id, available
    1983             if (defined($find_invalid)) {
     2012            if (defined($find_invalid) and $find_invalid) {
     2013                # returns instances which are NOT available (volume not available)
    19842014                $rows = $query->execute($key->path, 0);
    1985             }
    1986             else {
     2015            } else {
    19872016                $rows = $query->execute($key->path, 1);
    19882017            }
     
    19922021            }
    19932022        }
     2023        $db->commit;
     2024        ## if we do not call commit here, the transaction stays
     2025        ## open blocking some operations below.
    19942026
    19952027        while (my $row = $query->fetchrow_hashref) {
    19962028            my $instance = $row->{ 'uri' };
    19972029            push @locations, $instance if $instance;
     2030
     2031            # Carp::carp ("instance 2: $row->{ 'uri' }, $row->{ 'vol_id' }, $row->{ 'cab_id' }, $row->{ 'vol_idx' }\n");
    19982032        }
    19992033    };
     
    20032037        if (defined $vol_name and not defined $key->hard_volume) {
    20042038            $log->debug("retrying with 'any' volume");
    2005             return $self->find_instances($key->path, 'any');
     2039            return $self->find_instances($key->path, 'any', $find_invalid);
    20062040        }
    20072041        $log->logdie("database error: $@");
     
    20182052}
    20192053
     2054# this method returns instances on the specified volume
     2055# or a list of all available instances
     2056# it does NOT choose instances based on proximity
     2057# and it does NOT return invalid instances
    20202058sub find_instances_for_cull
    20212059{
     
    20612099    my $db  = $self->db($key);
    20622100
     2101    ## XXX this method is missing the alias deference section (see find_instances)
     2102    ## if aliases are intended to be compute nodes in the same cabinet / site as
     2103    ## the storage nodes, then this is not needed.
     2104
    20632105    # the key's volume can't be validiated on input for this method so we have
    20642106    # to check it after parsing the key
     
    20822124            unless ($rows > 0) {
    20832125                $query->finish;
    2084                 die("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
     2126                die("no instances on storage volume or volume is not available for key: $key volume: $vol_name");
    20852127            }
    20862128        } else {
     
    21052147        $db->rollback;
    21062148        # handle soft volumes
    2107         if (defined $vol_name and not defined $key->hard_volume) {
     2149        # we need to call find_intances_for_cull here so the returned structure
     2150        # is the same (find_instances just returns an array of strings)
     2151        if (defined $vol_name and not defined $key->hard_volume and ($vol_name ne "any")) {
    21082152            $log->debug("retrying with 'any' volume");
    2109             return $self->find_instances($key->path, 'any');
     2153            return $self->find_instances_for_cull($key->path, 'any');
    21102154        }
    21112155        $log->logdie("database error: $@");
    21122156    }
     2157    $db->commit;
    21132158
    21142159    # XXX remove this?
     
    22222267                }
    22232268            }
    2224 
    22252269            $db->commit;
    22262270            $log->debug("commit");
     
    22822326        $stat = $query->fetchrow_arrayref;
    22832327        $query->finish;
     2328        $db->commit;
    22842329    };
    22852330    $log->logdie("database error: $@") if $@;
     
    23182363    };
    23192364    $log->logdie("database error: $@") if $@;
     2365    $db->commit;
    23202366
    23212367    $log->logdie("no mounted volumes found") unless (scalar @$stats);
     
    24152461    my ($key, $name, $hard_volume) = @_;
    24162462   
    2417 #    $log->warn("_g_s_v: key:>$key< name:>$name< hard_vol:>$hard_volume<");
     2463    # track the number of calls to this function and
     2464    # give up after 10 attempts
     2465    $get_storage_volume_calls ++;
     2466
     2467#   $log->warn("_g_s_v: key:>$key< name:>$name< hard_vol:>$hard_volume<");
    24182468    my $sql = $self->sql;
    24192469    my $db  = $self->db($key);
     
    24272477            # %free, name, avaiable, allocate
    24282478            $rows = $query->execute($max_used_space, $name, 1, 1);
    2429             # XXX destinguish between non-existant and unavailable
     2479            # XXX distinguish between non-existant and unavailable
    24302480            unless ($rows > 0) {
    24312481                $query->finish;
     2482                $db->commit;
    24322483
    24332484                # if a volume name was specified, and is soft, and we failed to
     
    24422493            if ($rows > 1) {
    24432494                $query->finish;
     2495                $db->commit;
    24442496                die("affected row count is $rows instead of 1");
    24452497            }
     
    24492501            $rows = $query->execute($max_used_space, 1, 1, $topfew_count);
    24502502#           $log->warn("Storage_volume: $rows $topfew_count");
    2451             # there has to be atleast one storage volume
     2503            # there has to be at least one storage volume
    24522504            unless ($rows > 0) {
    24532505                $query->finish;
    2454                 die("no storage volume is available for key: $key volume: $name hard_volume: $hard_volume");
     2506                $db->commit;
     2507                # prevent failure in the die due to undefined variables
     2508                my $hard_volume_str = defined $hard_volume ? $hard_volume : "undefined";
     2509                my $name_str = defined $name ? $name : "undefined";
     2510                die("no storage volume is available for key: $key volume: $name_str hard_volume: $hard_volume_str");
    24552511            }
    24562512        }
     
    24652521            $log->error($@);
    24662522            $log->debug("retrying...");
    2467             return $self->_get_storage_volume(@_);
     2523            if ($get_storage_volume_calls < 10) {
     2524                return $self->_get_storage_volume(@_);
     2525            }
     2526            # else
     2527            $log->logdie("no available storage volume: $@");
    24682528        }
    24692529        # else
     
    25022562        unless ($rows > 0) {
    25032563            $query->finish;
    2504             die("Requested key $key does not exist");
     2564            die("Requested key $key does not exist (or cabinet is undefined)");
    25052565        }
    25062566        if ($rows == 1) {
     
    25132573            }
    25142574            $query->finish;
    2515         }
    2516         else {
     2575        } else {
     2576            # if instances are spread across multiple cabinets, allow the next instance to go anywhere
     2577            # NOTE: this does not prevent the new instance from going to the same volume as one of the existing instances
    25172578            $forbidden_cabinet = 0;
    25182579            $forbidden_site    = 0;
    25192580            $query->finish;
    25202581        }
    2521            
     2582        $db->commit;
    25222583
    25232584        $query = $db->prepare_cached( $sql->get_replication_volume_for_ext_id );
    2524         # ext_id, %free, avaiable, allocate
     2585        # ext_id, %free, available, allocate
     2586
    25252587        $rows = $query->execute($key->path, $max_used_space, 1, 1, $forbidden_cabinet, $forbidden_site, $topfew_count);
    2526         # XXX destinguish between non-existant and unaviable
     2588        # XXX distinguish between non-existant and unavailable
    25272589        unless ($rows > 0) {
    25282590            $query->finish;
     
    25442606        ($vol_id, $vol_host, $vol_path, $xattr, $free) = $query->fetchrow_array;
    25452607        $query->finish;
     2608        $db->commit;
    25462609    };
    25472610    $log->logdie("database error: $@") if $@;
     
    25902653        ($ext_id) = $query->fetchrow_array;
    25912654        $query->finish;
     2655        $db->commit;
     2656        ## if we do not call commit here, the transaction stays open blocking some operations below
    25922657    };
    25932658    if ($@) {
     
    26122677}
    26132678
    2614 
     2679# in the past, _is_valid_volume_name returned 'undef'. 
     2680# now it either returns 1 (success) or 0 (failure)
    26152681sub _is_valid_volume_name
    26162682{
     
    26502716        ($vol_id, $vol_path, $free) = $query->fetchrow_array;
    26512717        $query->finish;
     2718        $db->commit;
    26522719    };
    26532720    $log->logdie("database error: $@") if $@;
  • trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm

    r39926 r41172  
    574574DROP TABLE IF EXISTS directory;
    575575DROP TABLE IF EXISTS deleted;
     576DROP TABLE IF EXISTS cabinet;
     577DROP TABLE IF EXISTS aliasvol;
     578DROP TABLE IF EXISTS lost_instances;
    576579SET FOREIGN_KEY_CHECKS=1
    577580END
  • trunk/Nebulous-Server/lib/Test/Nebulous.pm

    r24540 r41172  
    1919our @EXPORT = qw( $NEB_DB $NEB_USER $NEB_PASS $NEB_MEMCACHED_SERVERS);
    2020
    21 our $NEB_DB     = $ENV{'NEB_DB'}   || "DBI:mysql:database=test:host=localhost";
    22 our $NEB_USER   = $ENV{'NEB_USER'} || "test";
    23 our $NEB_PASS   = $ENV{'NEB_PASS'} || '';
     21# require use of the test database server:
     22
     23our $NEB_DB     = "DBI:mysql:database=test:host=localhost:mysql_socket=/var/run/mysqld/mysqld.sock";
     24our $NEB_USER   = "test";
     25our $NEB_PASS   = '';
    2426our $NEB_MEMCACHED_SERVERS = ['127.0.0.1:11211'];
    2527
     
    3537my $dir6 = "";
    3638my $dir7 = "";
     39my $dir8 = "";
     40
     41sub show_setup {
     42    my $self = shift;
     43
     44    print "DB: $NEB_DB, USER: $NEB_USER, PASS: $NEB_PASS\n";
     45}
     46
    3747
    3848sub setup {
     
    4959    $dir6 = tempdir( CLEANUP => 0 );
    5060    $dir7 = tempdir( CLEANUP => 0 );
     61    $dir8 = tempdir( CLEANUP => 0 );
    5162
    5263    foreach my $statement (@{ $sql->get_db_schema }) {
     
    5465    }
    5566
    56     # node01/node02: allocate = TRUE
    57     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (1, 'node01', 'node01', ?, '/', TRUE, TRUE) }, undef, $dir1);
    58     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e7 FROM volume WHERE vol_id = ? }, undef, 1);
    59 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e7) }, undef, $dir1);
     67    # generate 2 cabinets so we can replicate to a valid location
     68    $dbh->do(qq{ INSERT INTO cabinet (name, site_id, location) values ("cab01", 1, "main") });
     69    $dbh->do(qq{ INSERT INTO cabinet (name, site_id, location) values ("cab02", 1, "main") });
     70    $dbh->do(qq{ INSERT INTO cabinet (name, site_id, location) values ("cab03", 2, "back") });
     71    $dbh->do(qq{ INSERT INTO cabinet (name, site_id, location) values ("cab04", 2, "back") });
    6072
    61     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (2, 'node02', 'node02', ?, '/', TRUE, TRUE) }, undef, $dir2);
    62     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e8 FROM volume WHERE vol_id = ? }, undef, 2);
    63 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e8) }, undef, $dir2);
     73    # node01 : allocate = TRUE (cab01, site 1)
     74    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (1, 1, 'node01', 'node01', ?, '/', TRUE, TRUE) }, undef, $dir1);
     75    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e7, note FROM volume WHERE vol_id = ? }, undef, 1);
    6476
    65     # node03: allocate = TRUE
    66     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (3, 'node03', 'node03', ?, '/', TRUE, TRUE) }, undef, $dir3);
    67     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e8 FROM volume WHERE vol_id = ? }, undef, 3);
    68 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e8) }, undef, $dir3);
     77    # node02 : allocate = TRUE (cab02, site 1)
     78    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (2, 2, 'node02', 'node02', ?, '/', TRUE, TRUE) }, undef, $dir2);
     79    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e8, note FROM volume WHERE vol_id = ? }, undef, 2);
     80
     81    # node03: allocate = TRUE (cab03, site 2)
     82    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (3, 3, 'node03', 'node03', ?, '/', TRUE, TRUE) }, undef, $dir3);
     83    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e8, note FROM volume WHERE vol_id = ? }, undef, 3);
    6984
    7085    # node04: allocate = FALSE, available = FALSE
    71     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (4, 'node04', 'node04', ?, '/', FALSE, FALSE) }, undef, $dir4);
    72     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e7 FROM volume WHERE vol_id = ? }, undef, 4);
    73 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e7) }, undef, $dir4);
     86    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (4, 1, 'node04', 'node04', ?, '/', FALSE, FALSE) }, undef, $dir4);
     87    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e8, note FROM volume WHERE vol_id = ? }, undef, 4);
    7488
    7589    # node05: allocate = FALSE, available = TRUE
    76     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (5, 'node05', 'node05', ?, '/', FALSE, TRUE) }, undef, $dir5);
    77     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e7 FROM volume WHERE vol_id = ? }, undef, 5);
    78 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e7) }, undef, $dir5);
     90    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (5, 1, 'node05', 'node05', ?, '/', FALSE, TRUE) }, undef, $dir5);
     91    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e8, note FROM volume WHERE vol_id = ? }, undef, 5);
    7992
    8093    # node06: allocate = TRUE, available = FALSE
    81     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (6, 'node06', 'node06', ?, '/', TRUE, FALSE) }, undef, $dir6);
    82     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e7 FROM volume WHERE vol_id = ? }, undef, 6);
    83 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e7) }, undef, $dir6);
     94    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (6, 1, 'node06', 'node06', ?, '/', TRUE, FALSE) }, undef, $dir6);
     95    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e8, note FROM volume WHERE vol_id = ? }, undef, 6);
    8496
    8597    # node07: full
    86     $dbh->do(qq{ INSERT INTO volume (vol_id, name, host, path, mountpoint, allocate, available) VALUES (7, 'node07', 'node07', ?, '/', TRUE, TRUE) }, undef, $dir7);
    87     $dbh->do(qq{ INSERT INTO mountedvol SELECT *, 10e10, 10e10 FROM volume WHERE vol_id = ? }, undef, 7);
    88 #    $dbh->do(qq{ INSERT INTO mount VALUES (?, 10e10, 10e10) }, undef, $dir7);
     98    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (7, 1, 'node07', 'node07', ?, '/', TRUE, TRUE) }, undef, $dir7);
     99    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e10, note FROM volume WHERE vol_id = ? }, undef, 7);
     100   
     101    # node08: allocate = TRUE, (cab04, site 2)
     102    $dbh->do(qq{ INSERT INTO volume (vol_id, cab_id, name, host, path, mountpoint, allocate, available) VALUES (8, 4, 'node08', 'node08', ?, '/', TRUE, TRUE) }, undef, $dir8);
     103    $dbh->do(qq{ INSERT INTO mountedvol SELECT vol_id,name,host,path,allocate,available,xattr,mountpoint, 10e10, 10e8, note FROM volume WHERE vol_id = ? }, undef, 8);
    89104
    90 #    $dbh->do(qq{ call getmountedvol() });
     105#   $dbh->do(qq{ call getmountedvol() });
    91106}
    92107
    93108sub cleanup {
    94109    # memcached needs to be emptied between test runs
    95         Cache::Memcached->new(servers => $NEB_MEMCACHED_SERVERS)->flush_all;
     110    Cache::Memcached->new(servers => $NEB_MEMCACHED_SERVERS)->flush_all;
    96111    # if flush_all() turns out to be useless as feared
    97112#   my $memd = Cache::Memcached->new(servers => $NEB_MEMCACHED_SERVERS);
     
    106121#   $query->finish;
    107122
     123   
    108124    foreach my $statement (@{ $sql->get_db_clear }) {
    109125        $dbh->do( $statement );
     
    118134    rmtree([$dir6], 0, 1) if -e $dir6;
    119135    rmtree([$dir7], 0, 1) if -e $dir7;
     136    rmtree([$dir8], 0, 1) if -e $dir8;
     137}
     138
     139# function to change state of one node for tests:
     140sub switch_node_state {
     141    my $self = shift;
     142
     143    $dbh->do(qq{ UPDATE volume set available = FALSE where name = 'node02'});
     144    $dbh->do(qq{ UPDATE mountedvol set available = FALSE where name = 'node02'});
     145}
     146
     147sub get_node_dirs {
     148    my $self = shift;
     149
     150    return ($dir1, $dir2, $dir3, $dir4, $dir5, $dir6, $dir7, $dir8);
    120151}
    121152
  • trunk/Nebulous-Server/t/03_server_setup.t

    r24546 r41172  
    1414use Nebulous::Server;
    1515use Test::Nebulous;
     16
     17Test::Nebulous->show_setup;
     18die "test";
    1619
    1720Test::Nebulous->setup;
  • trunk/Nebulous-Server/t/04_server_create_object.t

    r24356 r41172  
    3030
    3131Test::Nebulous->setup;
    32 
    3332{
    3433    # key
     
    4039    uri_scheme_ok($uri, 'file');
    4140
    42 SKIP: {
    43     skip "requires xattr support", 1 unless $test_xattr;
    44     is(getfattr($path, 'user.nebulous_key'), 'foo', 'user.nebulous_key xattr');
    45 }
    46 }
    47 
    48 Test::Nebulous->setup;
    49 
     41  SKIP: {
     42      skip "requires xattr support", 1 unless $test_xattr;
     43      is(getfattr($path, 'user.nebulous_key'), 'foo', 'user.nebulous_key xattr');
     44    }
     45}
     46
     47Test::Nebulous->setup;
    5048{
    5149    # key
     
    5755    uri_scheme_ok($uri, 'file');
    5856
    59 SKIP: {
    60     skip "requires xattr support", 1 unless $test_xattr;
    61     is(getfattr($path, 'user.nebulous_key'), 'foo', 'user.nebulous_key xattr');
    62 }
     57  SKIP: {
     58      skip "requires xattr support", 1 unless $test_xattr;
     59      is(getfattr($path, 'user.nebulous_key'), 'foo', 'user.nebulous_key xattr');
     60    }
    6361}
    6462
     
    528526    $neb->create_object("foo", '~node07');
    529527};
    530 like($@, qr/node07 is not available/, "request volume this is full");
     528like($@, qr/node07 is not available/, "request volume which is full");
    531529
    532530Test::Nebulous->setup;
     
    535533    $neb->create_object("neb://~node07/foo");
    536534};
    537 like($@, qr/node07 is not available/, "request volume this is full");
     535like($@, qr/node07 is not available/, "request volume which is full");
    538536
    539537Test::Nebulous->setup;
  • trunk/Nebulous-Server/t/05_server_replicate_object.t

    r24995 r41172  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 25;
     10use Test::More tests => 43;
    1111
    1212use lib qw( ./t ./lib );
     
    2828
    2929Test::Nebulous->setup;
    30 
    3130{
    3231    # key
     
    4544
    4645Test::Nebulous->setup;
    47 
    4846{
    4947    # key, $volume
     
    6260
    6361Test::Nebulous->setup;
    64 
    6562{
    6663    # key, $volume is undef
     
    7976
    8077Test::Nebulous->setup;
    81 
    8278{
    8379    # key, $volume
     
    147143}
    148144
     145# hard_volume tests:
     146
     147# replication with hard_volume:
     148Test::Nebulous->setup;
     149{
     150    my @nodedirs = Test::Nebulous->get_node_dirs();
     151
     152    # checking on replicate_object: hard_volume as node target
     153    my $uri1 = $neb->create_object("foo", "~node01");
     154    my $uri2 = $neb->replicate_object("foo", "~node02");
     155
     156    my $locations = $neb->find_instances("foo");
     157    my $Nloc = @$locations;
     158
     159    is($Nloc, 2, "found 2 instances");
     160   
     161    my $loc1 = $locations->[0];
     162    my $loc2 = $locations->[1];
     163
     164    like($loc1, qr/$nodedirs[0]/, "instance matches expected node");
     165    like($loc2, qr/$nodedirs[1]/, "instance matches expected node");
     166}
     167
     168# replication to unknown volume: should succeed
     169Test::Nebulous->setup;
     170{
     171    my @nodedirs = Test::Nebulous->get_node_dirs();
     172
     173    # checking on replicate_object, does this logic make sense?
     174    my $uri1 = $neb->create_object("foo", "~node01");
     175    my $uri2 = $neb->replicate_object("foo", "dummy");
     176
     177    my $locations = $neb->find_instances("foo");
     178    my $Nloc = @$locations;
     179
     180    is($Nloc, 2, "found 2 instances");
     181   
     182    my $loc1 = $locations->[0];
     183    my $loc2 = $locations->[1];
     184
     185    like($loc1, qr/$nodedirs[0]/, "instance matches expected node");
     186    uri_scheme_ok($loc2, 'file');
     187}
     188
     189# replication to unknown volume with hard_volume: should fail
     190Test::Nebulous->setup;
     191eval {
     192    my @nodedirs = Test::Nebulous->get_node_dirs();
     193
     194    # checking on replicate_object, does this logic make sense?
     195    my $uri1 = $neb->create_object("foo", "~node01");
     196    my $uri2 = $neb->replicate_object("foo", "~dummy");
     197
     198    my $locations = $neb->find_instances("foo");
     199};
     200like($@, qr/is not a valid volume name/, "replicate to unknown node with hard_volume should fail");
     201
     202# replication to unavailable volume: should succeed
     203Test::Nebulous->setup;
     204{
     205    my @nodedirs = Test::Nebulous->get_node_dirs();
     206
     207    # checking on replicate_object, does this logic make sense?
     208    my $uri1 = $neb->create_object("foo", "~node01");
     209    my $uri2 = $neb->replicate_object("foo", "node04");
     210
     211    my $locations = $neb->find_instances("foo");
     212    my $Nloc = @$locations;
     213
     214    is($Nloc, 2, "found 2 instances");
     215   
     216    my $loc1 = $locations->[0];
     217    my $loc2 = $locations->[1];
     218
     219    like($loc1, qr/$nodedirs[0]/, "instance matches expected node");
     220    uri_scheme_ok($loc2, 'file');
     221}
     222
     223# replication to unavailable volume with hard_volume: should fail
     224Test::Nebulous->setup;
     225eval {
     226    my @nodedirs = Test::Nebulous->get_node_dirs();
     227
     228    # checking on replicate_object, does this logic make sense?
     229    my $uri1 = $neb->create_object("foo", "~node01");
     230    my $uri2 = $neb->replicate_object("foo", "~node04");
     231
     232    my $locations = $neb->find_instances("foo");
     233};
     234like($@, qr/is not available/, "replicate to unknown node with hard_volume should fail");
     235
     236### END hard_volume tests
     237
     238### location-aware tests (do we respect the cab_id / vol_id exclusions?)
     239
     240# here are the volume definitions (Test/Nebulous.pm):
     241# name   : vol_id : cab_id : site_id : xattr
     242# node01 :      1 :      1 :       1 :     0
     243# node02 :      2 :      2 :       1 :     0
     244# node03 :      3 :      3 :       2 :     0
     245# node04 :      4 :      1 :       1 :     0
     246# node05 :      5 :      1 :       1 :     0
     247# node06 :      6 :      1 :       1 :     0
     248# node07 :      7 :      1 :       1 :     0
     249# node08 :      8 :      4 :       2 :     0
     250
     251# replication without volume
     252Test::Nebulous->setup;
     253{
     254    my @nodedirs = Test::Nebulous->get_node_dirs();
     255
     256    # checking on replicate_object: hard_volume as node target
     257    my $uri1 = $neb->create_object("foo", "~node01");
     258    my $uri2 = $neb->replicate_object("foo");
     259
     260    my $locations = $neb->find_instances("foo");
     261    my $Nloc = @$locations;
     262
     263    is($Nloc, 2, "found 2 instances");
     264   
     265    my $loc1 = $locations->[0];
     266    my $loc2 = $locations->[1];
     267
     268    # if the volume is not explicitly specified, then the first copy
     269    # should go to a different volume, cabinet, and site
     270    # if first is one node01, replication should go to node03 or node08
     271    # since those both have different site_id values
     272    like($loc1, qr/$nodedirs[0]/, "instance matches expected node");
     273
     274    my $isnode03 = $loc2 =~ m/$nodedirs[2]/;
     275    my $isnode08 = $loc2 =~ m/$nodedirs[7]/;
     276    ok($isnode03 || $isnode08, "instance matches expected node");
     277}
     278
     279# replication without volume
     280Test::Nebulous->setup;
     281{
     282    my @nodedirs = Test::Nebulous->get_node_dirs();
     283
     284    # checking on replicate_object, does this logic make sense?
     285    my $uri1 = $neb->create_object("foo", "~node03");
     286    my $uri2 = $neb->replicate_object("foo");
     287
     288    my $locations = $neb->find_instances("foo");
     289    my $Nloc = @$locations;
     290
     291    is($Nloc, 2, "found 2 instances");
     292   
     293    my $loc1 = $locations->[0];
     294    my $loc2 = $locations->[1];
     295
     296    # if the volume is not explicitly specified, then the first copy
     297    # should go to a different volume, cabinet, and site
     298    # if first is one node03, replication should go to node01 or node02
     299    # since those both have different site_id values
     300    like($loc1, qr/$nodedirs[2]/, "instance matches expected node");
     301
     302    my $isnode01 = $loc2 =~ m/$nodedirs[0]/;
     303    my $isnode02 = $loc2 =~ m/$nodedirs[1]/;
     304    ok($isnode01 || $isnode02, "instance matches expected node");
     305}
     306
    149307Test::Nebulous->setup;
    150308
  • trunk/Nebulous-Server/t/08_server_find_instances.t

    r24362 r41172  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 19;
     10use Test::More tests => 44;
    1111
    1212use lib qw( ./t ./lib );
     
    2222);
    2323
    24 Test::Nebulous->setup;
    25 
     24# XXX previously, the logic was: if we request a hard volume location
     25# using ~node, then we would give an error if no data is available except on that node.
     26
     27# the code has been modified so that the requested storage object is provided if possible,
     28# even if the apparently "hard" target did not exist.
     29
     30Test::Nebulous->setup;
     31Test::Nebulous->cleanup; # make sure the database is reset before running any tests
     32
     33# for (my $i = 0; $i < $Nloc; $i++) {
     34#       my $loc = $locations->[$i];
     35#       print "location: $loc\n";
     36#}
     37
     38Test::Nebulous->setup;
    2639{
    2740    # key
     
    3548
    3649Test::Nebulous->setup;
    37 
    3850{
    3951    # key
     
    4961
    5062Test::Nebulous->setup;
    51 
    5263{
    5364    # key, volume
     
    6172
    6273Test::Nebulous->setup;
    63 
    6474{
    6575    # key, volume
     
    7383
    7484Test::Nebulous->setup;
    75 
    7685{
    7786    # key, volume
     
    8594
    8695Test::Nebulous->setup;
    87 
    8896{
    8997    # key
     
    98106}
    99107
    100 # object exists but instance is on a different volume
    101 Test::Nebulous->setup;
    102 
     108# request from a hard_volume returns an instance which is not on the hard volume if available
     109Test::Nebulous->setup;
    103110eval {
    104111    # key, volume
    105112    my $uri = $neb->create_object('foo', '~node01');
    106 
    107113    my $locations = $neb->find_instances('foo', '~node02');
    108 };
    109 like($@, qr/no instances on storage volume/, 'instances on a different volume');
     114
     115    uri_scheme_ok($locations->[0], 'file');
     116    is($uri, $locations->[0], "URIs match");
     117};
     118is($@, "", "instance on different node (as hard_volume) returned");
     119
     120# request from a hard_volume returns an instance which is not on the hard volume if available
     121Test::Nebulous->setup;
     122eval {
     123    # key, volume
     124    my $uri = $neb->create_object('foo', '~node01');
     125    my $locations = $neb->find_instances('foo', '~node02');
     126
     127    uri_scheme_ok($locations->[0], 'file');
     128    is($uri, $locations->[0], "URIs match");
     129};
     130is($@, "", "instance on different node (as hard_volume) returned");
     131
     132### TESTS FOR INSTANCE ON INVALID NODE
     133diag ("TESTS FOR INSTANCE ON INVALID NODE");
     134
     135# request from a soft_volume for an instance which is on an invalid node (find_invalid = 1) [SOFT, 1]
     136Test::Nebulous->setup;
     137eval {
     138    # key, volume
     139    my $uri = $neb->create_object('foo', '~node02');
     140    Test::Nebulous->switch_node_state;
     141
     142    my $locations = $neb->find_instances('foo', 'node02', 1);
     143    uri_scheme_ok($locations->[0], 'file');
     144    is($uri, $locations->[0], "URIs match");
     145};
     146is($@, "", "instance on invalid node (as soft_volume) returned with find_invalid = 1");
     147
     148# request from a soft_volume for an instance which is on an invalid node (find_invalid = 0) [SOFT, 0]
     149Test::Nebulous->setup;
     150eval {
     151    # key, volume
     152    my $uri = $neb->create_object('foo', '~node02');
     153    Test::Nebulous->switch_node_state;
     154
     155    my $locations = $neb->find_instances('foo', 'node02', 0);
     156};
     157like($@, qr/database error/, "instance on invalid node (as soft_volume) not returned (find_invalid = 0)");
     158
     159# request from a hard_volume for an instance which is on an invalid node (find_instance not supplied) [SOFT, X]
     160Test::Nebulous->setup;
     161eval {
     162    # key, volume
     163    my $uri = $neb->create_object('foo', '~node02');
     164    Test::Nebulous->switch_node_state;
     165
     166    my $locations = $neb->find_instances('foo', 'node02');
     167};
     168like($@, qr/no instances available for key/, "instance on invalid node (as soft_volume) not returned (find_invalid not set)");
     169
     170# request from a hard_volume for an instance which is on an invalid node (find_invalid = 1) [HARD, 1]
     171Test::Nebulous->setup;
     172eval {
     173    # key, volume
     174    my $uri = $neb->create_object('foo', '~node02');
     175    Test::Nebulous->switch_node_state;
     176
     177    my $locations = $neb->find_instances('foo', '~node02', 1);
     178    uri_scheme_ok($locations->[0], 'file');
     179    is($uri, $locations->[0], "URIs match");
     180};
     181is($@, "", "instance on invalid node (as hard_volume) returned with find_invalid = 1");
     182
     183# request from a hard_volume for an instance which is on an invalid node (find_invalid = 0) [HARD, 0]
     184Test::Nebulous->setup;
     185eval {
     186    # key, volume
     187    my $uri = $neb->create_object('foo', '~node02');
     188    Test::Nebulous->switch_node_state;
     189
     190    my $locations = $neb->find_instances('foo', '~node02', 0);
     191};
     192like($@, qr/no instances on storage volume/, "instance on invalid node (as hard_volume) not returned (find_invalid = 0)");
     193
     194# request from a hard_volume for an instance which is on an invalid node [HARD, X]
     195Test::Nebulous->setup;
     196eval {
     197    # key, volume
     198    my $uri = $neb->create_object('foo', '~node02');
     199    Test::Nebulous->switch_node_state;
     200
     201    my $locations = $neb->find_instances('foo', '~node02');
     202};
     203like($@, qr/no instances on storage volume/, "instance on invalid node (as hard_volume) not returned (find_invalid not set)");
     204
     205#### TESTING the instance proximity analysis
     206Test::Nebulous->setup;
     207{
     208    my @nodedirs = Test::Nebulous->get_node_dirs();
     209
     210    # place 4 instances on specific nodes (hard targets works):
     211    my $uri1 = $neb->create_object("foo", "~node01");
     212    my $uri2 = $neb->replicate_object("foo", "~node02");
     213    my $uri3 = $neb->replicate_object("foo", "~node03");
     214    my $uri4 = $neb->replicate_object("foo", "~node08");
     215
     216    my $locations = $neb->find_instances("foo", "node01");
     217    my $Nloc = @$locations;
     218
     219    is($Nloc, 4, "found 4 instances");
     220   
     221    my $loc1 = $locations->[0];
     222    my $loc2 = $locations->[1];
     223    my $loc3 = $locations->[2];
     224    my $loc4 = $locations->[3];
     225
     226    # choosing instance relative to node01 yields:
     227    like($loc1, qr/$nodedirs[0]/, "node01 is closest to node01");   
     228    like($loc2, qr/$nodedirs[1]/, "node02 is 2nd closest to node01");
     229    like($loc3, qr/$nodedirs[2]/, "node03 is 3rd closest to node01");
     230    like($loc4, qr/$nodedirs[7]/, "node08 is 4th closest to node01");
     231}
     232
     233#### TESTING the instance proximity analysis
     234Test::Nebulous->setup;
     235{
     236    my @nodedirs = Test::Nebulous->get_node_dirs();
     237
     238    # place 4 instances on specific nodes (hard targets works):
     239    my $uri1 = $neb->create_object("foo", "~node01");
     240    my $uri2 = $neb->replicate_object("foo", "~node02");
     241    my $uri3 = $neb->replicate_object("foo", "~node03");
     242    my $uri4 = $neb->replicate_object("foo", "~node08");
     243
     244    my $locations = $neb->find_instances("foo", "node03");
     245    my $Nloc = @$locations;
     246
     247    is($Nloc, 4, "found 4 instances");
     248   
     249    my $loc1 = $locations->[0]; #
     250    my $loc2 = $locations->[1]; #
     251    my $loc3 = $locations->[2]; #
     252    my $loc4 = $locations->[3]; #
     253
     254    # choosing instance relative to node01 yields:
     255    like($loc1, qr/$nodedirs[2]/, "node03 is closest to node03");
     256    like($loc2, qr/$nodedirs[7]/, "node08 is 2nd closest to node03");
     257    like($loc3, qr/$nodedirs[1]/, "node02 is 3rd closest to node03");
     258    like($loc4, qr/$nodedirs[0]/, "node08 is 4th closest to node03");
     259}
     260
     261########
    110262
    111263Test::Nebulous->setup;
     
    125277
    126278Test::Nebulous->setup;
    127 
    128 eval {
    129     $neb->find_instances();
    130 };
    131 like($@, qr/1 - 2 were expected/, "no params");
     279eval {
     280    my $locations = $neb->find_instances();
     281};
     282like($@, qr/1 - 3 were expected/, "no params");
     283# note the new API expects 1-3 parameters
    132284
    133285Test::Nebulous->setup;
     
    135287eval {
    136288    $neb->create_object('foo');
    137     $neb->find_instances('foo', 'node01', 3);
    138 };
    139 like($@, qr/1 - 2 were expected/, "too many params");
     289    $neb->find_instances('foo', 'node01', 3, 5);
     290};
     291like($@, qr/1 - 3 were expected/, "too many params");
     292# note the new API expects 1-3 parameters
    140293
    141294Test::Nebulous->cleanup;
  • trunk/Nebulous-Server/t/11_server_is_valid_volume_name.t

    r24356 r41172  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 3;
     10use Test::More tests => 5;
    1111
    1212use lib qw( ./t ./lib );
     
    3131Test::Nebulous->setup;
    3232
    33 is($neb->_is_valid_volume_name('foo', 'node99'), undef, "invalid volume name");
     33is($neb->_is_valid_volume_name('foo', 'node99'), 0, "invalid volume name");
     34
     35Test::Nebulous->setup;
     36
     37# key does not need to exist (is hashed to select db server)
     38ok($neb->_is_valid_volume_name('bax', 'node01'), "valid volume name");
     39
     40Test::Nebulous->setup;
     41
     42# 'any' should always be a valid name
     43ok($neb->_is_valid_volume_name('foo', 'any'), "valid volume name");
    3444
    3545Test::Nebulous->cleanup;
  • trunk/Nebulous-Server/t/15_server_xattr.t

    r24356 r41172  
    184184    $neb->getxattr_object('foo', 'user.bar');
    185185};
    186 like($@, qr|xattr neb:///foo:user.bar does not exist|,
    187     "get xattr from non-existant xattr key");
     186like($@, qr|xattr neb:///foo:user.bar does not exist|, "get xattr from non-existant xattr key");
    188187
    189188Test::Nebulous->setup;
  • trunk/Nebulous-Server/t/16_mounts.t

    r24356 r41172  
    2828    my $mounts = $neb->mounts();
    2929
    30     is(scalar @$mounts, 7, "number of rows");
     30    is(scalar @$mounts, 8, "number of rows");
    3131
    3232    my %row;
     
    3535        = @{$mounts->[0]};
    3636   
    37     is($row{total},     100000000000);
    38     is($row{used},      100000000);
    39     is($row{vol_id},    1);
    40     is($row{name},      "node01");
    41     is($row{host},      "node01");
    42     is($row{allocate},  1);
    43     is($row{available}, 1);
    44     is($row{xattr},     0);
     37    is($row{total},     100000000000, "total bytes");
     38    is($row{used},      100000000, "used bytes");
     39    is($row{vol_id},    1, "vol id");
     40    is($row{name},      "node01", "name");
     41    is($row{host},      "node01", "host");
     42    is($row{allocate},  1, "is allocated");
     43    is($row{available}, 1, "is available");
     44    is($row{xattr},     0, "has no xattr");
    4545
    4646    # 2nd row
     
    4848        = @{$mounts->[1]};
    4949
    50     is($row{total},     100000000000);
    51     is($row{used},      1000000000);
    52     is($row{vol_id},    2);
    53     is($row{name},      "node02");
    54     is($row{host},      "node02");
    55     is($row{allocate},  1);
    56     is($row{available}, 1);
    57     is($row{xattr},     0);
     50    is($row{total},     100000000000, "total bytes");
     51    is($row{used},      1000000000, "used bytes");
     52    is($row{vol_id},    2, "vol id");
     53    is($row{name},      "node02", "name");
     54    is($row{host},      "node02", "host");
     55    is($row{allocate},  1, "is allocated");
     56    is($row{available}, 1, "is available");
     57    is($row{xattr},     0, "has no xattr");
    5858}
    5959
  • trunk/Nebulous-Server/t/18_server_chmod_object.t

    r24356 r41172  
    3838    is($mode, 0440, "returned mode");
    3939    is($neb->getxattr_object($key, 'user.mode'), 0440, "xattr user.mode");
     40
     41    # reset to 600 so the user can delete the file and /tmp entry
     42    chmod(0600, $path);
    4043}
    4144
     
    5053    my $mode = $neb->chmod_object($key, 0440);
    5154
    52     my $st1 = stat(URI->new($uri1)->path);
    53     my $st2 = stat(URI->new($uri2)->path);
     55    my $path1 = URI->new($uri1)->path;
     56    my $path2 = URI->new($uri2)->path;
     57
     58    my $st1 = stat($path1);
     59    my $st2 = stat($path2);
    5460
    5561    is($st1->mode &07777, 0440, "chmod() first instance");
     
    5763    is($mode, 0440, "returned mode");
    5864    is($neb->getxattr_object($key, 'user.mode'), 0440, "xattr user.mode");
     65
     66    # reset to 600 so the user can delete the file and /tmp entry
     67    chmod (0600, $path1);
     68    chmod (0600, $path2);
    5969}
    6070
  • trunk/Nebulous/Build.PL

    r32473 r41172  
    9696        'Test::Nebulous'            => 0,
    9797        'Test::Cmd'                 => '1.05',
    98         'Apache2::SOAP'             => 0,
     98# gentoo: 'Apache2::SOAP'             => 0,
     99        'Apache::SOAP'             => 0, # needed instead for ubuntu 18.04
    99100        'Apache::DBI'               => '1.05',
    100101        'Apache::Test'              => '1.27',  # bundles Apache::TestMB
  • trunk/Nebulous/bin/neb-cat

    r13080 r41172  
    1818use constant CHUNK_SIZE => 1024;
    1919
    20 my ($server);
     20my ($server, $help);
    2121
    2222$server = $ENV{'NEB_SERVER'} unless $server;
     
    2424GetOptions(
    2525    'server|s=s'    => \$server,
     26    'help|h'        => \$help,
    2627) || pod2usage( 2 );
    2728
    28 pod2usage( -msg => "Required options: --server <key...>", -exitval => 2 )
    29         unless defined $server;
     29# explicitly defined -h / --help:
     30if ($help) { pod2usage( -verbose => 1 ); }
     31
     32pod2usage( -msg => "Required options: --server <key...>", -exitval => 2 ) unless defined $server;
    3033
    3134my $neb = Nebulous::Client->new(
     
    9598=over 4
    9699
    97 =item * --server|-s <URL>
     100=item --server|-s <URL>
    98101
    99102URL of the Nebulous server to connect to.
  • trunk/Nebulous/bin/neb-cp

    r16182 r41172  
    1616use Pod::Usage qw( pod2usage );
    1717
    18 my ($volume, $server);
     18my ($volume, $server, $help);
    1919
    2020$server = $ENV{'NEB_SERVER'} unless $server;
     
    2323    'volume=s'      => \$volume,
    2424    'server|s=s'    => \$server,
     25    'help|h'        => \$help,
    2526) || pod2usage( 2 );
     27
     28# explicitly defined -h / --help:
     29if ($help) { pod2usage( -verbose => 1 ); }
    2630
    2731my $src = shift;
  • trunk/Nebulous/bin/neb-cull

    r30236 r41172  
    1717
    1818my ($min_copies, $server, $volume, $one_only);
    19 my ($soft_volume);
     19my ($soft_volume, $help);
    2020$server = $ENV{'NEB_SERVER'} unless $server;
    2121
     
    2626    'one_only|o'    => \$one_only,
    2727    'soft_volume'   => \$soft_volume,
     28    'help|h'        => \$help,
    2829) || pod2usage( 2 );
     30
     31# explicitly defined -h / --help:
     32if ($help) { pod2usage( -verbose => 1 ); }
    2933
    3034my $key = shift;
     
    5963# print "@cull_args\n";
    6064
    61 
    6265if ($one_only) {
    6366    my $status = $neb->there_can_be_only_one(@cull_args);
     67    if (not defined $status) {
     68        die "not enough instances of Nebulous key: $key";
     69    }
    6470    if ($status == 0) {
    6571        die "not enough instances of Nebulous key: $key";
  • trunk/Nebulous/bin/neb-insert

    r25939 r41172  
    9595=head1 SYNOPSIS
    9696
    97     neb-insert --server <neb-server> <neb-key> <local-file> [--copies <n>] [--destroy]
     97    neb-insert [--server <neb-server>] <neb-key> <local-file> [--copies <n>] [--destroy]
    9898
    9999#=head1 DESCRIPTION
  • trunk/Nebulous/bin/neb-ls

    r28581 r41172  
    1919    $ls,
    2020    $column,
     21    $help
    2122);
    2223
    2324$server = $ENV{'NEB_SERVER'} unless $server;
    24 
    2525
    2626GetOptions(
     
    2929    'l'             => \$ls,
    3030    'column|c'      => \$column,
     31    'help|h'        => \$help,
    3132) || pod2usage( 2 );
     33
     34# explicitly defined -h / --help:
     35if ($help) { pod2usage( -verbose => 1 ); }
    3236
    3337# twiddle column so that it does it by default.
     
    3539$column = not $column;
    3640
     41if ($ls) { $path = 1; }
     42
    3743my $pattern = shift;
    3844
    3945pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
    40 pod2usage( -msg => "Required options: --server", -exitval => 2 )
    41     unless $server;
     46pod2usage( -msg => "Required options: --server", -exitval => 2 ) unless $server;
    4247
    4348my $neb = Nebulous::Client->new(
     
    96101=head1 SYNOPSIS
    97102
    98     neb-ls [--server <URL>] [-c] [-p] <pattern>
     103    neb-ls [--server <URL>] [-c] [-p] [-l] <pattern>
    99104
    100105=head1 DESCRIPTION
    101106
    102107This program list Nebulous keys matched by C<<pattern>>.  Call it with no
    103 arguments is equivalent to searching with the pattern C<neb://>.  SQL like
     108arguments is equivalent to searching with the pattern C<neb://>.  SQL-like
    104109wildcards are supported to select out certain files.
    105110
     
    108113=over 4
    109114
    110 =item * --path|-p
     115=item --path|-p
    111116
    112117Find the disk files corresponding to the keys found.
    113118
    114 =item * --column|-c
     119=item --column|-c
    115120
    116121Disable column formatting, and output results one to a line.
    117122
     123=item --l|-l
     124
     125Give disk file information using ls (implies -p).
     126
    118127Optional
    119128
    120 =item * --server|-s <URL>
     129=item --server|-s <URL>
    121130
    122131URL of the Nebulous server to connect to.
  • trunk/Nebulous/bin/neb-migrate

    r28446 r41172  
    2323
    2424$server = $ENV{'NEB_SERVER'} unless $server;
     25
     26die "this tool is probably too inefficient unless used very carefully";
    2527
    2628GetOptions(
  • trunk/Nebulous/bin/neb-repair

    r39926 r41172  
    4545);
    4646
    47 die "can't connected to Nebulous Server: $server"
     47die "can't connect to Nebulous Server: $server"
    4848    unless defined $neb;
    4949
    5050my $stat = $neb->stat($key);
    5151die "nebulous key: $key not found" unless $stat;   
     52
    5253my $instances = $neb->find_instances($key, 'any');
    5354die "no instances found" unless $instances;   
     
    7172
    7273for (my $i = 0; $i <= $#files; $i++) {
     74    # count existing files and get the MD5 sums
    7375    if (-e $files[$i]) {
    7476        $existance[$i] = 1;
     
    8991        push @{ $md5sum_valid{$md5sums[$i]} }, $files[$i];
    9092        $last_f = $files[$i];
    91     }
    92     else {
     93    } else {
    9394        $existance[$i] = 0;
    9495        $md5sums[$i] = 'NON-EXISTANT';
     
    9899}
    99100
     101# check number of copies and number of unique MD5 sum values
    100102my $N_mds = scalar(keys(%md5sum_uniq));
    101103my $N_files = scalar(@files);
     104
     105# seems like we should not call neb-replicate until *after* we have
     106# removed 0-byte copies
    102107if ($N_files < $user_copies) {
    103108    print "Insufficient copies ($N_files) of $key, replicating!\n";
    104109    system("neb-replicate $key");
    105110}
     111
    106112if ($N_mds == 1) {
    107113    print "Nebulous key $key is consistent.\n";
    108 }
    109 else {
     114} else {
    110115    my $valid_sum = '';
    111116    my $valid_file = '';
    112117    my $m;
    113118    foreach $m (keys %md5sum_valid) {
    114         if (($m ne 'd41d8cd98f00b204e9800998ecf8427e')&&($m ne 'NON-EXISTANT')) {
     119        if (($m ne 'd41d8cd98f00b204e9800998ecf8427e') && ($m ne 'NON-EXISTANT')) {
    115120            if ($valid_sum ne '') {
    116121                die "Too many acceptable files for key $key\n";
     
    122127    if ($valid_sum eq '') {
    123128        die "No acceptable file for key $key\n";
    124     }
    125     else {
     129    } else {
    126130        print "Repairing instances\n";
    127131        foreach $m (keys %md5sum_valid) {
     
    130134                    print "\tcp $valid_file $f\n";
    131135                    system("cp $valid_file $f");
     136
     137                    # if we failed to make a copy, the target ($f) could be inaccessible
    132138                    if ($? >> 8 != 0) {
    133139                        if ($existance[0] == 1) {
    134                             # We can fix this with culls and replications.
     140
     141                            # The target is a valid file 0-byte file
     142                            # but we cannot replace it with the
     143                            # correct file.  We can fix this with
     144                            # culls and replications.
     145
    135146                            print "Attempting to fix this.\n";
    136147                            print("neb-replicate $key\n");
    137148                            system("neb-replicate $key");
    138149                            if ($? >> 8 == 0) {
     150                                # if the neb-replicate succeeded, remove the bad copy with neb-cull
    139151                                my $bad_volume = (split /\//, $f)[2];
    140152                                print("neb-cull --volume $bad_volume $key\n");
    141153                                system("neb-cull --volume $bad_volume $key");
    142                             }
    143                             else {
     154                            } else {
    144155                                die "Failed to copy file $valid_file to $f, and subsequent replication also failed!\n";
    145156                            }
    146                         }
    147                         else {
     157                        } else {
    148158                            die "Failed to copy file $valid_file to $f!\n";
    149159                        }
     
    187197=head1 DESCRIPTION
    188198
    189 This program repairs instances and corrects instance counts for a nebulous key. 
     199This program repairs instances and corrects instance counts for a nebulous key:
     200
     201If some of the existing instances have the MD5 sum corresponding to a
     2020-byte file, but the rest have the same, non-zero byte md5sum, then
     203replace the 0-byte files with the non-zero byte version.
     204
     205At the end, if the number of instances is less than the value of
     206user.copies, then additional copies are generated.
    190207
    191208=head1 OPTIONS
  • trunk/Nebulous/bin/neb-replicate

    r29476 r41172  
    4242);
    4343
     44# Nebulous::Client programs can use this to set the log level:
     45# $neb->set_log_level ('DEBUG');
     46
    4447die "can't connected to Nebulous Server: $server"
    4548    unless defined $neb;
     
    5053    for (my $i = 0; $i < $copies; $i++) {
    5154        if (defined $volume) {
     55            # this is coded so that all copies end up on the specified volume which seems wrong
    5256            $neb->replicate($key, $volume)
    5357                or die "failed to replicate Nebulous key: $key";
  • trunk/Nebulous/bin/neb-shift

    r31964 r41172  
    1717
    1818my ($volume, $server);
     19
     20die "this tool may fail since find_instances will return an instance which is not on the hard volume";
    1921
    2022$server = $ENV{'NEB_SERVER'} unless $server;
  • trunk/Nebulous/bin/neb-stat

    r32045 r41172  
    1919use URI;
    2020
    21 my ($validate,$server,$nouris);
     21my ($validate,$server,$nouris,$help);
    2222
    2323$server = $ENV{'NEB_SERVER'} unless $server;
    2424
    2525GetOptions(
    26     'server|s=s'     => \$server,
    27     'validate|v'         => \$validate,
    28     'files'          => \$nouris,
     26    'server|s=s'    => \$server,
     27    'validate|v'    => \$validate,
     28    'files|f'       => \$nouris,
     29    'help|h'        => \$help,
    2930) || pod2usage( 2 );
    3031
     32# explicitly defined -h / --help:
     33if ($help) { pod2usage( -verbose => 1 ); }
     34
    3135my $key = shift;
    3236
    3337pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
    34 pod2usage( -msg => "Required options: --server", -exitval => 2 )
    35     unless $server;
    36 pod2usage( -msg => "missing key", exitval => 2 )
    37     unless defined $key;
     38pod2usage( -msg => "Required options: --server", -exitval => 2 ) unless $server;
     39pod2usage( -msg => "missing key", exitval => 2 ) unless defined $key;
    3840
    3941my $neb = Nebulous::Client->new(
     
    5254eval {
    5355    $user_copies = $neb->getxattr($key, "user.copies");
     56    die ("user.copies not found") unless $user_copies;
    5457};
    55 unless(defined($user_copies)) {
     58unless(defined($user_copies) and $user_copies ne "") {
    5659    $user_copies = 1;
    5760}
     
    7477            $md5sum_uniq{$md5sums[$i]} = 1;
    7578            close($fh);
    76         }
    77         else {
     79        } else {
    7880            $existance[$i] = 0;
    7981            $md5sums[$i] = 'NON-EXISTANT';
    8082            $md5sum_uniq{$md5sums[$i]} = 1;
    8183        }
     84
    8285        if (defined($nouris)) {
    8386            $validation[$i] = sprintf("% 3d %32s %s",
     
    8588                                      $md5sums[$i],
    8689                                      $files[$i]);
    87         }
    88         else {
     90        } else {
    8991            $validation[$i] = sprintf("% 3d %32s %s",
    9092                                      $existance[$i],
     
    112114        "instance location:\n", " " x 4,
    113115        join("\n" . " " x 4, @validation), "\n";
     116} else {
     117   
     118    if (defined($nouris)) {
     119        my @files = map {URI->new($_)->file if $_} @$instances;
     120
     121        print
     122            "object id:             ", @$stat[0], "\n",
     123            "key:                   ", @$stat[1], "\n",
     124            "read lock:             ", @$stat[2], "\n",
     125            "write lock:            ", @$stat[3], "\n",
     126            "epoch:                 ", @$stat[4], "\n",
     127            "mtime:                 ", @$stat[5], "\n",
     128            "available instances:   ", @$stat[6], "\n",
     129            "requested instances:   ", $user_copies, "\n",
     130            "total instances:       ", @$stat[7], "\n",
     131           
     132            "instance location:\n", " " x 4,
     133            join("\n" . " " x 4, @files), "\n";
     134    } else {
     135        print
     136            "object id:             ", @$stat[0], "\n",
     137            "key:                   ", @$stat[1], "\n",
     138            "read lock:             ", @$stat[2], "\n",
     139            "write lock:            ", @$stat[3], "\n",
     140            "epoch:                 ", @$stat[4], "\n",
     141            "mtime:                 ", @$stat[5], "\n",
     142            "available instances:   ", @$stat[6], "\n",
     143            "requested instances:   ", $user_copies, "\n",
     144            "total instances:       ", @$stat[7], "\n",
     145           
     146            "instance location:\n", " " x 4,
     147            join("\n" . " " x 4, @$instances), "\n";
     148    }
     149
    114150}
    115 else {
    116     print
    117         "object id:             ", @$stat[0], "\n",
    118         "key:                   ", @$stat[1], "\n",
    119         "read lock:             ", @$stat[2], "\n",
    120         "write lock:            ", @$stat[3], "\n",
    121         "epoch:                 ", @$stat[4], "\n",
    122         "mtime:                 ", @$stat[5], "\n",
    123         "available instances:   ", @$stat[6], "\n",
    124         "requested instances:   ", $user_copies, "\n",
    125         "total instances:       ", @$stat[7], "\n",
    126        
    127         "instance location:\n", " " x 4,
    128         join("\n" . " " x 4, @$instances), "\n";
    129 }
    130151
    131152
     
    150171=over 4
    151172
    152 =item * --server|-s <URL>
     173=item --server|-s <URL>
    153174
    154175URL of the Nebulous server to connect to.
     
    156177Optional if the appropriate environment variable is set.
    157178
    158 =item * --validate|-v
     179=item --validate|-v
    159180
    160181Optional - prints out additional information including md5sum.
    161182
    162 =item * --files
     183=item --files
    163184
    164185Optional - prints out disk files instead of uris during validate stage.
     
    174195=over 4
    175196
    176 =item * C<NEB_SERVER>
     197=item C<NEB_SERVER>
    177198
    178199Equivalent to --server|-s
  • trunk/Nebulous/lib/Nebulous/Client.pm

    r40680 r41172  
    209209        },
    210210    );
    211 
     211   
    212212    $log->debug( "entered - @_" );
    213213
     
    310310    my $stats = $self->stat($key);
    311311    my $instances = $stats->[6];
     312
    312313    if ((not defined $instances) or ($instances == 0)) {
    313314        $self->set_err("can not cull - no instances");
     
    315316        return;
    316317    }
    317     if ($instances < $min_copies) {
     318    if ($instances <= $min_copies) {
    318319        $self->set_err("can not cull - not enough instances");
    319320        $log->debug("leaving");
    320 
    321321        return;
    322322    }
     
    334334
    335335    unless (defined $locations) {
    336         $self->set_err( "no instances" );
    337336        $log->debug( "leaving" );
    338 
    339337        return;
    340338    }
     
    351349        }
    352350    }
     351
    353352    # If we don't have two copies on one volume, see if we have two copies on a single
    354353    # cabinet. If so, delete the first of those copies.
     
    362361        }
    363362    }
     363
    364364    # Fail-safe. We didn't have any duplicates (the instances are "well-mixed"), so
    365365    # delete the first.
     
    403403    eval {
    404404        # first - strip off any inaccesible instances
     405        # these are not counted in the 'removed' number
    405406        if (not defined $self->prune($key)) {
    406407            # use the prune() method to also determine if $key is valid
    407408            die "invalid key: $key";
    408409        }
    409 
    410         # check to see if there is an instance on $vol_name that should be the
    411         # sole survivor
     410       
     411        # check to see if there is an instance on $vol_name that
     412        # should be the sole survivor.  This is a bit dangerous : what
     413        # if the only instance is on an invalid volume?  what if an
     414        # invalid volume is specified?
     415
    412416        if (defined $vol_name) {
    413417            $locations = $self->find_instances($key, $vol_name);
     418            if (not defined $locations) {
     419                die "no instances on requested node";
     420            }
     421            if (scalar @$locations == 0) {
     422                die "no instances on requested node";
     423            }
    414424        }
    415425
     
    418428
    419429        if (defined $locations) {
    420             my $instances = $self->find_instances($key, undef, 'find them all');
    421             if (scalar @$instances == 1) {
    422                 # only one instance nothing to do
    423                 return 0;
    424             }
    425             if (scalar @$instances == 0) {
     430            print "dev: looking for undef volume instances\n";
     431            # first delete the valid instances (except the one we own)
     432            my $instances_valid = $self->find_instances($key, undef, 0); # find all valid instances
     433            if (not defined $instances_valid) {
     434                # there should have been at least one valid instance?
    426435                die "no instances";
    427436            }
    428             foreach my $victim (@$instances) {
    429                 next if $victim eq $locations->[0];
    430                 $self->delete_instance($key, $victim);
    431                 $removed++;
     437            if (scalar @$instances_valid == 0) {
     438                # there should have been at least one valid instance?
     439                die "no instances";
    432440            }
     441
     442            # we have more than one instance, delete the others
     443            if (scalar @$instances_valid > 1) {
     444                foreach my $victim (@$instances_valid) {
     445                    next if $victim eq $locations->[0];
     446                    $self->delete_instance($key, $victim);
     447                    $removed ++;
     448                }
     449            }
     450            # the prune above should have deleted any invalid instances, so we only
     451            # need to worry about the valid instances;
    433452        } else {
    434453            # nuke whatever
     
    448467            }
    449468        }
    450 
    451469    };
    452470    if ($@) {
     
    663681    if ($response->fault) {
    664682        $self->set_err($response->faultstring);
     683
     684        ## invalid object key
     685        if ($response->faultstring =~ /is valid object key/) {
     686            $log->debug( "leaving" );
     687            die "invalid key $key, fails 'is valid object key' test\n";
     688        }
     689
     690        ## invalid object key
     691        if ($response->faultstring =~ /xattr is in user. namespace/) {
     692            $log->debug( "leaving" );
     693            die "invalid xattr key $name : fails 'xattr is in user. namespace' test\n";
     694        }
     695
    665696        $log->logdie("unhandled fault - ", $self->err);
    666697    }
     
    690721    if ( $response->fault ) {
    691722        $self->set_err($response->faultstring);
     723
     724        ## invalid object key
     725        if ($response->faultstring =~ /is valid object key/) {
     726            $log->debug( "leaving" );
     727            die "invalid key $key, fails 'is valid object key' test\n";
     728        }
     729
     730        ## invalid xattr key (not in user. namespace)
     731        if ($response->faultstring =~ /xattr is in user. namespace/) {
     732            $log->debug( "leaving" );
     733            die "xattr $name is invalid : xattr is in user. namespace\n";
     734        }
     735
     736        ## invalid xattr key
     737        if ($response->faultstring =~ /user\..*? does not exist/) {
     738            $log->debug( "leaving" );
     739            die "xattr key $name not found : xattr $name does not exist\n";
     740        }
    692741        $log->logdie("unhandled fault - ", $self->err);
    693742    }
     
    747796    if ( $response->fault ) {
    748797        $self->set_err($response->faultstring);
     798
     799        ## invalid object key
     800        if ($response->faultstring =~ /is valid object key/) {
     801            $log->debug( "leaving" );
     802            die "invalid key $key, fails 'is valid object key' test\n";
     803        }
     804
     805        ## invalid xattr key (not in user. namespace)
     806        if ($response->faultstring =~ /xattr is in user. namespace/) {
     807            $log->debug( "leaving" );
     808            die "xattr $name is invalid : xattr is in user. namespace\n";
     809        }
     810
     811        ## invalid xattr key
     812        if ($response->faultstring =~ /user\..*? does not exist/) {
     813            $log->debug( "leaving" );
     814            die "xattr key $name not found : xattr $name does not exist\n";
     815        }
     816
    749817        $log->logdie("unhandled fault - ", $self->err);
    750818    }
     
    865933    unless(defined($params[0])) {
    866934        $params[0] = hostname() . ".0";
    867 #       print STDERR "Setting host to $params[0]\n";
     935        # print STDERR "Setting host to $params[0]\n";
    868936    }
    869937
     
    871939    if ( $response->fault ) {
    872940        $self->set_err($response->faultstring);
     941
    873942        # check to see if this failure is because $key doesn't exist
    874943        if ($response->faultstring =~ /is valid object key/) {
     
    878947        # key is valid but no instances are on the specified volume
    879948        if ($response->faultstring =~ /no instances on storage volume/) {
     949            $log->debug( "leaving" );
     950            return;
     951        }
     952        # check to see if this failure is volume is unknown
     953        if ($response->faultstring =~ /is not a valid volume name/) {
     954            $log->debug( "leaving" );
     955            return;
     956        }
     957        # key is valid but no instances are on the specified volume
     958        if ($response->faultstring =~ /no instances available for key/) {
    880959            $log->debug( "leaving" );
    881960            return;
     
    9491028        $self->set_err($response->faultstring);
    9501029        # check to see if this failure is because $key doesn't exist
     1030        my $string = $response->faultstring;
    9511031        if ($response->faultstring =~ /is valid object key/) {
     1032            $self->set_err("invalid object key");
    9521033            $log->debug( "leaving" );
    9531034            return;
     
    9551036        # key is valid but no instances are on the specified volume
    9561037        if ($response->faultstring =~ /no instances on storage volume/) {
     1038            $self->set_err("no instances on storage volume or volume is not available");
    9571039            $log->debug( "leaving" );
    9581040            return;
     
    9721054
    9731055
     1056## this is used by PS:IPP:Config nebulous functions
    9741057sub find
    9751058{
     
    10141097    return $path;
    10151098}
    1016 
    10171099
    10181100sub open
     
    11241206    $log->debug( "entered - @_" );
    11251207
    1126 
    11271208    my $locations;
    11281209    if ($invalid) {
    1129         $locations = $self->find_instances( $key, 'any', 'find them all');
     1210        # delete the invalid instances:
     1211        $locations = $self->find_instances( $key, 'any', 1);
    11301212    }
    11311213    else {
     
    13151397        }
    13161398
     1399        if ($response->faultstring =~ /is valid object key/) {
     1400            $log->logdie("parameter #1 to delete_instance did not pass the 'is valid object key' callback");
     1401        }
     1402
    13171403        $log->logdie("unhandled fault - ", $self->err);
    13181404    }
     
    14771563}
    14781564
     1565sub set_log_level
     1566{
     1567    my $self = shift;
     1568
     1569    my $log_level = shift;
     1570
     1571    $log->level($log_level);
     1572
     1573    return $self;
     1574}
     1575
    14791576
    148015771;
  • trunk/Nebulous/lib/Nebulous/Util.pm

    r23934 r41172  
    7878    # The instance file attempting to be opened should always exist as it was
    7979    # created by the Nebulous server.
     80
    8081    my $fh;
    8182    for (my $i = 0; $i < 60; $i++) {
     
    160161        die "can not process $arg because it is not in name:value form"
    161162            unless defined $name and defined $value;
    162         die "xattr name: $name is not in to the form user.name"
     163        die "xattr name: $name is not in the form user.name"
    163164            unless $name =~ /^user\./;
    164165        $neb->setxattr($key, $name, $value, "replace")
  • trunk/Nebulous/nebclient

    • Property svn:ignore
      •  

        old new  
        2121stamp-h1
        2222test-driver
         23INSTALL
         24COPYING
  • trunk/Nebulous/nebclient/tests/tap

    • Property svn:ignore
      •  

        old new  
        1919src/.deps
        2020src/Makefile
         21INSTALL
         22COPYING
  • trunk/Nebulous/nebclient/tests/tests.c

    r24999 r41172  
    1616    if (foo) nebFree(foo)
    1717
     18int show_instances (nebServer *server, char *key) {
     19
     20  nebObjectInstances *locations = NULL;
     21
     22  locations = nebFindInstances(server, key, NULL);
     23
     24  for (int i = 0; i < locations->n; i++) {
     25    fprintf (stderr, "# loc %d : %s\n", i, locations->URI[i]);
     26  }
     27  nebObjectInstancesFree(locations);
     28  return 1;
     29}
     30
     31int count_instances (nebServer *server, char *key) {
     32
     33  nebObjectInstances *locations = NULL;
     34  locations = nebFindInstances(server, key, NULL);
     35  int Ninstances = locations ? locations->n : 0;
     36  nebObjectInstancesFree(locations);
     37  return Ninstances;
     38}
     39
    1840int main (int argc, char **argv) {
    1941    nebServer       *server = NULL;
    2042    char            *key = "foobarbaz";
    2143
    22     plan_tests(31);
     44    plan_tests(37);
    2345
    2446    if (getenv("NEB_SERVER")) {
     
    3759        filename = nebCreate(server, key, NULL, &URI);
    3860        diag("filename is %s", filename);
     61
     62        if (!filename) {
     63          fprintf (stdout, "not ok: no files in test server, exiting\n");
     64          exit (2);
     65        }
     66
     67        show_instances (server, key);
     68        ok (count_instances (server, key) == 1, "correct instance count");
     69
    3970        neb_ok(server, filename, "create object");
    4071        ok(URI, "URI not NULL");
     
    5384        neb_ok(server, fh > -1, "create new object filehandle");
    5485        ok(URI, "URI not NULL");
     86        ok (count_instances (server, key) == 1, "correct instance count");
    5587
    5688        tst_nebFree(URI);
    5789        close(fh);
    5890    }
     91
     92    show_instances (server, key);
    5993
    6094    {
     
    80114    }
    81115
    82 
    83116    neb_ok(server, nebReplicate(server, key, NULL, NULL), "replicate object");
     117    show_instances (server, key);
     118    ok (count_instances (server, key) == 2, "correct instance count");
    84119
    85120    neb_ok(server, nebOpen(server, key, NEB_WRITE) < 0, "write to object with multiple instances");
     121    show_instances (server, key);
    86122
    87123    neb_ok(server, nebCull(server, key), "cull object");
     124    show_instances (server, key);
     125    ok (count_instances (server, key) == 1, "correct instance count");
     126
     127    neb_ok(server, nebCull(server, key) == 0, "cannot cull object with one instance");
     128    show_instances (server, key);
     129    ok (count_instances (server, key) == 1, "correct instance count");
    88130
    89131    neb_ok(server, nebStat(server, key), "stat object");
     132    show_instances (server, key);
    90133
    91134    neb_ok(server, nebLock(server, key, NEB_WRITE), "lock object write");
  • trunk/Nebulous/t/50_client_create.t

    r24357 r41172  
    1010use Apache::Test qw( -withtestmore );
    1111
    12 plan tests => 9;
     12plan tests => 13;
    1313
    1414use lib qw( ./t ./lib );
     
    1919use URI::Split qw( uri_split );
    2020
     21# this returns the test apache server location
    2122my $hostport = Apache::Test->config->{ 'hostport' };
    2223
     
    3031
    3132    my $uri = $neb->create("foo");
     33    if (not defined $uri) { die "failure to create basic file (does it already exist?)"; }
     34
    3235    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
    3336    ok(-e $path, "good filename");
     37
    3438    uri_scheme_ok($uri, 'file');
     39   
     40    # need to remove the test entry we made above (create fails if file exists)
     41    ok( $neb->delete( "foo" ), "delete object" );
    3542}
    3643
     
    4855    ok(-e $path, "good filename");
    4956    uri_scheme_ok($uri, 'file');
     57
     58    # need to remove the test entry we made above (create fails if file exists)
     59    ok( $neb->delete( "foo" ), "delete object" );
    5060}
    5161
     
    6373    ok(-e $path, "good filename");
    6474    uri_scheme_ok($uri, 'file');
     75
     76    # need to remove the test entry we made above (create fails if file exists)
     77    ok( $neb->delete( "foo" ), "delete object" );
    6578}
    6679
     
    7487    $neb->create("foo");
    7588    is($neb->create("foo"), undef, "object already exists");
     89
     90    # need to remove the test entry we made above (create fails if file exists)
     91    ok( $neb->delete( "foo" ), "delete object" );
    7692}
    7793
  • trunk/Nebulous/t/53_client_cull.t

    r25121 r41172  
    1010use Apache::Test qw( -withtestmore );
    1111
    12 plan tests => 15;
     12plan tests => 18;
    1313
    1414use lib qw( ./t ./lib );
     
    2121
    2222Test::Nebulous->setup;
    23 
    2423{
    2524    # key
     
    3736
    3837Test::Nebulous->setup;
    39 
    4038{
    4139    # key, $volume
     
    4341        proxy => "http://$hostport/nebulous",
    4442    );
    45     $neb->create("foo");
    46     $neb->replicate("foo", "node01");
    47 
    48     my $uri = $neb->cull("foo", "node01");
     43    $neb->create("foo", "node01");
     44    $neb->replicate("foo", "node02");
     45   
     46    my $uri = $neb->cull("foo", "node02");
    4947
    5048    ok($uri, "good cull");
    5149    ok(! -e _get_file_path($uri), "file exists");
     50}
     51
     52Test::Nebulous->setup;
     53{
     54    # key, $volume
     55    my $neb = Nebulous::Client->new(
     56        proxy => "http://$hostport/nebulous",
     57    );
     58    $neb->create("foo", "node01");
     59    $neb->replicate("foo", "node02");
     60
     61    # cull with soft volume should succeed even if node does not have instance
     62    my $uri = $neb->cull("foo", "node03");
     63
     64    ok($uri, "good cull");
     65    ok(! -e _get_file_path($uri), "file exists");
     66}
     67
     68Test::Nebulous->setup;
     69{
     70    # key, $volume
     71    my $neb = Nebulous::Client->new(
     72        proxy => "http://$hostport/nebulous",
     73    );
     74    $neb->create("foo", "node01");
     75    $neb->replicate("foo", "node02");
     76
     77    # cull with hard volume should not succeed if node does not have instance
     78    my $uri = $neb->cull("foo", "~node03");
     79
     80    is($uri, undef, "nothing to cull on this node");
    5281}
    5382
     
    112141        proxy => "http://$hostport/nebulous",
    113142    );
    114     $neb->cull();
     143    my $uri = $neb->cull();
     144
     145    is ($uri, undef, "no params given to cull");
    115146};
    116147like( $@, qr/1 - 3 were expected/, "no params" );
     
    122153        proxy => "http://$hostport/nebulous",
    123154    );
    124     $neb->cull( 1, 2, 3, 4 );
     155    my $uri = $neb->cull( 1, 2, 3, 4 );
     156
     157    is ($uri, undef, "no params given to cull");
    125158};
    126159like( $@, qr/1 - 3 were expected/, "too many params" );
  • trunk/Nebulous/t/56_client_find_instances.t

    r19469 r41172  
    1010use Apache::Test qw( -withtestmore );
    1111
    12 plan tests => 29;
     12plan tests => 35;
    1313
    1414use lib qw( ./t ./lib );
     
    2020my $hostport = Apache::Test->config->{ 'hostport' };
    2121
    22 Test::Nebulous->setup;
    23 
     22### XXX EAM : this test suite finds real errors in the implementation. 
     23
     24## the API is now slightly different (what is the state of the API in the ipp ops code?)
     25## find_instances ("key", "volume", find_invalid)
     26
     27## this returns a result even if we request a hard volume unless the hard volume is not valid
     28
     29Test::Nebulous->setup;
     30Test::Nebulous->cleanup;
     31
     32### TEST BLOCK for find_invalid
     33## Test::Nebulous->setup;
     34## {
     35##     # volume/key, volume override
     36##     my $neb = Nebulous::Client->new(
     37##         proxy => "http://$hostport/nebulous",
     38##     );
     39##     $neb->create( "foo", "~node02" );
     40##     $neb->replicate( "foo", "~node01" );
     41##
     42##     Test::Nebulous->switch_node_state;
     43##     my $tmphost;
     44##
     45## #   my $locations = $neb->find_instances( "neb:///foo", "~node02", 1); # result : no instance
     46## #   my $locations = $neb->find_instances( "neb:///foo", "~node02", 0); # result : no instance
     47## #   my $locations = $neb->find_instances( "neb:///foo", "~node02"); # result : no instance
     48##
     49## #   my $locations = $neb->find_instances( "neb:///foo", "node02", 1); # result : no instance
     50## #   my $locations = $neb->find_instances( "neb:///foo", "node02", 0); # result : no instance
     51##     my $locations = $neb->find_instances( "neb:///foo", "node02"); # result : no instances
     52##
     53## #   my $locations = $neb->find_instances( "neb:///foo", undef, 1);
     54## #   my $locations = $neb->find_instances( "neb:///foo", undef, 0);
     55## #   my $locations = $neb->find_instances( "neb:///foo", $tmphost, 0);
     56##
     57## #   my $locations = $neb->find_instances( "neb:///foo", "bebaz", 1);
     58## #   my $locations = $neb->find_instances( "neb:///foo", "bebaz", 0);
     59##
     60## #   my $locations = $neb->find_instances( "neb:///foo");
     61## #   my $locations = $neb->find_instances( "neb://bebaz/foo");
     62##
     63## #   my $locations = $neb->find_instances( "neb:///foo");
     64## #   my $locations = $neb->find_instances( "neb:///foo", undef, 0);
     65##
     66##     foreach my $f (@$locations) {
     67##      print "location: $f\n";
     68##     }
     69##
     70##     is( scalar @$locations, 1, "found 1" );
     71##     like( @$locations[0], qr/file:/, "URIs match" );
     72##     ok( -e _get_file_path( @$locations[0] ), "URI matches file" );
     73## }
     74## die "quit";
     75
     76## Test::Nebulous->setup;
     77## eval {
     78##     # volume/key, volume override
     79##     my $neb = Nebulous::Client->new(
     80##         proxy => "http://$hostport/nebulous",
     81##     );
     82##     $neb->create( "foo", "~node01" );
     83##
     84##     my $locations_1 = $neb->find_instances( "neb://~invalid/foo", "~invalid");
     85##     is($locations_1, undef, "no instances in invalid node" );
     86##
     87##     # EAM: we fail this test because the logic of find_instances has
     88##     # changed: as long as there is an instance on a valid node, the
     89##     # instance gets returned
     90##     my $locations = $neb->find_instances( "neb://node01/foo", "~node02" );
     91##     is($locations, undef, "no instances on specified volume" );
     92## };
     93##print "result: $@\n";
     94##like( $@, qr/result message/, "my message" );
     95
     96# find a single instance by raw name (foo)
     97Test::Nebulous->setup;
    2498{
    2599    # key
     
    36110}
    37111
    38 Test::Nebulous->setup;
    39 
     112# find a both instances of a duplicated object
     113Test::Nebulous->setup;
    40114{
    41115    # key
     
    56130
    57131Test::Nebulous->setup;
    58 
    59132{
    60133    # key, volume
     
    79152    );
    80153    $neb->create( "foo" );
     154    $neb->set_log_level ('DEBUG');
    81155
    82156    my $locations = $neb->find_instances( "foo", undef );
     
    103177}
    104178
    105 Test::Nebulous->setup;
    106 
     179# find instance using hard_volume for wrong node
     180# (should still return a valid instance)
     181Test::Nebulous->setup;
    107182{
    108183    # volume/key, volume override
     
    111186    );
    112187    $neb->create( "foo", "~node01" );
     188    $neb->set_log_level ('DEBUG');
    113189
    114190    my $locations = $neb->find_instances( "neb://node01/foo", "~node02" );
    115191
     192    is( scalar @$locations, 1, "found 1" );
     193    like( @$locations[0], qr/file:/, "URIs match" );
     194    ok( -e _get_file_path( @$locations[0] ), "URI matches file" );
     195#   the API used to return undef if we used a hard_volume but it was not there
     196#   is($locations, undef, "no instances on specified volume" );
     197}
     198
     199# find instance using hard_volume for unknown node
     200# (should fail)
     201Test::Nebulous->setup;
     202{
     203    # volume/key, volume override
     204    my $neb = Nebulous::Client->new(
     205        proxy => "http://$hostport/nebulous",
     206    );
     207    $neb->create( "foo", "~node01" );
     208    $neb->set_log_level ('DEBUG');
     209
     210    my $locations = $neb->find_instances( "neb://node01/foo", "~nobody" );
    116211    is($locations, undef, "no instances on specified volume" );
     212#   is( scalar @$locations, 0, "found 0" );
     213#   under Ubuntu (Perl 5.26.1), @$locations evaluates to 0 if $locations is undef,
     214#   but not under Gentoo (Perl 5.6.6)
     215}
     216
     217# find instance using hard_volume for unavailable node
     218# (should fail)
     219Test::Nebulous->setup;
     220{
     221    # volume/key, volume override
     222    my $neb = Nebulous::Client->new(
     223        proxy => "http://$hostport/nebulous",
     224    );
     225    $neb->create( "foo", "~node01" );
     226    $neb->set_log_level ('DEBUG');
     227
     228    my $locations = $neb->find_instances( "neb://node01/foo", "~node04" );
     229
     230    is( scalar @$locations, 1, "found 1" );
     231    like( @$locations[0], qr/file:/, "URIs match" );
     232    ok( -e _get_file_path( @$locations[0] ), "URI matches file" );
     233
     234#   the API used to return undef if we used a hard_volume but it was not there
     235#   is($locations, undef, "no instances on specified volume" );
    117236}
    118237
     
    153272
    154273Test::Nebulous->setup;
    155 
    156274{
    157275    my $neb = Nebulous::Client->new(
     
    171289    $neb->find_instances();
    172290};
    173 like( $@, qr/1 - 2 were expected/, "no params" );
     291like( $@, qr/1 - 3 were expected/, "no params" );
    174292
    175293Test::Nebulous->setup;
     
    180298    );
    181299
    182     $neb->find_instances( "foo", 'read', 3 );
     300    $neb->find_instances( "foo", 'read', 3, 5 );
    183301};
    184 like( $@, qr/1 - 2 were expected/, "too many params" );
     302like( $@, qr/1 - 3 were expected/, "too many params" );
    185303
    186304Test::Nebulous->cleanup;
  • trunk/Nebulous/t/59_client_delete.t

    r24440 r41172  
    1010use Apache::Test qw( -withtestmore );
    1111
    12 plan tests => 13;
     12plan tests => 18;
    1313
    1414use lib qw( ./t ./lib );
     
    2020my $hostport = Apache::Test->config->{ 'hostport' };
    2121
    22 Test::Nebulous->setup;
    23 
     22# ensure fresh start:
     23Test::Nebulous->setup;
     24Test::Nebulous->cleanup;
     25
     26Test::Nebulous->setup;
    2427{
    2528    my $neb = Nebulous::Client->new(
     
    7881}
    7982
    80 # force flag
    81 Test::Nebulous->setup;
    82 
     83# test passing in undefined force flag
     84Test::Nebulous->setup;
    8385{
    8486    my $neb = Nebulous::Client->new(
     
    9092}
    9193
    92 Test::Nebulous->setup;
    93 
     94# test passing in force flag = 1
     95Test::Nebulous->setup;
    9496{
    9597    my $neb = Nebulous::Client->new(
     
    101103}
    102104
     105# test passing in force flag = 0
     106Test::Nebulous->setup;
     107{
     108    my $neb = Nebulous::Client->new(
     109        proxy => "http://$hostport/nebulous",
     110    );
     111    $neb->create( "foo" );
     112
     113    is( $neb->delete("foo", 0), 1, "force flag false" );
     114}
     115
     116# test passing in force flag = 0 where disk file is removed
     117Test::Nebulous->setup;
     118eval {
     119    my $neb = Nebulous::Client->new(
     120        proxy => "http://$hostport/nebulous",
     121    );
     122    $neb->create( "foo" );
     123    my $locations = $neb->find_instances( "foo" );
     124    my $diskfile = _get_file_path(@$locations[0]);
     125    unlink $diskfile;
     126    $neb->delete("foo", 0);
     127};
     128like( $@, qr/can't unlink file/, "no force flag, cannot delete inconsistent file" );
     129
     130# test passing in force flag = 1 where disk file is removed
     131Test::Nebulous->setup;
     132{
     133    my $neb = Nebulous::Client->new(
     134        proxy => "http://$hostport/nebulous",
     135    );
     136    $neb->create( "foo" );
     137    my $locations = $neb->find_instances( "foo" );
     138    my $diskfile = _get_file_path(@$locations[0]);
     139    unlink $diskfile;
     140    is( $neb->delete("foo", 1), 1, "force flag true deletes file" );
     141}
     142
     143# test passing in undef force flag where disk file is removed
     144Test::Nebulous->setup;
     145eval {
     146    my $neb = Nebulous::Client->new(
     147        proxy => "http://$hostport/nebulous",
     148    );
     149    $neb->create( "foo" );
     150    my $locations = $neb->find_instances( "foo" );
     151    my $diskfile = _get_file_path(@$locations[0]);
     152    unlink $diskfile;
     153    $neb->delete("foo", undef);
     154};
     155like( $@, qr/can't unlink file/, "no force flag, cannot delete inconsistent file" );
     156
     157# test passing in undefined force flag where disk file is removed
     158Test::Nebulous->setup;
     159eval {
     160    my $neb = Nebulous::Client->new(
     161        proxy => "http://$hostport/nebulous",
     162    );
     163    $neb->create( "foo" );
     164    my $locations = $neb->find_instances( "foo" );
     165    my $diskfile = _get_file_path(@$locations[0]);
     166    unlink $diskfile;
     167    $neb->delete("foo");
     168};
     169like( $@, qr/can't unlink file/, "no force flag, cannot delete inconsistent file" );
     170
    103171Test::Nebulous->setup;
    104172
     
    109177    $neb->delete();
    110178};
    111 like( $@, qr/1 - 2 were expected/, "no params" );
     179like( $@, qr/1 - 3 were expected/, "no params" );
    112180
    113181Test::Nebulous->setup;
     
    127195        proxy => "http://$hostport/nebulous",
    128196    );
    129     $neb->delete( "foo", 0, 2 );
    130 };
    131 like( $@, qr/1 - 2 were expected/, "too many params" );
     197    $neb->delete( "foo", 0, 1, 2 );
     198};
     199like( $@, qr/1 - 3 were expected/, "too many params" );
    132200
    133201Test::Nebulous->cleanup;
  • trunk/Nebulous/t/64_client_find_objects.t

    r17693 r41172  
    2121
    2222Test::Nebulous->setup;
    23 
    2423{
    2524    # key
  • trunk/Nebulous/t/65_client_mounts.t

    r19494 r41172  
    2929    my $mounts = $neb->mounts();
    3030
    31     is(scalar @$mounts, 7, "number of rows");
     31    is(scalar @$mounts, 8, "number of rows");
    3232
    3333    my %row;
  • trunk/Nebulous/t/66_client_xattr.t

    r24301 r41172  
    2121);
    2222
    23 # 1 key / xattr
    24 
    25 Test::Nebulous->setup;
    26 
     23# setxattr
     24Test::Nebulous->setup;
    2725{
    2826    my $uri = $neb->create('foo');
     
    4644
    4745# multiple xattrs
    48 
    49 Test::Nebulous->setup;
    50 
     46Test::Nebulous->setup;
    5147{
    5248    my $uri = $neb->create('foo');
     
    184180    $neb->getxattr('foo', 'user.bar');
    185181};
    186 like($@, qr|xattr neb:///foo:user.bar does not exist|,
     182like($@, qr|xattr user.bar does not exist|,
    187183    "get xattr from non-existant xattr key");
    188184
     
    256252    $neb->removexattr('foo', 'user.bar');
    257253};
    258 like($@, qr|xattr neb:///foo:user.bar does not exist|,
     254like($@, qr|xattr user.bar does not exist|,
    259255    "remove xattr from non-existant xattr key");
    260256
  • trunk/Nebulous/t/68_client_chmod.t

    r24281 r41172  
    4141    is($mode, 0440, "returned mode");
    4242    is($neb->getxattr($key, 'user.mode'), 0440, "xattr user.mode");
     43
     44    # reset to 600 so the user can delete the file and /tmp entry
     45    chmod(0600, $path);
    4346}
    4447
     
    5356    my $mode = $neb->chmod($key, 0440);
    5457
    55     my $st1 = stat(URI->new($uri1)->path);
    56     my $st2 = stat(URI->new($uri2)->path);
     58    my $path1 = URI->new($uri1)->path;
     59    my $path2 = URI->new($uri2)->path;
     60
     61    my $st1 = stat($path1);
     62    my $st2 = stat($path2);
    5763
    5864    is($st1->mode &07777, 0440, "chmod() first instance");
     
    6066    is($mode, 0440, "returned mode");
    6167    is($neb->getxattr($key, 'user.mode'), 0440, "xattr user.mode");
     68
     69    # reset to 600 so the user can delete the file and /tmp entry
     70    chmod(0600, $path1);
     71    chmod(0600, $path2);
    6272}
    6373
  • trunk/Nebulous/t/70_neb-ls.t

    r24560 r41172  
    2323use Test::Cmd;
    2424use Nebulous::Client;
     25use Nebulous::Util qw( :standard );
    2526use Test::Nebulous;
    2627
     
    2829my $neb_url  = "http://$hostport/nebulous";
    2930
    30 
    3131my $cmd = 'bin/neb-ls';
    3232
    33 # last ditch effort to make sure dsget is executable
     33# last ditch effort to make sure neb-ls is executable
    3434chmod 0755, 'bin/neb-ls';
    3535
     
    3737isa_ok($test, 'Test::Cmd');
    3838
    39 # NEB_SERVER env var not set
     39# test if NEB_SERVER env var not set
    4040undef $ENV{'NEB_SERVER'} if defined $ENV{'NEB_SERVER'};
    4141Test::Nebulous->setup;
    42 
    4342{
    4443    $test->run(args => '');
     
    4645}
    4746
    48 # NEB_SERVER set
    49 Test::Nebulous->setup;
    50 
     47# NEB_SERVER set (and used in the following tests)
     48Test::Nebulous->setup;
    5149{
    5250    $ENV{NEB_SERVER} = $neb_url;
     
    5755
    5856Test::Nebulous->setup;
    59 
    60 {
    61     my $neb = Nebulous::Client->new(
    62         proxy => $neb_url,
    63     );
    64     $neb->create('foo');
    65 
    66     $test->run(args => '');
    67 
     57{
     58    my $neb = Nebulous::Client->new(
     59        proxy => $neb_url,
     60    );
     61    $neb->create('foo');
     62
     63    $test->run(args => '');
    6864    is($? >> 8, 0, "exit code");
    6965    like($test->stdout, qr/^foo$/,      "stdout");
     
    7268
    7369Test::Nebulous->setup;
    74 
    7570{
    7671    my $neb = Nebulous::Client->new(
     
    8378
    8479    is($? >> 8, 0, "exit code");
    85     like($test->stdout, qr/^bar\nfoo$/,  "stdout");
     80    like($test->stdout, qr/^bar\s+foo$/,  "stdout");
    8681    like($test->stderr, qr/^$/,         "stderr");
    8782}
    8883
    8984Test::Nebulous->setup;
    90 
     85{
     86    my $neb = Nebulous::Client->new(
     87        proxy => $neb_url,
     88    );
     89    $neb->create('foo');
     90
     91    my $locations = $neb->find_instances( "foo" );
     92    my $diskfile = _get_file_path( @$locations[0] );
     93    my $filestats = `ls -l $diskfile`;
     94
     95    $test->run(args => '-l');
     96
     97    is($? >> 8, 0, "exit code");
     98    like($test->stdout, qr/^$filestats$/,  "stdout");
     99    like($test->stderr, qr/^$/,         "stderr");
     100}
     101
     102Test::Nebulous->setup;
    91103{
    92104    my $neb = Nebulous::Client->new(
     
    96108    $neb->create('bar');
    97109
    98     $test->run(args => '-l');
     110    $test->run(args => '-c');
    99111
    100112    is($? >> 8, 0, "exit code");
     
    109121        proxy => $neb_url,
    110122    );
    111     $neb->create('foo');
    112     $neb->create('bar');
    113 
    114     $test->run(args => '-1');
    115 
    116     is($? >> 8, 0, "exit code");
    117     like($test->stdout, qr/^bar\nfoo\n$/,   "stdout");
    118     like($test->stderr, qr/^$/,             "stderr");
    119 }
    120 
    121 Test::Nebulous->setup;
    122 
    123 {
    124     my $neb = Nebulous::Client->new(
    125         proxy => $neb_url,
    126     );
    127     $neb->create('a/foo');
    128 
    129     $test->run(args => '');
    130 
    131     is($? >> 8, 0, "exit code");
    132     like($test->stdout, qr||,               "stdout");
     123    $neb->create('a/foo');
     124
     125    $test->run(args => '');
     126
     127    is($? >> 8, 0, "exit code");
     128    like($test->stdout, qr|^a/$|,           "stdout");
    133129    like($test->stderr, qr/^$/,             "stderr");
    134130}
     
    161157
    162158    is($? >> 8, 0, "exit code");
    163     like($test->stdout, qr|^a/bar\na/foo$|,  "stdout");
     159    like($test->stdout, qr|^a/bar\s+a/foo$|,  "stdout");
    164160    like($test->stderr, qr/^$/,             "stderr");
    165161}
     
    193189
    194190    is($? >> 8, 0, "exit code");
    195     like($test->stdout, qr|^a/b/\na/foo$|,        "stdout");
     191    like($test->stdout, qr|^a/b/\s+a/foo$|,        "stdout");
    196192    like($test->stderr, qr/^$/,             "stderr");
    197193}
  • trunk/Nebulous/t/71_client_there_can_be_only_one.t

    r24930 r41172  
    1010use Apache::Test qw( -withtestmore );
    1111
    12 plan tests => 8;
     12plan tests => 13;
    1313
    1414use lib qw( ./t ./lib );
     
    2121
    2222Test::Nebulous->setup;
     23Test::Nebulous->cleanup;
    2324
     25## volume is defined, but it is not valid (should exit)
     26## Test::Nebulous->setup;
     27## {
     28##     my $key = "foo";
     29##     my $neb = Nebulous::Client->new(
     30##         proxy => "http://$hostport/nebulous",
     31##     );
     32##
     33##     my $uri = $neb->create($key, "node01");
     34##
     35##     $neb->replicate($key, "node02");
     36##
     37##     ## set node02 to an invalid state:
     38##     Test::Nebulous->switch_node_state;
     39##
     40##     # if requested node is invalid, the other instance is kept and the invalid one removed
     41##     # but since invalid instances are removed with a prune call, they are not counted
     42##     # in the number of items removed (return by the function call)
     43##     is($neb->there_can_be_only_one($key, "node02"), 0, "there can be only one!");
     44##     my $locations = $neb->find_instances( "foo" );
     45##
     46##     is( scalar @$locations, 1, "found 1" );
     47##     is($locations->[0], $uri, "instance on correct volume" );
     48## };
     49## is($@, "", "there_can_be_only_one with supplied volume should succeed");
     50## die "asdf";
     51
     52#######
     53
     54## volume not defined
     55Test::Nebulous->setup;
    2456{
    2557    my $key = "foo";
     
    3769}
    3870
     71## volume is defined, only valid instances
    3972Test::Nebulous->setup;
    40 
    41 {
     73eval {
    4274    my $key = "foo";
    4375    my $neb = Nebulous::Client->new(
     
    4577    );
    4678    $neb->create($key, "node01");
     79
    4780    my $uri = $neb->replicate($key, "node02");
    48 
    4981    is($neb->there_can_be_only_one($key, "node02"), 1, "there can be only one!");
    5082
     
    5385    is( scalar @$locations, 1, "found 1" );
    5486    is($locations->[0], $uri, "instance on correct volume" );
    55 }
     87};
     88is($@, "", "there_can_be_only_one with supplied volume should succeed");
     89
     90## volume is defined, but it is not valid (should exit)
     91Test::Nebulous->setup;
     92eval {
     93    my $key = "foo";
     94    my $neb = Nebulous::Client->new(
     95        proxy => "http://$hostport/nebulous",
     96    );
     97    my $uri = $neb->create($key, "node01");
     98
     99    $neb->replicate($key, "node02");
     100
     101    ## set node02 to an invalid state:
     102    Test::Nebulous->switch_node_state;
     103
     104    # if requested node is invalid, nothing is removed
     105    is($neb->there_can_be_only_one($key, "node02"), 0, "there can be only one!");
     106
     107    my $locations = $neb->find_instances( "foo" );
     108
     109    is( scalar @$locations, 1, "found 1" );
     110    is($locations->[0], $uri, "instance on correct volume" );
     111};
     112is($@, "", "there_can_be_only_one with supplied volume should succeed");
    56113
    57114Test::Nebulous->setup;
  • trunk/Nebulous/t/72_neb-cull.t

    r25121 r41172  
    3939# NEB_SERVER env var not set
    4040undef $ENV{'NEB_SERVER'} if defined $ENV{'NEB_SERVER'};
    41 Test::Nebulous->setup;
    42 
     41
     42## problem test
     43## Test::Nebulous->setup;
     44## {
     45##     $ENV{NEB_SERVER} = $neb_url;
     46##
     47##     my $key = 'foo';
     48##
     49##     my $neb = Nebulous::Client->new(
     50##         proxy => $neb_url,
     51##     );
     52##     $neb->create($key);
     53##
     54##     $test->run(args => "--one_only " . $key);
     55##
     56##     ## my $line1 = $test->stdout;
     57##     ## print "stdout: $line1\n";
     58##     ##
     59##     ## my $line2 = $test->stderr;
     60##     ## print "stderr: $line2\n";
     61##
     62##     is($neb->stat($key)->[6], 1, "correct # of instances");
     63##     is($? >> 8, 255, "exit code");
     64##     like($test->stdout, qr/^$/, "stdout");
     65##     like($test->stderr, qr/no instances/, "stderr");
     66## }
     67## die "stop";
     68
     69## Test::Nebulous->setup;
     70## {
     71##     my $key = 'foo';
     72##
     73##     my $neb = Nebulous::Client->new(
     74##         proxy => $neb_url,
     75##     );
     76##     $neb->create($key);
     77##     $neb->replicate($key);
     78##
     79##     $test->run(args => "--server $neb_url $key");
     80##
     81##     my $line = $test->stderr;
     82##     print "stderr: $line\n";
     83##
     84##     is($neb->stat($key)->[6], 1, "correct # of instances");
     85##     is($? >> 8, 0, "exit code");
     86##     like($test->stdout, qr/^$/, "stdout");
     87##     like($test->stderr, qr/^$/, "stderr");
     88## }
     89## die "TEST";
     90
     91Test::Nebulous->setup;
    4392{
    4493    $test->run(args => '');
     
    4897# NEB_SERVER set
    4998Test::Nebulous->setup;
    50 
    5199{
    52100    $ENV{NEB_SERVER} = $neb_url;
     
    57105
    58106Test::Nebulous->setup;
    59 
    60 {
    61     my $key = 'foo';
    62 
    63     my $neb = Nebulous::Client->new(
    64         proxy => $neb_url,
    65     );
    66     $neb->create($key);
     107{
     108    my $key = 'foo';
     109
     110    my $neb = Nebulous::Client->new(
     111        proxy => $neb_url,
     112    );
     113    $neb->create($key);
     114
     115    $test->run(args => "--server $neb_url $key");
     116#   $test->run(args => $key);
     117
     118    is($neb->stat($key)->[6], 1, "correct # of instances");
     119    is($? >> 8, 255, "exit code");
     120    like($test->stdout, qr/^$/, "stdout");
     121    like($test->stderr, qr/failed to cull Nebulous key/, "stderr");
     122}
     123
     124Test::Nebulous->setup;
     125
     126{
     127    my $key = 'foo';
     128
     129    my $neb = Nebulous::Client->new(
     130        proxy => $neb_url,
     131    );
     132    $neb->create($key);
     133    $neb->replicate($key);
    67134
    68135    $test->run(args => $key);
    69136
    70     is($neb->stat($key)->[6], 1, "correct # of instances");
    71     is($? >> 8, 255, "exit code");
    72     like($test->stdout, qr/^$/, "stdout");
    73     like($test->stderr, qr/failed to cull Nebulous key/, "stderr");
    74 }
    75 
    76 Test::Nebulous->setup;
    77 
    78 {
    79     my $key = 'foo';
    80 
    81     my $neb = Nebulous::Client->new(
    82         proxy => $neb_url,
    83     );
    84     $neb->create($key);
     137    my $line = $test->stderr;
     138
     139    # the default min_copies is 2:
     140    is($neb->stat($key)->[6], 2, "correct # of instances");
     141    is($? >> 8, 255, "exit code");
     142    like($test->stdout, qr/^$/, "stdout");
     143    like($test->stderr, qr/not enough instances/, "stderr");
     144}
     145
     146Test::Nebulous->setup;
     147
     148{
     149    my $key = 'foo';
     150
     151    my $neb = Nebulous::Client->new(
     152        proxy => $neb_url,
     153    );
     154    $neb->create($key);
     155    $neb->replicate($key);
    85156    $neb->replicate($key);
    86157
    87158    $test->run(args => $key);
    88159
    89     is($neb->stat($key)->[6], 1, "correct # of instances");
    90     is($? >> 8, 0, "exit code");
    91     like($test->stdout, qr/^$/, "stdout");
    92     like($test->stderr, qr/^$/, "stderr");
    93 }
    94 
    95 Test::Nebulous->setup;
    96 
    97 {
    98     my $key = 'foo';
    99 
    100     my $neb = Nebulous::Client->new(
    101         proxy => $neb_url,
    102     );
    103     $neb->create($key);
    104     $neb->replicate($key);
    105     $neb->replicate($key);
    106 
    107     $test->run(args => $key);
    108 
    109160    is($neb->stat($key)->[6], 2, "correct # of instances");
    110161    is($? >> 8, 0, "exit code");
     
    113164}
    114165
     166## problem test
    115167Test::Nebulous->setup;
    116168
     
    202254
    203255    is($neb->stat($key)->[6], 1, "correct # of instances");
    204     is($? >> 8, 0, "exit code");
     256
     257    is($? >> 8, 255, "exit code");
    205258    like($test->stdout, qr/^$/, "stdout");
    206259    like($test->stderr, qr/not enough instances/, "stderr");
     
    221274    $test->run(args => "--min_copies 2 " . $key);
    222275
    223     is($neb->stat($key)->[6], 1, "correct # of instances");
     276    is($neb->stat($key)->[6], 2, "correct # of instances");
    224277    is($? >> 8, 0, "exit code");
    225278    like($test->stdout, qr/^$/, "stdout");
  • trunk/Nebulous/t/conf/extra.conf.in

    r4911 r41172  
    33# this file will be Include-d by @ServerRoot@/httpd.conf
    44
     5# need to add MPM?
     6
     7# Conflicts: mpm_worker mpm_prefork
     8#LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
     9#LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so
     10LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so
     11#LoadModule cgid_module /usr/lib/apache2/modules/mod_cgid.so
     12LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so
     13LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so
     14
     15# event MPM
     16# StartServers: initial number of server processes to start
     17# MinSpareThreads: minimum number of worker threads which are kept spare
     18# MaxSpareThreads: maximum number of worker threads which are kept spare
     19# ThreadsPerChild: constant number of worker threads in each server process
     20# MaxRequestWorkers: maximum number of worker threads
     21# MaxConnectionsPerChild: maximum number of requests a server process serves
     22<IfModule mpm_event_module>
     23        StartServers                     2
     24        MinSpareThreads          25
     25        MaxSpareThreads          75
     26        ThreadLimit                      64
     27        ThreadsPerChild          25
     28        MaxRequestWorkers         150
     29        MaxConnectionsPerChild   0
     30</IfModule>
     31
     32<IfModule mod_alias.c>
     33        <IfModule mod_cgi.c>
     34#       Define ENABLE_USR_LIB_CGI_BIN
     35        </IfModule>
     36
     37        <IfModule mod_cgid.c>
     38#       Define ENABLE_USR_LIB_CGI_BIN
     39        </IfModule>
     40
     41        <IfDefine ENABLE_USR_LIB_CGI_BIN>
     42                ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
     43                <Directory "/usr/lib/cgi-bin">
     44                        AllowOverride None
     45                        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
     46                        Require all granted
     47                </Directory>
     48        </IfDefine>
     49</IfModule>
     50
     51# nebulous location:
    552<Location /nebulous>
    653    SetHandler perl-script
    7     PerlResponseHandler Apache2::SOAP
     54    PerlResponseHandler Apache::SOAP
    855    PerlSetVar dispatch_to "PerlHandler Nebulous::Server::SOAP"
    956    PerlSetVar options "compress_threshold => 10000"
  • trunk/Nebulous/t/conf/startup.pl.in

    r24372 r41172  
    55use lib qw( @ServerRoot@ );
    66
     7use ModPerl::Util (); #for CORE::GLOBAL::exit
     8
     9use Apache2::RequestRec ();
     10use Apache2::RequestIO ();
     11use Apache2::RequestUtil ();
     12
     13use Apache2::ServerRec ();
     14use Apache2::ServerUtil ();
     15use Apache2::Connection ();
     16use Apache2::Log ();
     17
     18use APR::Table ();
     19
     20use ModPerl::Registry ();
     21
     22use Apache2::Const -compile => ':common';
     23use APR::Const -compile => ':common';
     24
     25use Apache::SOAP;
     26
    727use Apache::DBI;
    828use DBI;
     
    1030use Nebulous::Server::Apache;
    1131use Nebulous::Server;
    12 use Test::Nebulous;
     32
     33# do not inherit here, let's be explicit
     34# use Test::Nebulous;
     35
     36# EAM : making this match Nebulous-Server/docs/apache2-mod_perl-startup.pl:
     37
     38# use the real mysql server:
     39#my $dsn         = 'DBI:mysql:database=nebulous:host=localhost,mysql_socket=8500';
     40#my $dbuser      = 'nebulous';
     41#my $dbpasswd    = '';
     42
     43# use the test mysql server (defined in Test::Nebulous)
     44my $dsn         = 'DBI:mysql:database=test:host=localhost:mysql_socket=/var/run/mysqld/mysqld.sock';
     45my $dbuser      = 'test';
     46my $dbpasswd    = '';
    1347
    1448#$Apache::DBI::DEBUG = 1;
    15 Apache::DBI->connect_on_init( $NEB_DB, $NEB_USER, $NEB_PASS );
    16 Apache::DBI->setPingTimeOut($NEB_DB, 10);
     49#Apache::DBI->connect_on_init( $NEB_DB, $NEB_USER, $NEB_PASS );
     50Apache::DBI->setPingTimeOut($dsn, 10);
    1751
    1852my $config = Nebulous::Server::Config->new(
     
    2256$config->add_db(
    2357    dbindex     => 0,
    24     dsn         => $NEB_DB,
    25     dbuser      => $NEB_USER,
    26     dbpasswd    => $NEB_PASS,
     58    dsn         => $dsn,
     59    dbuser      => $dbuser,
     60    dbpasswd    => $dbpasswd,
    2761);
    28 #$config->add_db(
    29 #    dbindex     => 1,
    30 #    dsn         => 'DBI:mysql:database=nebulous1:host=localhost',
    31 #    dbuser      => $dbuser,
    32 #    dbpasswd    => $dbpasswd,
    33 #);
    3462
    3563Nebulous::Server::SOAP->new_on_init($config);
Note: See TracChangeset for help on using the changeset viewer.