Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 347401

Summary: Test failures when DB4O suite uses client/server DB4OStore
Product: [Modeling] EMF Reporter: Caspar D. <caspar_d>
Component: cdo.coreAssignee: Caspar D. <caspar_d>
Status: CLOSED DUPLICATE QA Contact:
Severity: normal    
Priority: P3 CC: saulius.tvarijonas, vroldanbet
Version: 4.0   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Patch
none
Test failures for optimizing==true
none
Patch none

Description Caspar D. CLA 2011-05-27 03:07:28 EDT
Currently the DB4ORepositoryConfig returns a MEMDB4OStore, and all tests
pass with that.

But if I change the config to instantiate a DB4OStore(path,port), a
considerable number of tests fail. So far I see 6 failures in 
AttributeTest (all IllegalStateEx: "Cannot modify a frozen list");
1 failure in UnsetTest (NPE); 7 failures in SessionTest (DatabaseFile
LockedException); 1 failure in ViewTest (again DBFileLockedEx).
Comment 1 Caspar D. CLA 2011-05-27 03:09:50 EDT
@Override
protected IStore createStore(String repoName)
{
  String path = "/tmp/cdodb.db4o";

  // Remove an existing database, unless this is a restart within a test
  //
  if (!isRestarting())
  {
    File f = new File(path);
    if (f.exists())
    {
      f.delete();
    }
  }

  return new DB4OStore(path, 50032);
}
Comment 2 Caspar D. CLA 2011-05-27 03:11:32 EDT
The above is a "patch" to be pasted into AllTestsDB4O.java, to 
instantiate a DB4OStore.

Note also this fixes an earlier oversight in this repo config:
it didn't take restarts into account. (I already fixed this in my
dev branch for the durable locks, see bug 347285.)
Comment 3 Caspar D. CLA 2011-05-27 03:31:39 EDT
Furthermore:

MultiValuedOfAttributeTest: 9 failures ("Cannot modify frozen list")
SetFeatureTest: 2 failures (NPE)
CommitInfoTest: 5 failures
ChunkingTest: 4 failures
ExternalReferenceTest: 2 failures
XATransactionTest: 5 failures
Comment 4 Caspar D. CLA 2011-05-27 04:38:46 EDT
Furthermore:

BackupTest: 8 failures
Bugzilla_258933_Test: 2 failures
Bugzilla_259869_Test: 1 failure
Bugzilla_329752_Test: 1 failure
Comment 5 Caspar D. CLA 2011-05-27 06:41:46 EDT
Hm, that earlier code snippet was a little mindfart.. of course
the path would at least have to be qualified with the repoName,
otherwise all tests using more than 1 repo are guaranteed to
encounter a problem. Running tests again.. pretty slow. Would
be nice if we could have optimizing=true for the db4o suite.
Comment 6 Caspar D. CLA 2011-05-27 06:56:59 EDT
And the port needs to be randomized:


@Override
protected IStore createStore(String repoName)
{
  String path = "/tmp/cdodb_" + repoName + ".db4o";

  // Remove an existing database, unless this is a
  // restart within a test
  //
  if (!isRestarting())
  {
    File f = new File(path);
    if (f.exists())
    {
      f.delete();
    }
  }

  int port = 1024 + random.nextInt(65536 - 1024);
  return new DB4OStore(path, port);
}
Comment 7 Caspar D. CLA 2011-05-31 01:25:44 EDT
More trouble: DB4OStore.doDeactivate is flawed. It calls openClient() after
calling tearDownObjectServer. Of course, this always fails, but the error
is snuffed, and so has gone unnoticed.
Comment 8 Caspar D. CLA 2011-05-31 01:26:56 EDT
Yet more trouble: it seems like the DB4O shuts itself down when it
encounters an internal error. This means the database gets closed
without the test framework knowing about it. And with optimizing==true
in the repoconfig, this means the next test encounters a closed 
database while it expects an open one.
Comment 9 Caspar D. CLA 2011-05-31 01:49:02 EDT
And there's a 2nd bug in doDeactivate: it stores an updated
instance of the ServerInfo class, which was originally obtained
from the db4o database. This is correct, but the mistake is
that it's stored using an com.db4o.ObjectContainer that is
newly opened during deactivation. As a result, the instance
is considered a new object by db4o. After deactivation, there
are 2 instances of ServerInfo in the database, which causes
an exception (ISE) in initServerInfo on the next startup.
Comment 10 Caspar D. CLA 2011-06-01 02:39:20 EDT
And then there's the problem that the DB4O store doesn't recognize
the explicit CDORevisionData.NIL object. It actually serializes
this object into the store :-)

