From f40e4c97e7538b996356ede28d9434591777022d Mon Sep 17 00:00:00 2001 From: "git@daemon.de" Date: Mon, 8 Jul 2013 15:36:04 +0200 Subject: [PATCH] added lots of unittests and while I was at it, fixed a couple of bugs in the backend modules. --- NOTEDB.pm | 3 +- NOTEDB/binary.pm | 33 ++++++---- NOTEDB/dbm.pm | 4 +- NOTEDB/dumper.pm | 6 +- NOTEDB/general.pm | 9 +-- NOTEDB/pwsafe3.pm | 33 ++++++---- NOTEDB/text.pm | 6 +- bin/note | 2 +- t/run.t | 151 +++++++++++++++++++++++++++++++++++----------- 9 files changed, 173 insertions(+), 74 deletions(-) diff --git a/NOTEDB.pm b/NOTEDB.pm index afd28ef..7ff6e9d 100644 --- a/NOTEDB.pm +++ b/NOTEDB.pm @@ -10,7 +10,7 @@ package NOTEDB; use Exporter (); use vars qw(@ISA @EXPORT $crypt_supported); -$NOTEDB::VERSION = "1.38"; +$NOTEDB::VERSION = "1.39"; BEGIN { # make sure, it works, otherwise encryption @@ -96,6 +96,7 @@ sub changed { # my $this = shift; $this->{changed} = 1; + return 1; } diff --git a/NOTEDB/binary.pm b/NOTEDB/binary.pm index b8f5028..6b6068f 100644 --- a/NOTEDB/binary.pm +++ b/NOTEDB/binary.pm @@ -5,7 +5,7 @@ # package NOTEDB::binary; -$NOTEDB::binary::VERSION = "1.10"; +$NOTEDB::binary::VERSION = "1.11"; use strict; use IO::Seekable; @@ -28,7 +28,7 @@ sub new { my $self = {}; bless($self,$class); - $self->{NOTEDB} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb"); + $self->{NOTEDB} = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb"); my $MAX_NOTE = $param{max_note} || 4096; my $MAX_TIME = $param{max_time} || 64; @@ -384,17 +384,22 @@ sub _retrieve { my $file = $this->{dbname}; if (-s $file) { if ($this->changed() || $this->{unread}) { - my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n"; - flock $fh, LOCK_EX; + open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n"; + flock NOTE, LOCK_EX; + my($buffer, $t, $n, %res); + seek(NOTE, 0, 0); # START FROM BEGINNING + while(read(NOTE, $buffer, $this->{sizeof})) { + my ($num, $note, $date) = unpack($this->{typedef}, $buffer); + $t = $this->ude($date); + $n = $this->ude($note); + $res{$num}->{'note'} = $n; + $res{$num}->{'date'} = $t; + } + flock NOTE, LOCK_UN; + close NOTE; - my %data = ParseConfig(-ConfigFile => $fh) or die "could not read to database: $!\n"; - - flock $fh, LOCK_UN; - $fh->close(); - - $this->{unread} = 0; - $this->{data} = \%data; - return %data; + $this->cache(%res); + return %res; } else { return %{$this->{data}}; @@ -405,6 +410,10 @@ sub _retrieve { } } +sub _store { + # compatibility dummy + return 1; +} 1; # keep this! diff --git a/NOTEDB/dbm.pm b/NOTEDB/dbm.pm index 7f6724f..480c59a 100644 --- a/NOTEDB/dbm.pm +++ b/NOTEDB/dbm.pm @@ -6,7 +6,7 @@ package NOTEDB::dbm; -$NOTEDB::dbm::VERSION = "1.40"; +$NOTEDB::dbm::VERSION = "1.41"; use DB_File; use NOTEDB; @@ -29,7 +29,7 @@ sub new my $notefile = "note.dbm"; my $timefile = "date.dbm"; - my $dbm_dir = $param{directory} || File::Spec->catfile($ENV{HOME}, ".note_dbm"); + my $dbm_dir = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".note_dbm"); if (! -d $dbm_dir) { # try to make it diff --git a/NOTEDB/dumper.pm b/NOTEDB/dumper.pm index d2445cd..8d66d8a 100644 --- a/NOTEDB/dumper.pm +++ b/NOTEDB/dumper.pm @@ -4,7 +4,7 @@ package NOTEDB::dumper; -$NOTEDB::dumper::VERSION = "1.01"; +$NOTEDB::dumper::VERSION = "1.02"; use strict; use Data::Dumper; @@ -29,7 +29,7 @@ sub new { my $self = {}; bless($self,$class); - $self->{NOTEDB} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb"); + $self->{NOTEDB} = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb"); if(! -e $param{dbname}) { open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n"; @@ -76,7 +76,7 @@ sub set_del_all { sub get_single { my($this, $num) = @_; - my($address, $note, $date, $buffer, $n, $t, $buffer, ); + my($address, $note, $date, $n, $t, $buffer, ); my %data = $this->get_all(); return ($data{$num}->{note}, $data{$num}->{date}); diff --git a/NOTEDB/general.pm b/NOTEDB/general.pm index 078cf1c..4c4ac51 100644 --- a/NOTEDB/general.pm +++ b/NOTEDB/general.pm @@ -4,7 +4,7 @@ package NOTEDB::general; -$NOTEDB::general::VERSION = "1.03"; +$NOTEDB::general::VERSION = "1.04"; use strict; #use Data::Dumper; @@ -44,6 +44,7 @@ sub new { $self->{mtime} = $self->get_stat(); $self->{unread} = 1; + $self->{changed} = 1; $self->{data} = {}; $self->{LOCKFILE} = $param{dbname} . "~LOCK"; @@ -88,7 +89,7 @@ sub set_del_all { sub get_single { my($this, $num) = @_; - my($address, $note, $date, $buffer, $n, $t, $buffer, ); + my($address, $note, $date, $n, $t, $buffer, ); my %data = $this->get_all(); @@ -143,7 +144,6 @@ sub get_nextnum { my @numbers = sort { $a <=> $b } keys %data; $num = pop @numbers; $num++; - return $num; return $num; } @@ -267,6 +267,7 @@ sub uen { $crypted = $raw; } my $coded = encode_base64($crypted); + chomp $coded; return $coded; } @@ -310,7 +311,7 @@ sub _retrieve { my ($this) = @_; my $file = $this->{dbname}; if (-s $file) { - if ($this->changed() || $this->{unread}) { + if ($this->{changed} || $this->{unread}) { my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n"; flock $fh, LOCK_EX; diff --git a/NOTEDB/pwsafe3.pm b/NOTEDB/pwsafe3.pm index b9163fc..52f2623 100644 --- a/NOTEDB/pwsafe3.pm +++ b/NOTEDB/pwsafe3.pm @@ -3,8 +3,8 @@ package NOTEDB::pwsafe3; -$NOTEDB::pwsafe3::VERSION = "1.03"; - +$NOTEDB::pwsafe3::VERSION = "1.04"; +use lib qw(/home/scip/D/github/Crypt--PWSafe3/blib/lib); use strict; use Data::Dumper; use Time::Local; @@ -51,14 +51,19 @@ sub version { sub get_stat { my ($this) = @_; - my $mtime = (stat($this->{dbname}))[9]; - return $mtime; + if(-e $this->{dbname}) { + return (stat($this->{dbname}))[9]; + } + else { + return time; + } } sub filechanged { my ($this) = @_; my $current = $this->get_stat(); - if ($current > $this->{mtime}) { + + if ($current >= $this->{mtime}) { $this->{mtime} = $current; return $current; } @@ -77,7 +82,7 @@ sub set_del_all { sub get_single { my($this, $num) = @_; - my($address, $note, $date, $buffer, $n, $t, $buffer, ); + my($address, $note, $date, $n, $t, $buffer, ); my %data = $this->get_all(); @@ -329,6 +334,7 @@ sub _retrieve { notes => $record->notes, group => $record->group, lastmod=> $record->lastmod, + ctime => $record->ctime, ); $data{$num}->{note} = \%entry; } @@ -355,7 +361,7 @@ sub _pwsafe3tonote { # # convert pwsafe3 record to note record my ($this, $record) = @_; - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($record->{lastmod}); + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($record->{ctime}); my $date = sprintf("%02d.%02d.%04d %02d:%02d:%02d", $mday, $mon+1, $year+1900, $hour, $min, $sec); chomp $date; my $note; @@ -406,6 +412,9 @@ sub _notetopwsafe3 { ($title, $content) = split /\n/, $text, 2; } + if(!defined $content) { $content = ""; } + if(!defined $group) { $group = ""; } + $user = $passwd = ''; if ($content =~ /(user|username|login|account|benutzer):\s*(.+)/i) { $user = $2; @@ -414,9 +423,10 @@ sub _notetopwsafe3 { $passwd = $2; } - # 1 2 3 5 6 7 - if ($date =~ /^(\d\d)\.(\d\d)\.(\{4}) (\d\d):(\d\d):(\d\d)$/) { - $ts = timelocal($7, $6, $5, $1, $2-1, $3-1900); + # 1 2 3 4 5 6 + if ($date =~ /^(\d\d)\.(\d\d)\.(\d{4}) (\d\d):(\d\d):(\d\d)$/) { + # timelocal($sec,$min,$hour,$mday,$mon,$year); + $ts = timelocal($6, $5, $4, $1, $2-1, $3-1900); } # make our topics pwsafe3 compatible groups @@ -426,17 +436,16 @@ sub _notetopwsafe3 { # pwsafe3 uses windows newlines, so convert ours $content =~ s/\n/\r\n/gs; - my %record = ( uuid => $this->_getuuid($num), user => $user, passwd => $passwd, group => $group, title => $title, + ctime => $ts, lastmod=> $ts, notes => $content, ); - return %record; } diff --git a/NOTEDB/text.pm b/NOTEDB/text.pm index c81f648..376b1f1 100644 --- a/NOTEDB/text.pm +++ b/NOTEDB/text.pm @@ -4,7 +4,7 @@ package NOTEDB::text; -$NOTEDB::text::VERSION = "1.03"; +$NOTEDB::text::VERSION = "1.04"; use strict; #use Data::Dumper; @@ -30,7 +30,7 @@ sub new { my $self = {}; bless($self,$class); - $self->{NOTEDB} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb"); + $self->{NOTEDB} = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb"); if(! -e $param{dbname}) { open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n"; @@ -77,7 +77,7 @@ sub set_del_all { sub get_single { my($this, $num) = @_; - my($address, $note, $date, $buffer, $n, $t, $buffer, ); + my($address, $note, $date, $n, $t, $buffer, ); my %data = $this->get_all(); diff --git a/bin/note b/bin/note index 712c103..3f3d003 100755 --- a/bin/note +++ b/bin/note @@ -144,7 +144,7 @@ $CONF = File::Spec->catfile($ENV{HOME}, ".noterc"); $USER = getlogin || getpwuid($<); chomp $USER; $TOPIC = 1; -$version = "1.3.17"; +$version = "1.3.18"; $CurDepth = 1; # the current depth inside the topic "directory" structure... $maxlen = "auto"; $timelen = 22; diff --git a/t/run.t b/t/run.t index 553d553..2d0e6f2 100644 --- a/t/run.t +++ b/t/run.t @@ -1,53 +1,132 @@ # -*-perl-*- -use Test::More tests => 8; -#use Test::More qw(no_plan); +#use Test::More tests => 8; +use Test::More qw(no_plan); +use Data::Dumper; + +my $expect = { + 1 => { + 'date' => '23.12.2000 10:33:02', + 'note' => 'any new text' + }, + 2 => { + 'date' => '03.02.2004 18:13:52', + 'note' => 'yet whatever you mean' + } + }; + BEGIN { use_ok "NOTEDB" }; require_ok("NOTEDB"); +my $key = '01010101'; +my $alg = 'Rijndael'; -require_ok("NOTEDB::binary"); +foreach my $CR (1 .. 0) { + $NOTEDB::crypt_supported = $CR; + + SKIP: { + skip "no crypt", 1 if $CR; # FIXME: for some weird reason, crypto doesn't work with ::binary? + eval { require NOTEDB::binary; }; + skip "Fatal, skipping test for NOTEDB::binary", 1 if $@; + unlink "t/binary.out"; + my $db = new NOTEDB::binary(dbname => "t/binary.out"); + $db->use_crypt($key, $alg) if $CR; + ok(ref($db), "Database object loaded"); + &wrdb($db, "NOTEDB::binary"); + } + SKIP: { + eval { require NOTEDB::general; }; + skip "Config::General not installed, skipping test for NOTEDB::general", 1 if $@; + unlink "t/general.out"; + my $db2 = NOTEDB::general->new(dbname => "t/general.out"); + $db2->use_crypt($key, $alg) if $CR; + ok(ref($db2), "Database object loaded"); + &wrdb($db2, "NOTEDB::general"); + } -my $db = new NOTEDB::binary(dbname => "t/1.out"); -ok(ref($db), "Database object loaded"); + SKIP: { + eval { require NOTEDB::text; }; + skip "Storable not installed, skipping test for NOTEDB::text", 1 if $@; + unlink "t/test.out"; + my $db3 = NOTEDB::text->new(dbname => "t/text.out"); + $db3->use_crypt($key, $alg) if $CR; + ok(ref($db3), "Database object loaded"); + &wrdb($db3, "NOTEDB::text"); + } + SKIP: { + eval { require NOTEDB::dumper; }; + skip "Data::Dumper not installed, skipping test for NOTEDB::dumper", 1 if $@; + unlink "t/dumper.out"; + my $db4 = NOTEDB::dumper->new(dbname => "t/dumper.out"); + $db4->use_crypt($key, $alg) if $CR; + ok(ref($db4), "Database object loaded"); + &wrdb($db4, "NOTEDB::dumper"); + } - - -my $r = $db->set_new(1, "any new text", "23.12.2000 10:33:02"); -ok($r, "true"); - - - -my $next = $db->get_nextnum(); -if ($next == 2) { - pass("Get next note id"); -} -else { - fail("Get next note id"); + SKIP: { + eval { require NOTEDB::dbm; }; + skip "DB_File not installed, skipping test for NOTEDB::dbm", 1 if $@; + unlink "t/note.dbm"; + unlink "t/date.dbm"; + my $db5 = NOTEDB::dbm->new(dbname => "t"); + $db5->use_crypt($key, $alg) if $CR; + ok(ref($db5), "Database object loaded"); + &wrdb($db5, "NOTEDB::dbm"); + } } - - - - -my ($note, $date) = $db->get_single(1); -if ($note =~ /any new text/) { - ok("Reading note"); -} -else { - fail("Reading note"); +SKIP: { + eval { require NOTEDB::pwsafe3; }; + skip "Crypt::PWSafe3 not installed, skipping test for NOTEDB::pwsafe3", 1 if $@; + unlink "t/pwsafe3.out"; + my $db6 = NOTEDB::pwsafe3->new(dbname => "t/pwsafe3.out"); + $db6->{key} = "01010101"; + ok(ref($db6), "Database object loaded"); + &wrdb3($db6, "NOTEDB::pwsafe3"); } +sub wrdb { + my ($db, $name) = @_; + is_deeply($db->{use_cache}, undef, "$name: Chache disabled"); + $db->set_new(1, $expect->{1}->{note}, $expect->{1}->{date}); + my ($note, $date) = $db->get_single(1); + like($note, qr/any new text/, "$name: Retrieve newly written entry content"); + like($date, qr/^\d\d/, "$name: Retrieve newly written entry date"); -my $expect = { - 1 => { - 'date' => '23.12.2000 10:33:02', - 'note' => 'any new text' - } - }; + $db->set_new(2, $expect->{2}->{note}, $expect->{2}->{date}); -my %all = $db->get_all(); -is_deeply($expect, \%all, "Get all notes hash"); + my $next = $db->get_nextnum(); + is_deeply($next, 3, "$name: Get next note id"); + + my %all = $db->get_all(); + is_deeply($expect, \%all, "$name: Get all notes hash") or diag(Dumper(\%all)); +} + +sub wrdb3 { + my ($db, $name) = @_; + is_deeply($db->{use_cache}, undef, "$name: Chache disabled"); + + my $ex3 = $expect; + my $n = $db->get_nextnum; + $db->set_new($n, $ex3->{1}->{note}, $ex3->{1}->{date}); + $ex3->{$n} = delete $ex3->{1}; + + my ($note, $date) = $db->get_single($n); + like($note, qr/any new text/, "$name: Retrieve newly written entry content"); + like($date, qr/^\d\d/, "$name: Retrieve newly written entry date"); + + $n = $db->get_nextnum; + $db->set_new($n, $ex3->{2}->{note}, $ex3->{2}->{date}); + $ex3->{$n} = delete $ex3->{2}; + + my %all = $db->get_all(); + # hack %all to that it passes the next test + foreach my $n (keys %all) { + chomp $all{$n}->{note}; + } + + is_deeply($ex3, \%all, "$name: Get all notes hash") or diag(Dumper(\%all)); +}