[Rt-devel] [RFC][PATCH] DBIx-SB tests on other DBs

Ruslan U. Zakirov Ruslan.Zakirov at miet.ru
Fri May 20 16:13:01 EDT 2005


	Heya.
Here is new variant and I think it's ready for mainline.
New feature is cleanup_schema function in utils.pl that is needed for 
InterBase.pm tests and may be for other DBs.

Applies cleanly on trunk.

--
Best regards, Ruslan.

Ruslan U. Zakirov wrote:
>     Hello.
> Ok, here is what I've done to allow us run SB tests on mysql, postgres 
> and other DBs.
> 
> All comments are wellcome, but some are required.
> For now I didn't finish several things:
> 1) connect_* functions in utils.pl.
> This functions should connect handle to test DBs of your RDBMS. I wrote 
> only simple 'connect_mysql' that connects to DB 'test' with user 'root' 
> and empty password. I use it for local testings, but for CPAN we should 
> use configurable connect_* functions. Because configuration should be 
> asked or entered once across all tests, I think we should use ENV 
> variables or write config options into t/ dir. Please, suggest prefered 
> way and if you choose ENV then suggest generic naming.
> 
> 2) I wrote mysql schemas for current test suite, please, wrote schemas 
> for other DBs and send them back with report about test suite success or 
> fails.
> 
> Wait for your comments. Best regards, Ruslan.
> _______________________________________________
> Rt-devel mailing list
> Rt-devel at lists.bestpractical.com
> http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-devel
> 