Btw, I'm fixing all of the above in the dev branch that I opened for
bug 347285.
Comment 11 Caspar D. CLA 2011-06-01 03:06:06 EDT
Created attachment 197062 [details]
Patch

I intend to commit this to my dev branch, but with Eclipse.org's SVN server
broken for now, that's not possible. This fixes all db4o problems not related
to or caused by test optimization.

(Btw, this is a normal unified patch, not an Eclipse patch.)
Comment 12 Caspar D. CLA 2011-06-01 04:45:16 EDT
Created attachment 197065 [details]
Test failures for optimizing==true

Attaching the test failures that occur when the DB4ORepoConfig
is amended to have optimizing==true.
Comment 13 Caspar D. CLA 2011-06-02 06:49:41 EDT
The fact that isOptimizing==true causes failures obviously suggests that
there is a problem with re-using the DB4O database accross tests.

One thing that looks flawed to me, is that the DB4OStore doesn't seem
to have any logic for maintaining the lastObjectID across sessions, or
for determining it from the database content. So it looks like the
store starts issuing CDOID's from 1 every time it is activated.

Another thing I'm not sure is working correctly, is the storage of
the rootResourceID.
Comment 14 Caspar D. CLA 2011-06-02 07:09:24 EDT
Created attachment 197227 [details]
Patch
Comment 15 Caspar D. CLA 2011-06-02 07:10:50 EDT
(In reply to comment #14)
> Created attachment 197227 [details]
> Patch

That's another normal unified patch. It really needs to go into
the dev branch, but I still can't commit.

Don't commit to HEAD, there's some debug cruft in there.
Comment 16 Caspar D. CLA 2011-06-05 22:34:59 EDT
Committed revision 7926. (dev branch)
Comment 17 Caspar D. CLA 2011-06-07 23:49:31 EDT
Subsumed under bug 347285.

*** This bug has been marked as a duplicate of bug 347285 ***
Comment 18 Victor Roldan Betancort CLA 2011-06-17 10:00:09 EDT
Caspar, MemDB4OStore was mean to accelerate the test-suite. I originally used to use file-based DB4OStore, but while developing, executing the test-suite took just too much. Do you think its feasible to turn back to its usage by default? Im not sure to understand why there were failures in the MEMBased version and not in the file based version. Is it a DB4O problem, or problems in MEMDB4OStore implementation itself?
Comment 19 Caspar D. CLA 2011-06-21 04:00:34 EDT
(In reply to comment #18)

Victor,

At the risk of sounding a little daft, I don't quite remember. My 
goal was to fix all the failing tests, and also to rework things so 
that the DB4O test suite would be able to run with optimizing==true
(which means it doesn't tear down and then set up a new repo for every
test). I ran into various small bugs on several fronts (some of which
I've described earlier in this comment thread), some of which were to
do with the MEMDB4OStore, some more with the test config. At some point
all tests were passing with the MEMDB4OStore, but not with the regular
DB4OStore that I reintroduced, so from then on I made it my goal to make
everything pass with the latter, and never looked back to ask myself the
question of whether the failures were really due to DB4O-internal
differences between the file-based and memory-based implementations.

If you want to use the MEMDB4OStore again, I propose that we create a
separate config for that, and I recommend you run it with optimizing==true
as well. In the case of a memory-based store, the performance advantage
is of course not very interesting, but reusing a repo across tests can
actually reveal hidden problems. The incorrect storage/retrieval of the
ServerInfo object and the last_object_id (which I fixed) was one example
of that.
Comment 20 Victor Roldan Betancort CLA 2011-06-21 05:45:56 EDT
Caspar,

the sole purpose of MEMDB4OStore was to make the test-suite faster. When developing new functions (DB4OStore doesn't implement some CDO features, like branching), small changes may introduce many errors. Having a mem based implementation makes test-suite way faster to execute (actually, it takes 10 times less than file based, and quite close to H2), making practial the implement-test-fix-test procedure. It was only meant for test performance, not actual production.

I agree and I'll create a new bugzilla suggesting to create a separate config for MEMDB4OStore.

Thanks for the feedback, and congratulations for such a nice polishing of the DB4OStore implementation (which I actually just implemented in my spare time *for fun*). Are you guys using it in production? Is it providing good performance? I found some points to improve performance, which is still slightly worse than H2 DBStore.

Cheers!
Comment 21 Victor Roldan Betancort CLA 2011-06-21 05:56:05 EDT
There you go:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=349921
Comment 22 Eike Stepper CLA 2012-09-21 06:50:33 EDT
Closing.