I’ve just merged the master branch locally on my machine, ran the tests again 
and I’m still having exactly 99 Tests failing!

Can you please run the tests on your machine and share the result?

 

Amro

 

Von: [email protected] 
[mailto:[email protected]] Im Auftrag von Oskar Berggren
Gesendet: Sonntag, 23. Februar 2014 18:38
An: [email protected]
Betreff: Re: [nhibernate-development] Re: Firebirds broken tests

 

I've merged PR #249. But on the build server the number of failing tests was 
already down to 80, and didn't change.

/Oskar

 

2014-01-21 11:40 GMT+01:00 Amro El-Fakharany <[email protected]>:

Sorry everyone but I was plain wrong!
The Firebird driver doesn't have any pooling issues related to our discussion 
here and there is no need to change any configurations!

The trouble is in the implementation of IncrementGenerator wich creates a brand 
new connection every time it needs to fetch the next value.
Examples of failing tests are EntityWithInverseManyToManyTest and 
EntityWithInverseOneToManyJoinTest. Both of those Fixtures needs to be run in 
one shot to see one of them fail!

I have opened a jira ticket https://nhibernate.jira.com/browse/NH-3591 and 
created a pull request https://github.com/nhibernate/nhibernate-core/pull/249

Now on my machine this lets the failing tests drops from 455 (after merging the 
last changes) down to 99.

Amro



On Friday, January 10, 2014 12:03:28 PM UTC+1, Amro El-Fakharany wrote:

Done as discussed so far: https://github.com/nhibernate/nhibernate-core/pull/246

I also need to make a small change to the firebird configuration template for 
the following reason (it is not included in the pull request yet):
When there are more than one connection to a database firebird will regect any 
Drop or Alter table statements from one connection if the table was/is used by 
any of other connections.
Now The Firebird driver has some issues with connection pooling in such it 
sometimes opens a brand new connection instead of returning one from the pool.
This results in a lot of tests failing to drop the schema after they're done. 
This in turn causes the following tests to fail because the fixture setup 
raises an exception complaining about tables being already created.
More than 200 tests are failing because of this!

We have basically two* options:
1) Turn pooling off. This will make the tests run very, very slow but should be 
relatively safe.
2) Force the driver to run under embedded mode. I don't know precisely why, but 
the pooling issues disappear in this mode and the tests are still running fast. 
The drawback ist that the driver may change this in furture releases.
Both of these options can be set in the driver configuration template and we're 
done.

- Which option would you guys choose? Personally I would go for the second one.
- Can I include it in the same pull request above?

*There is actually a third option I'm thinking about which is to contribute to 
the driver project and fix that annoying pooling issue but I'm not sure if I 
can do that and even if I can it won't happen soon.

Amro

On Monday, December 23, 2013 11:23:27 AM UTC+1, Amro El-Fakharany wrote:

Hi Everybody,
I noticed that there are some (actually a lot!) tests broken for Firebird and I 
decided to tackle each Problem one by one.

So far I have found three Issues wich are (roughly description):
1) Decimal data type: Firebird does'nt support precisions larger than 18 and 
the default of nh is 19. 
I extended the FirebirdDialect to override the "GetTypeName" method and swap 
larger Decimal precisions with 18.

2) Parameters Within a select clause: Firebird needs a typecast if a parameter 
is used within a select clause.
I extended the FirebirdClientDriver to override the AdjustCommand method and 
typecast the parameter.

3) Temporary Tables: Firebird supports temporary Tables, which must be created 
in an isolated transaction, and so I thought it is just a matter of extending 
the dialect and overriding the related properties and methods.
Running the tests afterwards I discovered that this was'nt the case.

After digging deeper in the code I think I now know what's going on and I think 
the issue is a "nasty" one and not necessarily related to Firebird.
This is going to be a rather long Description but please bear with me since I 
really need some guidance here!

I'll start with one failing test which is found in 
AbstractEntityWithOneToManyTests.OneToManyCollectionOptimisticLockingWithUpdate().
The relevant Part is at the end of the test:
            s = OpenSession();
            t = s.BeginTransaction(); <== keep this in mind.

            c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
            s.CreateQuery("delete from Party").ExecuteUpdate();