-------------- next part --------------
==== Patch <mysql tests> level 3
Source: fac90757-c5f0-0310-a953-bfb799f65e4e:/DBIx-SearchBuilder/local:1632
Target: e417ac7c-1bcc-0310-8ffa-8f5827389a85:/DBIx-SearchBuilder/trunk:2885
        (svn://svn.bestpractical.com/DBIx-SearchBuilder)
Log:
 r233 at colinux:  cubic | 2005-02-25 15:44:38 +0000
 local copy
 r242 at colinux:  cubic | 2005-04-04 20:17:35 +0000
 M::I path update
 r1621 at colinux:  cubic | 2005-04-07 13:53:26 +0000
 nocap API test
 r1622 at colinux:  cubic | 2005-04-07 14:00:13 +0000
 add inc/ file for auto install feature
 r1623 at colinux:  cubic | 2005-04-07 16:11:05 +0000
 test suit changes:
   @AvailableDrivers array of the drivers that has DBD:: module installed
   connect_handle, connect_sqlite functions
 r1629 at colinux:  cubic | 2005-04-06 13:28:07 +0000
 cross DB test suite framework
 r1632 at colinux:  cubic | 2005-05-20 19:56:24 +0000
 cleanup_schema function integration

=== t/01records.t
==================================================================
--- t/01records.t  (revision 2885)
+++ t/01records.t  (patch mysql tests level 3)
@@ -6,105 +6,117 @@
 use File::Spec;
 use Test::More;
 BEGIN { require "t/utils.pl" }
+our (@AvailableDrivers);
 
-eval "use DBD::SQLite";
-if ($@) { 
-plan skip_all => "DBD::SQLite required for testing database interaction" 
-} else{
-plan tests => 30;
-}
+use constant TESTS_PER_DRIVER => 30;
 
-my $handle = get_handle('SQLite');
-$handle->Connect( Driver => 'SQLite', Database => File::Spec->catfile(File::Spec->tmpdir(), "sb-test.$$"));
-isa_ok($handle->dbh, 'DBI::db');
+my $total = scalar(@AvailableDrivers) * TESTS_PER_DRIVER;
+plan tests => $total;
 
-my $ret = $handle->SimpleQuery(TestApp::Address->schema);
-isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back");
+foreach my $d ( @AvailableDrivers ) {
+SKIP: {
+	unless( has_schema( 'TestApp::Address', $d ) ) {
+		skip "No schema for '$d' driver", TESTS_PER_DRIVER;
+	}
+	unless( should_test( $d ) ) {
+		skip "ENV is not defined for driver '$d'", TESTS_PER_DRIVER;
+	}
 
+	my $handle = get_handle( $d );
+	connect_handle( $handle );
+	isa_ok($handle->dbh, 'DBI::db');
 
-my $rec = TestApp::Address->new($handle);
-isa_ok($rec, 'DBIx::SearchBuilder::Record');
+	my $ret = init_schema( 'TestApp::Address', $handle );
+	isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back");
 
-# _Accessible testings
-is( $rec->_Accessible('id' => 'read'), 1, 'id is accessible for read' );
-is( $rec->_Accessible('id' => 'write'), undef, 'id is not accessible for write' );
-is( $rec->_Accessible('unexpected_field' => 'read'), undef, "field doesn't exist and can't be accessible for read" );
+	my $rec = TestApp::Address->new($handle);
+	isa_ok($rec, 'DBIx::SearchBuilder::Record');
 
-can_ok($rec,'Create');
+	# _Accessible testings
+	is( $rec->_Accessible('id' => 'read'), 1, 'id is accessible for read' );
+	is( $rec->_Accessible('id' => 'write'), undef, 'id is not accessible for write' );
+	is( $rec->_Accessible('unexpected_field' => 'read'), undef, "field doesn't exist and can't be accessible for read" );
 
-my ($id) = $rec->Create( Name => 'Jesse', Phone => '617 124 567');
-ok($id,"Created record ". $id);
-ok($rec->Load($id), "Loaded the record");
+	can_ok($rec,'Create');
 
+	my ($id) = $rec->Create( Name => 'Jesse', Phone => '617 124 567');
+	ok($id,"Created record ". $id);
+	ok($rec->Load($id), "Loaded the record");
 
-is($rec->id, $id, "The record has its id");
-is ($rec->Name, 'Jesse', "The record's name is Jesse");
 
-my ($val, $msg) = $rec->SetName('Obra');
-ok($val, $msg) ;
-is($rec->Name, 'Obra', "We did actually change the name");
+	is($rec->id, $id, "The record has its id");
+	is ($rec->Name, 'Jesse', "The record's name is Jesse");
 
-# Validate immutability of the field id
-($val, $msg) = $rec->Setid( $rec->id + 1 );
-ok(!$val, $msg);
-is($msg, 'Immutable field', 'id is immutable field');
-is($rec->id, $id, "The record still has its id");
+	my ($val, $msg) = $rec->SetName('Obra');
+	ok($val, $msg) ;
+	is($rec->Name, 'Obra', "We did actually change the name");
 
-# Check some non existant field
-ok( !eval{ $rec->SomeUnexpectedField }, "The record has no 'SomeUnexpectedField'");
-{
-	# test produce DBI warning
-	local $SIG{__WARN__} = sub {return};
-	is( $rec->_Value( 'SomeUnexpectedField' ), undef, "The record has no 'SomeUnexpectedField'");
-}
-($val, $msg) = $rec->SetSomeUnexpectedField( 'foo' );
-ok(!$val, $msg);
-is($msg, 'Nonexistant field?', "Field doesn't exist");
-($val, $msg) = $rec->_Set('SomeUnexpectedField', 'foo');
-ok(!$val, "$msg");
+	# Validate immutability of the field id
+	($val, $msg) = $rec->Setid( $rec->id + 1 );
+	ok(!$val, $msg);
+	is($msg, 'Immutable field', 'id is immutable field');
+	is($rec->id, $id, "The record still has its id");
 
+	# Check some non existant field
+	ok( !eval{ $rec->SomeUnexpectedField }, "The record has no 'SomeUnexpectedField'");
+	{
+		# test produce DBI warning
+		local $SIG{__WARN__} = sub {return};
+		is( $rec->_Value( 'SomeUnexpectedField' ), undef, "The record has no 'SomeUnexpectedField'");
+	}
+	($val, $msg) = $rec->SetSomeUnexpectedField( 'foo' );
+	ok(!$val, $msg);
+	is($msg, 'Nonexistant field?', "Field doesn't exist");
+	($val, $msg) = $rec->_Set('SomeUnexpectedField', 'foo');
+	ok(!$val, "$msg");
 
-# Validate truncation on update
 
-($val,$msg) = $rec->SetName('1234567890123456789012345678901234567890');
+	# Validate truncation on update
 
-ok($val, $msg) ;
+	($val,$msg) = $rec->SetName('1234567890123456789012345678901234567890');
 
-is($rec->Name, '12345678901234', "Truncated on update");
+	ok($val, $msg) ;
 
+	is($rec->Name, '12345678901234', "Truncated on update");
 
 
-# Test unicode truncation:
-my $univalue = "這是個測試";
 
-($val,$msg) = $rec->SetName($univalue.$univalue);
+	# Test unicode truncation:
+	my $univalue = "這是個測試";
 
-ok($val, $msg) ;
+	($val,$msg) = $rec->SetName($univalue.$univalue);
 
-is($rec->Name, '這是個測');
+	ok($val, $msg) ;
 
+	is($rec->Name, '這是個測');
 
 
-# make sure we do _not_ truncate things which should not be truncated
-($val,$msg) = $rec->SetEmployeeId('1234567890');
 
-ok($val, $msg) ;
+	# make sure we do _not_ truncate things which should not be truncated
+	($val,$msg) = $rec->SetEmployeeId('1234567890');
 
-is($rec->EmployeeId, '1234567890', "Did not truncate id on create");
+	ok($val, $msg) ;
 
-# make sure we do truncation on create
-my $newrec = TestApp::Address->new($handle);
-my $newid = $newrec->Create( Name => '1234567890123456789012345678901234567890',
-                             EmployeeId => '1234567890' );
+	is($rec->EmployeeId, '1234567890', "Did not truncate id on create");
 
-$newrec->Load($newid);
+	# make sure we do truncation on create
+	my $newrec = TestApp::Address->new($handle);
+	my $newid = $newrec->Create( Name => '1234567890123456789012345678901234567890',
+	                             EmployeeId => '1234567890' );
 
-ok ($newid, "Created a new record");
-is($newrec->Name, '12345678901234', "Truncated on create");
-is($newrec->EmployeeId, '1234567890', "Did not truncate id on create");
+	$newrec->Load($newid);
 
+	ok ($newid, "Created a new record");
+	is($newrec->Name, '12345678901234', "Truncated on create");
+	is($newrec->EmployeeId, '1234567890', "Did not truncate id on create");
 
+	cleanup_schema( 'TestApp::Address', $handle );
+}} # SKIP, foreach blocks
 
+1;
+
+
+
 package TestApp::Address;
 
 use base qw/DBIx::SearchBuilder::Record/;
@@ -133,9 +145,20 @@
 
 }
 
