Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Test files (based on Test::Class). README glorified.

  • Loading branch information...
commit dbe6cfaba6a57baee86713b86239b002372bd452 1 parent 93a8d50
M. Nunberg authored
26 Client.xs
@@ -344,6 +344,21 @@ SV *PLCB_stats(SV *self, AV *stats)
344 344 return ret_hvref;
345 345 }
346 346
  347 +static SV*
  348 +return_empty(SV *self, int error, const char *errmsg)
  349 +{
  350 + libcouchbase_t instance;
  351 + PLCB_t *object;
  352 + AV *ret_av;
  353 +
  354 + mk_instance_vars(self, instance, object);
  355 + ret_av = newAV();
  356 + av_store(ret_av, PLCB_RETIDX_ERRNUM, newSViv(error));
  357 + av_store(ret_av, PLCB_RETIDX_ERRSTR, newSVpvf(
  358 + "Couchbase::Client usage error: %s", errmsg));
  359 + plcb_ret_blessed_rv(object, ret_av);
  360 +}
  361 +
347 362 /*Used for set/get/replace/add common interface*/
348 363 static libcouchbase_storage_t PLCB_XS_setmap[] = {
349 364 LIBCOUCHBASE_SET,
@@ -403,6 +418,10 @@ PLCB_set(self, key, value, ...)
403 418 CODE:
404 419 set_plst_get_offset(4, exp_offset, "USAGE: set(key, value [,expiry]");
405 420
  421 + if(ix >= 3 && SvROK(value)) {
  422 + die("Cannot append/prepend a reference");
  423 + }
  424 +
406 425 RETVAL = PLCB_set_common(
407 426 self, key, value,
408 427 PLCB_XS_setmap[ix],
@@ -485,6 +504,13 @@ PLCB_cas(self, key, value, cas_sv, ...)
485 504 STRLEN cas_len;
486 505
487 506 CODE:
  507 + if(SvTYPE(cas_sv) == SVt_NULL) {
  508 + /*don't bother the network if we know our CAS operation will fail*/
  509 + RETVAL = return_empty(self,
  510 + LIBCOUCHBASE_KEY_EEXISTS, "I was given an undef cas");
  511 + return;
  512 + }
  513 +
488 514 plcb_cas_from_sv(cas_sv, cas_val, cas_len);
489 515
490 516 set_plst_get_offset(5, exp_offset, "USAGE: cas(key,value,cas[,expiry])");
7 MANIFEST
... ... @@ -1,7 +1,7 @@
1 1 Changes
2 2 MANIFEST
3 3 Makefile.PL
4   -README
  4 +README.pod
5 5
6 6 lib/Couchbase/Client.pm
7 7 lib/Couchbase/Client/Return.pm
@@ -16,6 +16,10 @@ lib/Couchbase/Client/Async.pm
16 16 lib/Couchbase/Client/Async/Event.pm
17 17 lib/Couchbase/Client/Async/Request.pm
18 18
  19 +lib/Couchbase/MockServer.pm
  20 +lib/Couchbase/Test/ClientSync.pm
  21 +lib/Couchbase/Test/Common.pm
  22 +
19 23 Client.xs
20 24 Async.xs
21 25
@@ -36,3 +40,4 @@ error_constants.pl
36 40 print_constants.pl
37 41
38 42 t/00-load.t
  43 +t/01-main.t
39 Makefile.PL
... ... @@ -1,9 +1,21 @@
1 1 use strict;
2 2 use warnings;
3 3 use ExtUtils::MakeMaker;
  4 +use Dir::Self;
4 5
5   -system("$^X error_constants.pl lib/Couchbase/Client/Errors_const.pm");
6   -system("$^X idx_constants.pl lib/Couchbase/Client/IDXConst_const.pm");
  6 +use lib __DIR__;
  7 +
  8 +my $plcb_config = do 'PLCB_Config.pm';
  9 +
  10 +my $include_path = $plcb_config->{COUCHBASE_INCLUDE_PATH} || "";
  11 +my $library_path = $plcb_config->{COUCHBASE_LIBRARY_PATH} || "";
  12 +
  13 +if($include_path) {
  14 + $include_path = "-I$include_path";
  15 +}
  16 +if($library_path) {
  17 + $library_path = "-L$library_path";
  18 +}
7 19
8 20 WriteMakefile(
9 21 NAME => 'Couchbase::Client',
@@ -16,18 +28,33 @@ WriteMakefile(
16 28 ($ExtUtils::MakeMaker::VERSION >= 6.3002
17 29 ? ('LICENSE'=> 'perl')
18 30 : ()),
19   - PL_FILES => {},
  31 +
  32 + PL_FILES => {
  33 + "error_constants.pl" => "lib/Couchbase/Client/Errors_const.pm",
  34 + "idx_constants.pl" => "lib/Couchbase/Client/IDXConst_const.pm"
  35 + },
  36 +
  37 + CONFIGURE_REQUIRES => {
  38 + 'Dir::Self' => 0,
  39 + },
  40 +
20 41 PREREQ_PM => {
21 42 'Array::Assign' => 0,
22 43 'ExtUtils::H2PM' => 0.08,
23 44 'Class::XSAccessor' => 1.11,
24 45 'Test::More' => 0,
  46 +
  47 + #These modules are needed for tests, but not strictly required for
  48 + #functionality
  49 +
  50 + 'Log::Fu' => 0.25,
  51 + 'Test::Class' => 0.36,
  52 + 'LWP::UserAgent' => 0,
25 53 },
26 54 NEEDS_LINKING => 1,
27 55 OPTIMIZE => '-O0 -ggdb3',
28   - LIBS => ['-L/sources/libcouchbase/.libs -lcouchbase -lcouchbase_libevent'],
29   - #LIBS => ['-lcouchbase'],
30   - INC => '-I/sources/libcouchbase/include /sources/memcached/include',
  56 + LIBS => ["$library_path -lcouchbase -lcouchbase_libevent"],
  57 + INC => $include_path,
31 58 dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
32 59 clean => { FILES => 'Couchbase-Client-*' },
33 60 );
14 PLCB_Config.pm
... ... @@ -0,0 +1,14 @@
  1 +#this perl 'hash' contains configuration information necessary
  2 +#to bootstrap and/or configure the perl couchbase client and run
  3 +#necessary tests.
  4 +
  5 +{
  6 + COUCHBASE_INCLUDE_PATH => "/sources/libcouchbase/include",
  7 + COUCHBASE_LIBRARY_PATH => "/sources/libcouchbase/.libs",
  8 +
  9 + #URL from which to download the mock JAR file for tests
  10 + COUCHBASE_MOCK_JARURL =>
  11 + "http://files.couchbase.com/maven2/org/couchbase/mock/".
  12 + "CouchbaseMock/0.5-SNAPSHOT/CouchbaseMock-0.5-20120103.162550-11.jar",
  13 +};
  14 +
13 README
... ... @@ -1,13 +0,0 @@
1   -Couch::Couchbase is a Perl client for Couchbase (http://www.couchbase.org).
2   -
3   -This is a 'smart' or 'Type-2' client, as opposed to legacy Memcached clients.
4   -
5   -This module depends on having libcouchbase development packages installed;
6   -
7   -It currently features no functionality unit tests.
8   -
9   -Included is a wrapper module which provides backwards API compatibility
10   -with Cache::Memcached::* modules.
11   -
12   -Currently only the single-op synchronous inteface is implemented.
13   -
103 README.pod
Source Rendered
... ... @@ -0,0 +1,103 @@
  1 +=head1 Introduction
  2 +
  3 +Couch::Couchbase is a Perl client for Couchbase (http://www.couchbase.org).
  4 +
  5 +The couchbase client is a smart, vbucket-aware client. What this means is that
  6 +Couchbase::Client can tap into your Couchbase cluster, with the client needing
  7 +to be able to access (initially) only a single entry point.
  8 +
  9 +The module provides:
  10 +
  11 +=head2 Synchronous Interface: Couchbase::Client
  12 +
  13 +This is the simplest and most tested interface. The methods are self-explanatory.
  14 +Additionally, the return type is complex and detailed, allowing error reporting
  15 +for any unexpected conditions (something severely lacking in any Memcache client
  16 +implementation).
  17 +
  18 +=head2 Legacy Interface: Couchbase::Client::Compat
  19 +
  20 +Drop-in replacement for Cache::Memcached and Cache::Memcached::Fast.
  21 +
  22 +I can't say it's 100% compatible yet, but the basic methods have been implemented.
  23 +Internally it just wraps around the new interface
  24 +
  25 +=head2 Asynchronous Framework for Perl: Couchbase::Client::Async
  26 +
  27 +Provides the necessary functions and utilities needed to make a POE, IO::Async,
  28 +etc. client for Couchbase.
  29 +
  30 +=head2 Mock Server Interface: Couchbase::MockServer
  31 +
  32 +Interface to the Java C<Couchbase::Mock>. This is a work in progress.
  33 +
  34 +=head1 Installing
  35 +
  36 +I will be focusing on installing and configuring C<libcouchbase> itself, the C
  37 +client library. It is assumed you have a functional installation of the couchbase
  38 +server somewhere. If not, go to http://www.couchbase.org
  39 +
  40 +To use this module, you should have installed C<libvbucket> (see the links on
  41 +the side here http://www.couchbase.com/develop/c/current).
  42 +
  43 +As of 01/28/2011, you will need to download C<libcouchbase> itself from
  44 +github (the current release versions contain bugs which may break this module).
  45 +
  46 +=head2 Building C<libcouchbase>
  47 +
  48 +
  49 +C<libcouchbase> itself depends on C<libvbucket>, so make sure to install that
  50 +(and its development libraries) first.
  51 +
  52 +Currently, I know of these dependencies:
  53 +
  54 +=over
  55 +
  56 +=item libevent >= 1.4
  57 +
  58 +=back
  59 +
  60 +Additionally, C<libcouchbase> depends on header files available from the
  61 +C<engine-pu> branch of the C<memcached> project. Note that actually building
  62 +memcached itself is not required.
  63 +
  64 +Your best bet would be to do
  65 +something like this:
  66 +
  67 + ~$ mkdir couch
  68 + ~$ git clone https://github.com/memcached/memcached.git -b engine-pu couch/memcached
  69 + ~$ git clone https://github.com/couchbase/libcouchbase.git couch/libcouchbase
  70 +
  71 + ~$ cd couch/libcouchbase
  72 + ~$ ./config/autorun.sh
  73 +
  74 + #make sure we know about the new memcached headers:
  75 +
  76 + ~$ CPPFLAGS=-I../memcached/include ./configure
  77 + ~$ make
  78 +
  79 + #optional, run some tests:
  80 + ~$ make check
  81 +
  82 +
  83 +=head2 Building Couchbase::Client
  84 +
  85 +To build the perl client, you should edit the C<PLCB_Config.pm> file, and
  86 +change the keys C<COUCHBASE_INCLUDE_PATH> and C<COUCHBASE_LIBRARY_PATH> to their
  87 +appropriate locations.
  88 +
  89 +If you were following the example above, your keys should look like this
  90 +
  91 + COUCHBASE_INCLUDE_PATH => "~/couch/libcouchbase/include",
  92 + COUCHBASE_LIBRARY_PATH => "~/couch/libcouchbase/.libs"
  93 +
  94 + #the '.libs' is an Autoconf thing, it seems.
  95 +
  96 +run
  97 + $ perl Makefile.PL #you know the drill..
  98 + $ make test
  99 +
  100 +There are some top-level scripts. Some have meaning to only the author, some might
  101 +be useful.
  102 +
  103 +Also, check out the runnable modules in the C<t/> directory
2  ignore.txt
@@ -10,3 +10,5 @@ pm_to_blib*
10 10 cover_db
11 11 pod2htm*.tmp
12 12 Couchbase-Client-*
  13 +*.jar
  14 +t/tmp/*
171 lib/Couchbase/MockServer.pm
... ... @@ -0,0 +1,171 @@
  1 +package Couchbase::MockServer;
  2 +use strict;
  3 +use warnings;
  4 +use LWP::UserAgent;
  5 +use File::Basename;
  6 +use URI;
  7 +use File::Path qw(mkpath);
  8 +use IO::Socket::INET;
  9 +use Socket;
  10 +use POSIX qw(:errno_h :signal_h);
  11 +use Time::HiRes;
  12 +use Log::Fu;
  13 +use Data::Dumper;
  14 +
  15 +
  16 +
  17 +my $SYMLINK = "CouchbaseMock_PLTEST.jar";
  18 +our $INSTANCE;
  19 +
  20 +use Class::XSAccessor {
  21 + constructor => '_real_new',
  22 + accessors => [qw(
  23 + harakiri_addr
  24 + port
  25 + pid
  26 + dir
  27 + url
  28 + nodes
  29 + buckets
  30 + vbuckets
  31 + harakiri_socket
  32 + )]
  33 +};
  34 +# This is the couchbase mock server, it will attempt to download, spawn, and
  35 +# otherwise control the java-based CouchbaseMock server.
  36 +
  37 +sub _do_run {
  38 + my $self = shift;
  39 + my @command;
  40 + push @command, "java", "-jar", $self->dir . "/$SYMLINK";
  41 +
  42 + my $buckets_arg = "--buckets=";
  43 +
  44 + foreach my $bucket (@{$self->buckets}) {
  45 + my ($name,$password,$type) = @{$bucket}{qw(name password type)};
  46 + $name ||= "";
  47 + $password ||= "";
  48 + $type ||= "";
  49 + if($type && $type ne "couchbase" && $type ne "memcache") {
  50 + die("type for bucket must be either 'couchbase' or 'memcache'");
  51 + }
  52 + my $spec = join(":", $name, $password, $type);
  53 + $buckets_arg .= $spec . ",";
  54 + }
  55 +
  56 + $buckets_arg =~ s/,$//g;
  57 +
  58 + push @command, $buckets_arg;
  59 +
  60 + push @command, "--port=" . $self->port;
  61 +
  62 + if($self->nodes) {
  63 + push @command, "--nodes=" . $self->nodes;
  64 + }
  65 +
  66 + if($self->harakiri_addr) {
  67 + push @command, "--harakiri-monitor=" . $self->harakiri_addr
  68 + } else {
  69 + my $sock = IO::Socket::INET->new(Listen => 5);
  70 + $self->harakiri_socket($sock);
  71 + my $port = $self->harakiri_socket->sockport;
  72 + log_infof("Listening on %d for harakiri", $port);
  73 + push @command, "--harakiri-monitor=localhost:$port";
  74 + }
  75 +
  76 + my $pid = fork();
  77 +
  78 + if($pid) {
  79 + #Parent: setup harakiri monitoring socket
  80 + $self->pid($pid);
  81 + log_info("Launched CouchbaseMock PID=$pid");
  82 + if($self->harakiri_socket) {
  83 + $self->harakiri_socket->blocking(0);
  84 + my $begin_time = time();
  85 + my $max_wait = 5;
  86 + my $got_accept = 0;
  87 + while(time - $begin_time < $max_wait) {
  88 + my $sock = $self->harakiri_socket->accept();
  89 + if($sock) {
  90 + $self->harakiri_socket($sock);
  91 + $got_accept = 1;
  92 + log_info("Got harakiri connection");
  93 + my $buf;
  94 + $self->harakiri_socket->recv($buf, 100, 0);
  95 + last;
  96 + } else {
  97 + sleep(0.1);
  98 + }
  99 + }
  100 + if(!$got_accept) {
  101 + die("Could not establish harakiri control connection");
  102 + }
  103 + $self->harakiri_socket->blocking(1);
  104 + }
  105 + } else {
  106 + log_infof("Executing %s", join(" ", @command));
  107 + exec(@command);
  108 + }
  109 +}
  110 +
  111 +sub new {
  112 + my ($cls,%opts) = @_;
  113 + if($INSTANCE) {
  114 + log_warn("Returning cached instance");
  115 + return $INSTANCE;
  116 + }
  117 + unless(exists $opts{url} and exists $opts{dir}) {
  118 + die("Must have directory and URL");
  119 + }
  120 + my $o = $cls->_real_new(%opts);
  121 + my $dir = $o->dir;
  122 + my $url = URI->new($o->url);
  123 + my $basepath = basename($url->path);
  124 + my $fqpath = "$dir/$basepath";
  125 +
  126 + if(!-d $dir) {
  127 + mkpath($dir);
  128 + }
  129 +
  130 + if(!-e $fqpath) {
  131 + log_warn("$fqpath does not exist. Downloading..");
  132 + my $ua = LWP::UserAgent->new();
  133 + $ua->get($url, ':content_file' => $fqpath);
  134 + }
  135 +
  136 + unlink("$dir/$SYMLINK");
  137 + symlink($fqpath, "$dir/$SYMLINK");
  138 +
  139 + #Initialize buckets to their defaults
  140 + if(!$o->buckets) {
  141 + $o->buckets([{
  142 + name => "default",
  143 + #does mock not support SASL?
  144 + #password => "secret"
  145 + }]);
  146 + }
  147 +
  148 + #initialize port to the default, if not there already
  149 + if(!$o->port) {
  150 + $o->port(8091);
  151 + }
  152 +
  153 + $o->_do_run();
  154 + $INSTANCE = $o;
  155 + return $o;
  156 +}
  157 +
  158 +sub GetInstance {
  159 + my $cls = shift;
  160 + return $INSTANCE;
  161 +}
  162 +
  163 +sub DESTROY {
  164 + my $self = shift;
  165 + kill SIGTERM, $self->pid;
  166 + waitpid($self->pid, 0);
  167 + log_infof("Reaped PID %d, status %d", $self->pid, $? >> 8);
  168 +
  169 +}
  170 +
  171 +1;
180 lib/Couchbase/Test/ClientSync.pm
... ... @@ -0,0 +1,180 @@
  1 +package Couchbase::Test::ClientSync;
  2 +use strict;
  3 +use warnings;
  4 +use base qw(Couchbase::Test::Common);
  5 +use Test::More;
  6 +use Couchbase::Client;
  7 +use Couchbase::Client::Errors;
  8 +use Data::Dumper;
  9 +
  10 +sub setup_client :Test(startup)
  11 +{
  12 + my $self = shift;
  13 + $self->mock_init();
  14 +
  15 + my %options = (
  16 + %{$self->common_options},
  17 + compress_threshold => 100
  18 + );
  19 +
  20 + my $o = Couchbase::Client->new(\%options);
  21 +
  22 + $self->cbo( $o );
  23 + $self->{basic_keys} = [qw(
  24 + Foo Bar Baz Blargh Bleh Meh Grr Gah)];
  25 + $self->err_ok();
  26 +}
  27 +
  28 +sub cbo {
  29 + if(@_ == 1) {
  30 + return $_[0]->{object};
  31 + } elsif (@_ == 2) {
  32 + $_[0]->{object} = $_[1];
  33 + return $_[1];
  34 + }
  35 +}
  36 +
  37 +sub err_ok {
  38 + my $self = shift;
  39 + my $errors = $self->cbo->get_errors;
  40 + my $nerr = 0;
  41 + foreach my $errinfo (@$errors) {
  42 + $nerr++;
  43 + }
  44 + ok($nerr == 0, "Got no errors");
  45 +}
  46 +
  47 +sub k2v {
  48 + my ($self,$k) = @_;
  49 + reverse($k);
  50 +}
  51 +
  52 +sub v2k {
  53 + my ($self,$v) = @_;
  54 + reverse($v);
  55 +}
  56 +
  57 +sub set_ok {
  58 + my ($self,$msg,@args) = @_;
  59 + my $ret = $self->cbo->set(@args);
  60 + ok($ret->is_ok, $msg);
  61 + $self->err_ok();
  62 + if(!$ret->is_ok) {
  63 + diag($ret->errstr);
  64 + }
  65 +}
  66 +
  67 +sub get_ok {
  68 + my ($self,$key,$expected) = @_;
  69 + my $ret = $self->cbo->get($key);
  70 + ok($ret->is_ok, "Status OK for GET($key)");
  71 + ok($ret->value eq $expected, "Got expected value for $key");
  72 +}
  73 +
  74 +sub T0_set_values_simple :Test(no_plan) {
  75 + my $self = shift;
  76 + foreach my $k (@{$self->{basic_keys}}) {
  77 + $self->set_ok("Key '$k'", $k, $self->k2v($k));
  78 + $self->get_ok($k, $self->k2v($k))
  79 + }
  80 +}
  81 +
  82 +sub T1_get_nonexistent :Test(no_plan) {
  83 + my $self = shift;
  84 + my $v = $self->cbo->get('NonExistent');
  85 + is($v->errnum, COUCHBASE_KEY_ENOENT, "Got ENOENT for nonexistent key");
  86 + $self->err_ok();
  87 +}
  88 +
  89 +sub T2_mutators :Test(no_plan) {
  90 + my $self = shift;
  91 + my $o = $self->cbo;
  92 +
  93 + my $key = "mutate_key";
  94 + $o->remove($key); #if it already exists
  95 + is($o->add($key, "BASE")->errnum, 0, "No error for add on new key");
  96 + is($o->prepend($key, "PREFIX_")->errnum, 0, "No error for prepend");
  97 + is($o->append($key, "_SUFFIX")->errnum, 0, "No error for append");
  98 + is($o->get($key)->value, "PREFIX_BASE_SUFFIX", "Got expected mutated value");
  99 +}
  100 +
  101 +sub T3_arithmetic :Test(no_plan) {
  102 + my $self = shift;
  103 + my $o = $self->cbo;
  104 + my $key = "ArithmeticKey";
  105 + $o->remove($key);
  106 + my $wv;
  107 +
  108 + $wv = $o->arithmetic($key, -12, 42);
  109 + ok($wv->is_ok, "Set arithmetic with initial value");
  110 +
  111 + $o->remove($key);
  112 +
  113 + $wv = $o->arithmetic($key, -12, undef);
  114 + is($wv->errnum, COUCHBASE_KEY_ENOENT, "Error without initial value (undef)");
  115 +
  116 + $wv = $o->arithmetic($key, -12, 0, 120);
  117 + ok($wv->is_ok, "No error with initial value=0");
  118 + is($wv->value, 0, "Initial value is 0");
  119 +
  120 + $wv = $o->incr($key);
  121 + is($wv->value, 1, "incr() == 1");
  122 +
  123 + $wv = $o->decr($key);
  124 + is($wv->value, 0, "decr() == 0");
  125 +}
  126 +
  127 +sub T4_atomic :Test(no_plan) {
  128 + my $self = shift;
  129 + my $o = $self->cbo;
  130 + my $key = "AtomicKey";
  131 + $o->delete($key);
  132 +
  133 + is($o->replace($key, "blargh")->errnum, COUCHBASE_KEY_ENOENT,
  134 + "Can't replace non-existent value");
  135 +
  136 + my $wv = $o->set($key, "initial");
  137 + ok($wv->errnum == 0, "No error");
  138 + ok(length($wv->cas), "Have cas");
  139 + $o->set($key, "next");
  140 + my $newv = $o->cas($key, "my_next", $wv->cas);
  141 +
  142 + is($newv->errnum,
  143 + COUCHBASE_KEY_EEXISTS, "Got EEXISTS for outdated CAS");
  144 +
  145 + $newv = $o->get($key);
  146 + ok($newv->cas, "Have CAS for new value");
  147 + $wv = $o->cas($key, "synchronized", $newv->cas);
  148 + ok($wv->errnum == 0, "Got no error for CAS with updated CAS");
  149 + is($o->get($key)->value, "synchronized", "Got expected value");
  150 +
  151 + $o->delete($key);
  152 + ok($o->add($key, "value")->is_ok, "No error for ADD with nonexistent key");
  153 + is($o->add($key, "value")->errnum,
  154 + COUCHBASE_KEY_EEXISTS, "Got eexists for ADD on existing key");
  155 +
  156 + ok($o->delete($key, $newv->cas)->errnum, "Got error for DELETE with bad CAS");
  157 + $newv = $o->get($key);
  158 + ok($o->delete($key, $newv->cas)->errnum == 0,
  159 + "No error for delete with updated CAS");
  160 +}
  161 +
  162 +sub T5_conversion :Test(no_plan) {
  163 + my $self = shift;
  164 + my $o = $self->cbo;
  165 + my $structure = [ qw(foo bar baz) ];
  166 + my $key = "Serialization";
  167 + my $rv;
  168 +
  169 + ok($o->set($key, $structure)->is_ok, "Serialized OK");
  170 +
  171 + $rv = $o->get($key);
  172 + ok($rv->is_ok, "Got serialized structure OK");
  173 + is_deeply($rv->value, $structure, "Got back our array reference");
  174 + eval {
  175 + $o->append($key, $structure);
  176 + };
  177 + ok($@, "Got error for append/prepending a serialized structure ($@)");
  178 +}
  179 +
  180 +1;
52 lib/Couchbase/Test/Common.pm
... ... @@ -0,0 +1,52 @@
  1 +package Couchbase::Test::Common;
  2 +use strict;
  3 +use warnings;
  4 +use base qw(Test::Class);
  5 +use Test::More;
  6 +use Couchbase::MockServer;
  7 +use Data::Dumper;
  8 +
  9 +our $Mock;
  10 +
  11 +sub mock_init
  12 +{
  13 + my $self = shift;
  14 + if(!$Mock) {
  15 + die("Mock object not found. Initialize mock object with Initialize()");
  16 + }
  17 + $self->{mock} = $Mock;
  18 +}
  19 +
  20 +sub mock { $_[0]->{mock} }
  21 +
  22 +sub common_options {
  23 + my $self = shift;
  24 + my $opthash = {};
  25 + my $defbucket = $self->mock->buckets->[0];
  26 +
  27 + if($defbucket->{password}) {
  28 + $opthash->{username} = "some_user";
  29 + $opthash->{password} = $defbucket->{password};
  30 + }
  31 + $opthash->{server} = "127.0.0.1:" . $self->mock->port;
  32 + $opthash->{bucket} = $defbucket->{name};
  33 + return $opthash;
  34 +}
  35 +
  36 +sub k2v {
  37 + my ($self,$k) = @_;
  38 + reverse($k);
  39 +}
  40 +
  41 +sub v2k {
  42 + my ($self,$v) = @_;
  43 + reverse($v);
  44 +}
  45 +
  46 +
  47 +sub Initialize {
  48 + my ($cls,%opts) = @_;
  49 + $Mock = Couchbase::MockServer->new(%opts);
  50 + return $Mock;
  51 +}
  52 +1;
20 t/01-main.t
... ... @@ -0,0 +1,20 @@
  1 +#!/usr/bin/perl
  2 +use Dir::Self;
  3 +use lib __DIR__ . "../lib";
  4 +use lib __DIR__ . "../";
  5 +
  6 +$Log::Fu::LINE_PREFIX = '#';
  7 +
  8 +my $config = do 'PLCB_Config.pm';
  9 +use Couchbase::Test::Common;
  10 +my $TEST_PORT;
  11 +
  12 +Couchbase::Test::Common->Initialize(
  13 + url => $config->{COUCHBASE_MOCK_JARURL},
  14 + dir => __DIR__ . "/tmp",
  15 + port => 8092,
  16 + nodes => 2,
  17 +);
  18 +
  19 +use Couchbase::Test::ClientSync;
  20 +Test::Class->runtests();

0 comments on commit dbe6cfa

Please sign in to comment.
Something went wrong with that request. Please try again.