Test::Database and Test::DSN

2014-04-02 Thread Philippe Bruhat (BooK)
Hi,

During the last Perl QA Hackathon, I've been talking with TIMB, REHSACK,
HMBRAND and RIBASUSHI about Test::Database.

Going back to the needs that people have, it seems to me that:
- the main need is to obtain DSN to databases that match a certain
  set of prerequisites
- the prerequisites can vary wildly, and much more than what
  Test::Database currently supports (the most obvious example being any
  type of database that is behind a DBD::ODBC DSN)
- with enough support from CPAN Testers, there is no real need to
  *automatically* create databases (unless explicitely asked to, most
  likely for the file-based databases)

Test::Database suffers from bad naming: Test::Database::Handle,
Test::Database::Driver, driver_dsn are overloading names already used
with slightly different meanings in DBI. These can probably be fixed,
as the main interface for Test::Database is its handle / handles method.

It is also used by a number of modules on CPAN, so we have to be careful
with backwards compatibility.

Here are some of my conclusions:
- Test::Database should only return workspaces / databases that have
  already been configured, and assume that the necessary persmissions for
  testing are granted (create table, drop table, etc)
- Test::Database must support a much larger set of configuration files,
  located in various places: system (/etc), global ($HOME), local (cwd).
  That last bit would allow some projects to provide their own config file
  (as RIBASUSHI wants to do with DBIx::Class)
- the configuration files would support a much more fine-grained
  description for each DSN, and the characteristics would be described,
  and not discovered (well, apart from the DBD version, which is probably
  the only runtime attrbute). For example, the details of a database
  engine to which one connect through an ODBC DSN probably can't easily
  be discovered. These DSN would be Test::DSN objects, which have a larger
  set of attributes than the current Test::Database::Handle objects,
  but could share the same basic methods (dns, connection_info, etc)

With this in mind, Test::DSN would replace the legacy
Test::Database::Handle, and provide the dsn itself (pointing to a database
where the test script can create and drop its tables), the connection
information, and a set of attributes describing the workspace. Test::Database
would read its config files to get the list of available Test::DSN objects
and their attributes, and provide a method to request them based on their
attributes (e.g. give me a dsn for MySQL version 5.6 minimum, with such and
such options configured).

Backwards compatibility is assured by using a new method to return the
new Test::DSN objects. Over time, the old methods will be limited in
scope, until they are faded out (first by doing nothing, and later being
dropped entirely).

There are other issues that come to mind, like how to deal with parallel
testing, or even multiple different test suites using the same database
dsn at the same time. Maybe Test::Database could provide some sort of
optional locking mechanism, but I've have a hard time coming up with a
good one. Modules like DBIT already take that into account, by creating
tables with names explicitely designed to avoid clashes.

If some locking is provided, I think it probably must be at the table
level, i.e. a script will declare that it wants exclusive access to tables
X, Y, Z when requesting a dsn. The function will block (there's probably
a need for a timeout, to avoid having test scripts hanging forever)
until it can return a dsn with exclusive access to those tables. If
no tables are declared, Test::Database will assume that the script is
taking care of the issue.

Another option is that Test::Database could provide a function that
returns a unique prefix for a given script, so that the test script
can use that when creating the tables. That would provide isolated
namespaces, and then we don't have to deal with locking directly.
With that namespace, we can even let Test::Database do things like
drop all tables in that namespace.

As for file-based DBD, they should be handled specifically:
- Test::Database can already create a unique Test::DSN for any of those
- Test::Database would only have drivers for file-based DSN, as these
  would be the only case where database creation needs to be delegated
  to Test::Database.
- if a test wants specific options, they could be part of the request,
  and influence the database creation proceass

I've said above that all DSN should come from configuration files, but
there are still a few that can be discovered automatically, like the
test databases for MySQL and Pg. Should these be automatically included
in the list of DSN if they are found?

-- 
 Philippe Bruhat (BooK)

 None suffer so much in a war as those who strive to end it.
(Moral from Groo The Wanderer #51 (Epic))


Re: Test::Database and Test::DSN

2014-04-02 Thread Philippe Bruhat (BooK)
On Wed, Apr 02, 2014 at 09:23:13AM +0200, Philippe Bruhat (BooK) wrote:
 
 It is also used by a number of modules on CPAN, so we have to be careful
 with backwards compatibility.
 

According to MetaCPAN, the current authors and distributions that depend
on Test::Database are:
- BARBIE
CPAN-Testers-Data-Generator
CPAN-Testers-Common-DBUtils
Labyrinth
CPAN-Testers-Data-Uploads
CPAN-Testers-Data-Addresses
CPAN-Testers-WWW-Reports-Mailer
CPAN-Testers-Data-Release
- HORNBURG
Dancer-Plugin-Interchange6
Dancer-Plugin-Nitesi
Nitesi-DBI
- MLAWREN
DBIx-ThinSQL
SQL-DB
- CFAERBER
DateTime-Format-DBI
- JAME
FTN-Database (does not actually use Test::Database)
- ADAMK
Xtract
- SILASMONK
CGI-Application-Plugin-PageLookup
(in CPAN ratings, the author says Please don't use this module. It
will be deleted eventually.)

I think it should be fairly easy to obtain some collaboration from the first
three authors at least.

Looking at some of the existing test suites using Test::Database, I've
noted the following:
- it should be possible to make negative queries (e.g. any DSN, but
  not for SQLite2 or DBM)
- I've seen the following used in several places:
  $handle-{driver}-drop_database($handle-name);

-- 
 Philippe Bruhat (BooK)

 You can always buy another house but you cannot put a price on a home.
(Moral from Groo The Wanderer #63 (Epic))


Re: Test::Database and Test::DSN

2014-04-02 Thread Darren Duncan
For actual or intended Test::Database use cases that you know about, which of 
these situations are represented:


1. The test requires the actual DBMS used in production, it is designed with 
only a single specific DBMS in mind, no substitutions allowed.


2. Like #1 except substitutions are allowed if the substitute is compatible for 
all the DBMS syntax/capabilities used.


3. The test will work with a variety of DBMS and works to least common 
denominator.

4. The test will work with a variety of DBMS and will do different things 
depending on which DBMS is in use as it recognizes their different syntax or 
capabilities.


5. Some other option?

Thanks in advance for the info.

-- Darren Duncan