+sub schema_mysql {
+<<EOF;
+CREATE TEMPORARY TABLE Address (
+        id integer AUTO_INCREMENT,
+        Name varchar(36),
+        Phone varchar(18),
+        EmployeeId int(8),
+  	PRIMARY KEY (id))
+EOF
 
-sub schema {
+}
 
+sub schema_sqlite {
+
 <<EOF;
 CREATE TABLE Address (
         id  integer primary key,
=== t/01basics.t
==================================================================
--- t/01basics.t  (revision 2885)
+++ t/01basics.t  (patch mysql tests level 3)
@@ -4,17 +4,15 @@
 
 use Test::More;
 BEGIN { require "t/utils.pl" }
-our (@SupportedDrivers);
+our (@AvailableDrivers);
 
-my $total = scalar(@SupportedDrivers) * 4;
+use constant TESTS_PER_DRIVER => 4;
+
+my $total = scalar(@AvailableDrivers) * TESTS_PER_DRIVER;
 plan tests => $total;
 
-foreach my $d ( @SupportedDrivers ) {
+foreach my $d ( @AvailableDrivers ) {
 SKIP: {
-	eval "require DBD::$d";
-	if( $@ ) {
-		skip "DBD::$d is not installed", 4;
-	}
 	use_ok('DBIx::SearchBuilder::Handle::'. $d);
 	my $handle = get_handle( $d );
 	isa_ok($handle, 'DBIx::SearchBuilder::Handle');
=== t/utils.pl
==================================================================
--- t/utils.pl  (revision 2885)
+++ t/utils.pl  (patch mysql tests level 3)
@@ -2,6 +2,14 @@
 
 use strict;
 
+=head1 VARIABLES
+
+=head2 @SupportedDrivers
+
+Array of all supported DBD drivers.
+
+=cut
+
 our @SupportedDrivers = qw(
 	Informix
 	mysql
@@ -13,7 +21,24 @@
 	Sybase
 );
 
+=head2 @AvailableDrivers
 
+Array that lists only drivers from supported list
+that user has installed.
+
+=cut
+
+our @AvailableDrivers = grep { eval "require DBD::". $_ } @SupportedDrivers;
+
+=head1 FUNCTIONS
+
+=head2 get_handle
+
+Returns new DB specific handle. Takes one argument DB C<$type>.
+Other arguments uses to construct handle.
+
+=cut
+
 sub get_handle
 {
 	my $type = shift;
@@ -21,11 +46,126 @@
 	eval "require $class";
 	die $@ if $@;
 	my $handle;
-	{
-#		no strict 'refs';
-		$handle = $class->new( @_ );
-	}
+	$handle = $class->new( @_ );
 	return $handle;
 }
 
+=head2 handle_to_driver
+
+Returns driver name which gets from C<$handle> object argument.
+
+=cut
+
+sub handle_to_driver
+{
+	my $driver = ref($_[0]);
+	$driver =~ s/^.*:://;
+	return $driver;
+}
+
+=head2 connect_handle
+
+Connects C<$handle> object to DB.
+
+=cut
+
+sub connect_handle
+{
+	my $call = "connect_". lc handle_to_driver( $_[0] );
+	return unless defined &$call;
+	goto &$call;
+}
+
+sub connect_sqlite
+{
+	my $handle = shift;
+	return $handle->Connect(
+		Driver => 'SQLite',
+		Database => File::Spec->catfile(File::Spec->tmpdir(), "sb-test.$$")
+	);
+}
+
+sub connect_mysql
+{
+	my $handle = shift;
+	return $handle->Connect(
+		Driver => 'mysql',
+		Database => $ENV{'SB_TEST_MYSQL'},
+		User => $ENV{'SB_TEST_MYSQL_USER'} || 'root',
+		Pass => $ENV{'SB_TEST_MYSQL_PASS'} || '',
+	);
+}
+
+=head2 should_test
+
+Checks environment for C<SB_TEST_*> variables.
+Returns true if specified DB back-end should be tested.
+Takes one argument C<$driver> name.
+
+=cut
+
+sub should_test
+{
+	my $driver = shift;
+	return 1 if lc $driver eq 'sqlite';
+	my $env = 'SB_TEST_'. uc $driver;
+	return $ENV{$env};
+}
+
+=head2 had_schema
+
+Returns true if C<$class> has schema for C<$driver>.
+
+=cut
+
+sub has_schema
+{
+	my ($class, $driver) = @_;
+	my $method = 'schema_'. lc $driver;
+	return UNIVERSAL::can( $class, $method );
+}
+
+=head2 init_schema
+
+Takes C<$class> and C<$handle> and inits schema by calling
+C<schema_$driver> method of the C<$class>.
+Returns last C<DBI::st> on success or last return value of the
+SimpleQuery method on error.
+
+=cut
+
+sub init_schema
+{
+	my ($class, $handle) = @_;
+	my $call = "schema_". lc handle_to_driver( $handle );
+	my $schema = $class->$call();
+	$schema = ref( $schema )? $schema : [$schema];
+	my $ret;
+	foreach my $query( @$schema ) {
+		$ret = $handle->SimpleQuery( $query );
+		return $ret unless UNIVERSAL::isa( $ret, 'DBI::st' );
+	}
+	return $ret;
+}
+
+=head2 cleanup_schema
+
+Takes C<$class> and C<$handle> and inits schema by calling
+C<cleanup_schema_$driver> method of the C<$class> if method exists.
+Always returns undef.
+
+=cut
+
+sub cleanup_schema
+{
+	my ($class, $handle) = @_;
+	my $call = "cleanup_schema_". lc handle_to_driver( $handle );
+	return unless UNIVERSAL::can( $class, $call );
+	my $schema = $class->$call();
+	$schema = ref( $schema )? $schema : [$schema];
+	foreach my $query( @$schema ) {
+		eval { $handle->SimpleQuery( $query ) };
+	}
+}
+
 1;
=== t/02records_object.t
==================================================================
--- t/02records_object.t  (revision 2885)
+++ t/02records_object.t  (patch mysql tests level 3)
@@ -4,44 +4,55 @@
 use strict;
 use warnings;
 use File::Spec;
+use Test::More;
 
 BEGIN { require "t/utils.pl" }
+our (@AvailableDrivers);
 
-use Test::More;
-eval "use DBD::SQLite";
-if ($@) { 
-plan skip_all => "DBD::SQLite required for testing database interaction" 
-} else{
-plan tests => 9;
-}
-my $handle = get_handle('SQLite');
-$handle->Connect( Driver => 'SQLite', Database => File::Spec->catfile(File::Spec->tmpdir(), "sb-test.$$"));
-isa_ok($handle->dbh, 'DBI::db');
+use constant TESTS_PER_DRIVER => 8;
 
-foreach( @{ TestApp->schema } ) {
-	my $ret = $handle->SimpleQuery($_);
+my $total = scalar(@AvailableDrivers) * TESTS_PER_DRIVER;
+plan tests => $total;
+
+foreach my $d ( @AvailableDrivers ) {
+SKIP: {
+	unless( has_schema( 'TestApp', $d ) ) {
+		skip "No schema for '$d' driver", TESTS_PER_DRIVER;
+	}
+	unless( should_test( $d ) ) {
+		skip "ENV is not defined for driver '$d'", TESTS_PER_DRIVER;
+	}
+
+	my $handle = get_handle( $d );
+	connect_handle( $handle );
+	isa_ok($handle->dbh, 'DBI::db');
+
+	my $ret = init_schema( 'TestApp', $handle );
 	isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back");
-}
 
+	my $emp = TestApp::Employee->new($handle);
+	my $e_id = $emp->Create( Name => 'RUZ' );
+	ok($e_id, "Got an ide for the new emplyee");
+	my $phone = TestApp::Phone->new($handle);
+	isa_ok( $phone, 'TestApp::Phone', "it's atestapp::phone");
+	my $p_id = $phone->Create( Employee => $e_id, Phone => '+7(903)264-03-51');
+	# XXX: test fails if next string is commented
+	is($p_id, 1, "Loaded record $p_id");
+	$phone->Load( $p_id );
 
-my $emp = TestApp::Employee->new($handle);
-my $e_id = $emp->Create( Name => 'RUZ' );
-ok($e_id, "Got an ide for the new emplyee");
-my $phone = TestApp::Phone->new($handle);
-isa_ok( $phone, 'TestApp::Phone', "it's atestapp::phone");
-my $p_id = $phone->Create( Employee => $e_id, Phone => '+7(903)264-03-51');
-# XXX: test fails if next string is commented
-is($p_id, 1, "Loaded record $p_id");
-$phone->Load( $p_id );
+	my $obj = $phone->EmployeeObj($handle);
+	ok($obj, "Employee #$e_id has phone #$p_id");
+	is($obj->id, $e_id);
+	is($obj->Name, 'RUZ');
 
-my $obj = $phone->EmployeeObj($handle);
-ok($obj, "Employee #$e_id has phone #$p_id");
-is($obj->id, $e_id);
-is($obj->Name, 'RUZ');
+	cleanup_schema( 'TestApp', $handle );
+}} # SKIP, foreach blocks
 
+1;
 
+
 package TestApp;
-sub schema {
+sub schema_sqlite {
 [
 q{
 CREATE TABLE Employees (
@@ -55,7 +66,21 @@
 	Phone varchar(18)
 ) }
 ]
+}
 
+sub schema_mysql {
+[ q{
+CREATE TEMPORARY TABLE Employees (
+	id integer AUTO_INCREMENT primary key,
+	Name varchar(36)
+)
+}, q{
+CREATE TEMPORARY TABLE Phones (
+	id integer AUTO_INCREMENT primary key,
+	Employee integer NOT NULL,
+	Phone varchar(18)
+)
+} ]
 }
 
 package TestApp::Employee;
=== inc/Module/Install.pm
==================================================================
--- inc/Module/Install.pm  (revision 2885)
+++ inc/Module/Install.pm  (patch mysql tests level 3)
@@ -1,4 +1,4 @@
-#line 1 "inc/Module/Install.pm - /usr/local/share/perl/5.8.4/Module/Install.pm"
+#line 1 "inc/Module/Install.pm - /usr/lib/perl5/site_perl/5.8.5/Module/Install.pm"
 package Module::Install;
 $VERSION = '0.36';
 
=== inc/Module/Install/Base.pm
==================================================================
--- inc/Module/Install/Base.pm  (revision 2885)
+++ inc/Module/Install/Base.pm  (patch mysql tests level 3)
@@ -1,4 +1,4 @@
-#line 1 "inc/Module/Install/Base.pm - /usr/local/share/perl/5.8.4/Module/Install/Base.pm"
+#line 1 "inc/Module/Install/Base.pm - /usr/lib/perl5/site_perl/5.8.5/Module/Install/Base.pm"
 package Module::Install::Base;
 
 #line 28
=== inc/Module/Install/Makefile.pm
==================================================================
--- inc/Module/Install/Makefile.pm  (revision 2885)
+++ inc/Module/Install/Makefile.pm  (patch mysql tests level 3)
@@ -1,4 +1,4 @@
-#line 1 "inc/Module/Install/Makefile.pm - /usr/local/share/perl/5.8.4/Module/Install/Makefile.pm"
+#line 1 "inc/Module/Install/Makefile.pm - /usr/lib/perl5/site_perl/5.8.5/Module/Install/Makefile.pm"
 package Module::Install::Makefile;
 use Module::Install::Base; @ISA = qw(Module::Install::Base);
 
=== inc/Module/Install/AutoInstall.pm
==================================================================
--- inc/Module/Install/AutoInstall.pm  (revision 2885)
+++ inc/Module/Install/AutoInstall.pm  (patch mysql tests level 3)
@@ -1,4 +1,4 @@
-#line 1 "inc/Module/Install/AutoInstall.pm - /usr/local/share/perl/5.8.4/Module/Install/AutoInstall.pm"
+#line 1 "inc/Module/Install/AutoInstall.pm - /usr/lib/perl5/site_perl/5.8.5/Module/Install/AutoInstall.pm"
 package Module::Install::AutoInstall;
 use Module::Install::Base; @ISA = qw(Module::Install::Base);
 
=== inc/Module/Install/Metadata.pm
==================================================================
--- inc/Module/Install/Metadata.pm  (revision 2885)
+++ inc/Module/Install/Metadata.pm  (patch mysql tests level 3)
@@ -1,4 +1,4 @@
-#line 1 "inc/Module/Install/Metadata.pm - /usr/local/share/perl/5.8.4/Module/Install/Metadata.pm"
+#line 1 "inc/Module/Install/Metadata.pm - /usr/lib/perl5/site_perl/5.8.5/Module/Install/Metadata.pm"
 package Module::Install::Metadata;
 use Module::Install::Base; @ISA = qw(Module::Install::Base);
 
=== SearchBuilder/Handle.pm
==================================================================
--- SearchBuilder/Handle.pm  (revision 2885)
+++ SearchBuilder/Handle.pm  (patch mysql tests level 3)
@@ -85,7 +85,7 @@
            DisconnectHandleOnDestroy => undef,
 	       @_);
 
-    my $dsn = $self->DSN;
+    my $dsn = $self->DSN || '';
 
     # Setting this actually breaks old RT versions in subtle ways. So we need to explicitly call it
 

==== BEGIN SVK PATCH BLOCK ====
Version: svk 1.0_01 (linux)

eJyVWPt3E0eW1jKyjUUgkEBgAhkqjvwifvT7IUCxsR6W37awAycBpbq72lIsS0ZqGRzkzKluPf22
gUw2Q+ac/WGzf8H8eXvO3paMgzPGzPrItqS69dW9t+p+9d2O5O7fHmKLwSBT9LNMMb4wHgjMYEtP
drJC0S8ViZGysjm/WEyTVZL288V0dtEvFDN4mcBoPlvI6e4bC+cWieW+SelLxAoGWYBTmnDhBsQb
2Aaqhq1sJu9XG/AJK0eInyuy0hArF4d495Xws2oxT2CsAZzIkdVUPpXNwNKsxHNg4WeLLABkV0gm
kctmrcYIJw9x7lymqKezeZJw4YeE4pDomnN+CKlhb6RyRAef1uBbqwF0OLlhJ59gxxdTGf0PluCx
eBIkX4wTnNOT9wqptEFyb89qBCYeOve2FywANlfn3wRlptLEBbMGGRYMszkjP2A1wnjbWeG4Odcw
13A+pZ9kLR63ZsC6YKXS+YGV9L/YSsdsOdeW4Q4dSWS178H34yu8MzgONgUwG6N4ZSW9lrDIM8sg
aQs3Aua5ooo1kZclgTdlTdOwQGSZk3iR4QhnqFg1/TIjwGma8nh+9f9Xp5OiY56MZ9O7OdJqD1Dv
q4L3itO6dW3vLM20vFwqe3/my/GcPUsv0w+pHqHsRsvPH5Vm86+8tWe01fnGufi3sB2y22nYRraX
Xi2d/ftfvVSttNiDdpzO22N2X+vBKvXSu3TOnnfOVm6U26gUsX8I29YDx2Nfo2the77UaneNlc61
0fVQ6WqHczbs/NDqDJQe22q81OcJO+lo6aG/pIyXL/pLJr1a9n2wfSdY7vuuMiNU2h9UZjzfVe7T
a1Uh5PzgGapOU1T7MFwf6anx3u07vbXHVK23RWp/9dfD8O35+vLYxiV+40+0Z0OifRuPQ/WRC5vn
wxuXuM2biY1LVzazFG154VvP7FY3DdmPbmw9797+xJPYvhNyrkg7nz3aivbvZBZ2Df8uM74VPbf7
eGLzySe7VnTX8IT2Ls5tdsxt8n17q/T6fgdEcnN/+NH+11f3i8ZBx8cHIvVEDkYf7H99/UXno4OO
uy++ib/87MrLW2DY+3Jk9Kc/e8Ze5umdV3fptVdrtPOnS+CY8lNg8ucrP74SqslSshyyO8GrlbB9
pu4pjfxN8f29WLv4ur124/XVs6+FHc/M66j3l6Fy6B9z1XO/fjL+jy8d7y+XPPSz121AMahnaHgV
wznVs5n74fj9eGImPJcIzcUWwnNW1sJpHadxDt26fdvnM7M5gvWkgXoQ6kXPffHx2EwA/rcXMmmS
z/ckelB3d19vezvqmMp2+41uZHT0ta8nesJTCwYxUxlf+21fu57KpKz2t3/0NMGZwsr6OvoC9Wnp
rL6U9/nYxPJa/kkaPQ9PzkzPDc89HJ6/P52ITY3MhSfDU/fbZ+Zik+Phh6gnZYAZMNFb3NQswebx
x4oiY1ETRA3rskl02VCwgDnMKjKBky+cWkCCi8BibKiyKWqKLBkso2kyVkXMy4bJMjrLKn6FbdZP
yeOYnZ97Fjz1cwnvZdtrX33hpTfp1cXZBXt29Rb9eGbhAp300K/t3kbOsZaGms9Y6I+JF9CtEwNq
usMqggLVq2syI4uShImk6oKimTwmhqqZpwYkugiczuicTnhGY3WT1ySBlTVsmIImqYKm8ApQo3pI
Cfa3P3vLhdLK55696E36kX/vbHellal6Ht8c5evTod3RxfL4wxBdo2FqHUxlZ+i3Gxfog62P/GN/
qY0x5+gZu8WOHrTS1kqIrm+EnKDdQj+uxZxv4cT6d0adsdEVD73w41/szo/tSJQHw1IkOeawkeRm
yOmK2j67zT7j2k+Wrs+Wv2+j56MV76bX/ipWebw5Xp6MJCfKjytjTi+NVLtpvHKzDIbT1S4wpKEF
Z7TaVRp1YmPlFTtcSU+Ux/fC1WfVWG2ITlUfOd5lMGu3u87S6xfsiB2tSqXWwXLr93ao/pnjtUL1
LmCw2M5E/d4vs7X51tEfa8sto7N19lWozoH/XQsbxl64ztIW2ruw2VqKbqJQnY3Un0f5aqi+shd2
cGV0Y7kaotiOOVzJS1ejzr0wrkc3F0tgELLFuBOHZT+m4YoP/J7YTM5UHkzX1oEeV+1Y5VEpUjO9
NvLSi46X9gFWKbZ9Z7x+JrSRDG1/TafKj2uQq9GtPruVdgHj9kZ2rkW32ka3nkxXAnR052orpMEd
Gq1+VIluz1YABUxC2+bY9u2x+pndNtpJY7sfTG5+U4rtXI048bEdxpmo3AzteUK7emznjhOqrlWi
u9diW0+iuxcqY7uFsa0OJ7S1vBeqiXZk71GbHSlH90a2Ynt3qm4Iu/rMzhJs4+Tuf4xW12Dmw1p7
m90FOwZRRHeCPrs/vL8EAT+JHXwRqiRjB5/b8OtED4I0enADEn6zBpY0tH/DiR1MQhHBcge9o/Xz
4/tXaPTFmfDBp7G6N/TierTGje9KpfCLGGzAQGgvSS/awfBBbrx6ozIU2V2cenkZ7/Fu0ncv2CH6
Qy2676lOVRemXl5Z2o9Nv8TG/vOp2pcPd6VwdW0ofnBdO3jWQh/QxAsEh3ao1V64myTYYNHC8Fxs
+N5EOM75fMO5HF5DWRPhdBrlUeheCBkDPt9dvWAdlbSVxBZKp/JWHmUz6TVk5rLLvkKe5FAS51Eq
kwdWTRMD3UWLObKCnrsogUDHAPIn0Hpkfmrkfmx6yjeXRxnyFMZQfoXoKTOlowF0Hy8RgkC3FZZJ
xhq5ExzwTVtJksvnkZVFwCV5K1fQQdplE8jVkehpMqUnwQ41VcVdlCNmjz/xDfPoR5QffDxwKxAY
HIR5GaKP5AEidE+/izrAl3QParI6ajA3uNsF3L2YtbLrQLf9wR4f0PzdoEv42MKRVByc7A/q2HKp
qsdaXgGV0tPbhzryWr9F8taA39/R62vv9cNd8Lw7fi/hcl5i8mF8dqJ7fT4xHw/Pda+jYhF1u4pz
ZmY4Hs8ns4W0kfD5RpIErgREMqupXDYDtxAauXMriFZxLgVKLFcgCLh9qZ9kDKQRGAuyaZ08Qd0w
oXsAFdaNRF5PkmUMI/mevl5I/FBiGbYpa8xPuXQbH54IBHSc6elzryacMbQ12KZF38gd2GhIbxrn
Q/digUDegjxmUL6gg1JbxekC8cVTyytpMlsgubUMIrlcFoL+KoC+eQR5bt6W6EkPGkLPc8TqSeVx
T19387IjzwZ8w+mneA0yXMhAjp+j9RM5v8HYBqcRQ5d11WAxwxqGyCicgmXMM5gTRMU4lfMlF0HE
gqILKiGmyBGZE4DtNQPuD04XFVmTNb+gKk3K33/4KmArtP8rz8Xv0FcgBJdb7X7qdTq9V/7Tu32L
tlW/LXs3vy7H86ACr4AKNEAF+pyulk2pNGu1OJGyF3jXW0MgB4O0fS/VkIOtTgRY7VrpbO2plwZA
Dg68kYNVLw2CFpxwvNXL9TYqR+wnYXvpgf201Rm7TIthewLUYOdY6UwbLX7gLH/qfHjOGS/Nu1Lw
C0/IWYuUprtL4Uh5orP0hPaXP2lxxrvK0bPOilC2IpVZT7TSTwcqFu2sdoAkjMKwv6qHK1/cqp0L
14RLNXWsPv5hLV5LlBKHUmoRpFSldXv2Rk0D0u73ULn217atz6IbC+XQhv5Bfap2s/7BDlO/Nb0V
vFJPPNoigxtnnPDWnz3VmxuBP4gqqPYTbnjlmLZyFVVDTB0JKVdGHVdRh9XgaqlM1mpW5TE1dYKK
SkCpNlTUyRrKt45OPHKNA8NJCsdLPBYFAodNkjWVKALLsUQnjM7LavPIgbVyUqPGuE3d4GTWKDQQ
5fc2Mu5QE0893hyxbyENxprkObCy3Fj4WMPInOSHcsLst6e+0x/l1JJS3QyZpiyJsszwqsRyjMGK
usKzUJMCx7Eqx4JYe9NXTf06e97X7bFb2Go7Rz2/fnQnpYmD+ZRFEuKJO3CIb3Iip+gcwxnQwzEE
M5KpiaZpaLKhmvxhX+sqwuMpk04IevAezhM3b41MHUscd2w2z5w0exIuHnf4ZITjjTXPn4QwXLCy
b23fv4II/44bxMIG3Dd/RHjHNromp+xjI3OQaF1kWVXjBIkRJBGIkTElQeIYiRiKorOieLSRlfHK
1HlfH2ykVG2XqafiGz51I98soGBGFLAiiCyRNIkXBAyFpEI/oeiMqXGnnbXG/gCELLHEEGRVZmXZ
lEG3cyDaVbj3sKxqhq78ftiu/vrpeR8DPgaq7bep5/Vc+H0+NhZgOGxwsqYxLIcFVdNZSIEK7QTL
E4ERuNPaisYJcA+sqsOdwmOGZ0yeg7OrYUxMVuQlQ1YUER/5uPun3dbzPh58vFttD1LPzu3R9/nY
WEDhBCwyHIs5DmNRhYpjTVHRNCKZRDDwe/J42MxxDFEYDA6ZusHxrGoyDOy4LKqcZsjkyMff5n6b
fzuPv51/bx4bC6i6brAaFmSOgJcq3NcGZFBQBZk1MKcdPrBpPJM7XrV/eLY1OApC5KjgxPefdPH0
6BukLunQu2qizhFBhiSygsoQmVUk1oRPHG+6ZdeInv7zMv3np5c8nm3i8dL/Ztv/94yH/k/P9kmN
9htwrGGFx4amS9iUFYFonMkZjCGZhkl4VhEbHbkkyEWU43h+SM+mU5nCswBCekEDdVtEHMOI/QzX
z4mIFQOCEOAV9CUDPz4E1xlOg8BdWfPBbIF752wBXvA2wMoBXnwzezIQiKEVbCVRYQXogwAGJJM9
DURGLB8Q+QAnvQHJgAsraHgmhlw924Q41Q+AEAIMuMK/gcCGgVxWQ27ekCtkMbDim5YAmQRbhdyh
d+9OUBNaCrBsgDkK0fUJlGnKQnoSZxZJPuBDCA0dNSWhXGoV+gToHQ4bGNC1yDj8stGxuM1JoxNB
yw3S/b1TcZGaPYKVSDZOZd/RZxAXUBHILGR0KwVqp+m8eprzkptaTglAFIfO67ls3l389ygAMQf9
y9NsbqmByL8702I/xyBWDYhSgBOOEJti6FD4H7kHMVlkMYfd9z4/yxabz5jcZfPBIAdlyTUfrN9v
PBsPBOYzjQzhdKdUhBJ0z5CfL+bIKnwoFFKGnxOLg9AcPOs/XryN83r4RN3PS0UT6yqobblfF02m
n+FZph+rIt+vmZqsqqYkEoEEe7ni/3MZaH4yS2DDAb26yxABBAj0Cf2spuvNZRTTxPBHVDiZV1QM
dpL8b7kTeGdcATeq/wNyR+w2
==== END SVK PATCH BLOCK ====


More information about the Rt-devel mailing list