An Exception is thrown at s.CreateQuery().ExecuteUpdate().

Debuging and "Following the dots" you reach 
MultiTableDeleteExecutor.Execute(parameters, session) with:
            CoordinateSharedCacheCleanup(session);
            CreateTemporaryTableIfNecessary(persister, session);

the implementation of CreateTemporarayTableIfNecessary() in 
AbstractStatementExecutor is:
            IIsolatedWork work = new TmpIdTableCreationIsolatedWork(persister, 
log, session);
            if (ShouldIsolateTemporaryTableDDL())
            {
                if (Factory.Settings.IsDataDefinitionInTransactionSupported)
                {
                    Isolater.DoIsolatedWork(work, session);
                }
                else
                {
                    Isolater.DoNonTransactedWork(work, session);
                }
            }
            else
            {
                work.DoWork(session.ConnectionManager.GetConnection(), null);
                session.ConnectionManager.AfterStatement();
            }

The bold if Statement is absolutly useless! The Property 
IsDataDefinitionInTransactionSupported is never used (let alone set to true!) 
anywhere in the entire code base and hence it is always false.
I commented out the whole thing except Isolator.DoIsolatedWork(work, session) - 
because this is what firebird requires - just to see what will happen which was 
unfortunatly nothing. The test still fails with the same exception.

Digging further starting from Isolator.DoIsolatedWork(work, session) you reach 
AdoNetTransactionFactory.ExecuteWorkInIsolation(ISessionImplementor session, 
IIsolatedWork work, bool transacted) with the relevant implementaion part of (i 
removed the comments for brevity):
                if (session.Factory.Dialect is SQLiteDialect)
                    connection = session.Connection;
                else
                    connection = 
session.Factory.ConnectionProvider.GetConnection();

                if (transacted)
                {
                    trans = connection.BeginTransaction();
                }

                work.DoWork(connection, trans);

                if (transacted)
                {
                    trans.Commit();
                }
Notice how It's asking for a new connection and starting a new transaction 
(wich is precisly what it should do) if requested. It then passes both to 
work.DoWork. In our case here the "work" is 
TmpIdTableCreationIsolatedWork.DoWork(IDbConnection connection, IDbTransaction 
transaction) with the relevant implementation:
                    stmnt = session.ConnectionManager.CreateCommand();
                    stmnt.CommandText = persister.TemporaryIdTableDDL;
                    stmnt.ExecuteNonQuery();
                    
session.Factory.Settings.SqlStatementLogger.LogCommand(stmnt, FormatStyle.Ddl);

The code is not only ignoring the passed in connection and transaction but is 
asking for a command from the ConnectionManager which will return a command 
assigned to a different connection from that passed in!

Further more the ConnectionManager.CreateCommand() will assign the command the 
very first transaction created by the test and the whole thing blows up!
Here ist the implementation of ConnectionManager.CreateCommand():
            var result = GetConnection().CreateCommand();
            Transaction.Enlist(result);
            return result;

Now I think the solution is actually simple, namly refactor the 
TmpIdTableCreationIsolatedWork.DoWork to use the passed in parameters, but I 
need to make sure that other dialects will not be affected.
(After all there must be a reason why the original author(s) ignored the passed 
in parameters right?)

1) Does any dialect support DDL statements within the same transaction as the 
one which actually usese them (such as selects or inserts) at all?
2) If yes, will they be broken if we did the refactoring or do they also 
support DDL in separate transactions?
3) Can we remove the if 
(Factory.Settings.IsDataDefinitionInTransactionSupported) and instead just 
stick with Isolater.DoIsolatedWork(work, session);?

Sorry if the post was rather long and Merry Christmas to all of you.

-- 
 
--- 
You received this message because you are subscribed to the Google Groups 
"nhibernate-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected] 
<mailto:nhibernate-development%[email protected]> .
For more options, visit https://groups.google.com/groups/opt_out.

 

-- 
 
--- 
You received this message because you are subscribed to the Google Groups 
"nhibernate-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to  <mailto:[email protected]> 
[email protected].
For more options, visit  <https://groups.google.com/groups/opt_out> 
https://groups.google.com/groups/opt_out.

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"nhibernate-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to