Details

Description

Maven expects unit tests under .../src/test/java, and root-level project tests under tests/xxx/src/test/java (or equivalent, along with their own pom.xml at tests and tests/xxx). This is basically compatible with the ant build except in location detail. The proposal is to move stuff around to make the tests work with maven.

Activity

That sounds great.
For the end-to-end tests I would also suggest to make a maven project per test szenario (filesystem, sharepoint, ...).
The test code should be in the "src/test/java" directory.
When you are done, I could update the maven pom's.

Tobias Rübner
added a comment - 14/Jul/11 14:12 That sounds great.
For the end-to-end tests I would also suggest to make a maven project per test szenario (filesystem, sharepoint, ...).
The test code should be in the "src/test/java" directory.
When you are done, I could update the maven pom's.

I just ran into a potential issue. The framework tests are organized as follows:

the core test package consists of tests and a TestBase class

the agents test package consists of tests and a TestBase class that extends the core TestBase class

the pull-agent test package consists of tests and a TestBase class that extends the agents TestBase class

The question is, where should the TestBase classes live? Will maven do the right thing if these are all moved, to core/src/test/java, agents/src/test/java, and pull-agent/src/test/java, respectively? Or do we need specific mcf-core-test, mcf-agents-test, and mcf-pull-agent-test subprojects, for the test base classes? How is this usually handled in Maven?

Karl Wright
added a comment - 14/Jul/11 14:37 I just ran into a potential issue. The framework tests are organized as follows:
the core test package consists of tests and a TestBase class
the agents test package consists of tests and a TestBase class that extends the core TestBase class
the pull-agent test package consists of tests and a TestBase class that extends the agents TestBase class
The question is, where should the TestBase classes live? Will maven do the right thing if these are all moved, to core/src/test/java, agents/src/test/java, and pull-agent/src/test/java, respectively? Or do we need specific mcf-core-test, mcf-agents-test, and mcf-pull-agent-test subprojects, for the test base classes? How is this usually handled in Maven?

That is no problem for maven. You should leave the TestBase classes in their modules.
While building the module, I can add an additional instruction to include the test-classes to an xxx-test.jar.
On the module depending on those test-classes, I can include the test package to the test lifecycle.

Tobias Rübner
added a comment - 14/Jul/11 15:54 That is no problem for maven. You should leave the TestBase classes in their modules.
While building the module, I can add an additional instruction to include the test-classes to an xxx-test.jar.
On the module depending on those test-classes, I can include the test package to the test lifecycle.

I've created a branch, https://svn.apache.org/repos/asf/incubator/lcf/branches/CONNECTORS-223, where I've started the rearrangement. If you could have a look at the framework subproject in this branch to see if I have arranged things properly, that would be great. If that all looks OK, I'm planning to tackle the connectors next, then the end-to-end tests.

Karl Wright
added a comment - 14/Jul/11 16:34 I've created a branch, https://svn.apache.org/repos/asf/incubator/lcf/branches/CONNECTORS-223 , where I've started the rearrangement. If you could have a look at the framework subproject in this branch to see if I have arranged things properly, that would be great. If that all looks OK, I'm planning to tackle the connectors next, then the end-to-end tests.

Tobias Rübner
added a comment - 15/Jul/11 08:04 The structure looks good, but the tests need more dependencies.
Currently in maven all tests will fail!
I will create a patch for the maven poms, that includes the dependencies for the maven test lifecycle.

Tobias Rübner
added a comment - 15/Jul/11 08:58 Maven strongly depends on conventions.
By default, the Maven Surefire Plugin, which executes the tests, will automatically include all test classes with the following wildcard patterns:
"* /Test .java" - includes all of its subdirectories and all java filenames that start with "Test".
"**/*Test.java" - includes all of its subdirectories and all java filenames that end with "Test".
"**/*TestCase.java" - includes all of its subdirectories and all java filenames that end with "TestCase".
Your test class names do not match this convention.
Now we have 2 choices:
rename the test classes (e.g. mcf-agents Sanity -> SanityTest)
change the pattern to include the tests (* /Sanity .java)

Renaming the tests should not be hard. But what about the test base classes? Since they begin with "Test" they will be executed independently, although they do not have any actual tests in them. They do have expensive setup and teardown methods though. Thus they should probably also be renamed to something that won't execute on its own.

Karl Wright
added a comment - 15/Jul/11 09:56 Renaming the tests should not be hard. But what about the test base classes? Since they begin with "Test" they will be executed independently, although they do not have any actual tests in them. They do have expensive setup and teardown methods though. Thus they should probably also be renamed to something that won't execute on its own.

Tobias Rübner
added a comment - 15/Jul/11 10:07 No, I don't think you have to rename the TestBase classes. They do not have any @Test Annotations and so the code will only be executed when an explicit call was made.

Thank you. Now I run into some other problems.
Running the tests creates the databses files in the root directory of the module.
This depends on the test configuration defined in org.apache.manifoldcf.core.tests.BaseHSQLDB.
Maybe we could change that path to the test classpath

Tobias Rübner
added a comment - 18/Jul/11 09:44 Thank you. Now I run into some other problems.
Running the tests creates the databses files in the root directory of the module.
This depends on the test configuration defined in org.apache.manifoldcf.core.tests.BaseHSQLDB.
Maybe we could change that path to the test classpath
currentPath = new File( "." ).getCanonicalFile();
//currentPath = new File( this .getClass().getClassLoader().getResource( "." ).getPath()).getCanonicalFile();

The only requirement I have for creation of the test databases and configuration files is that it must be possible to have multiple workareas checked out with on tests running on each so that the tests do not collide with one another. Setting up paths that depend on resources may therefore not work.

Karl Wright
added a comment - 18/Jul/11 13:07 The only requirement I have for creation of the test databases and configuration files is that it must be possible to have multiple workareas checked out with on tests running on each so that the tests do not collide with one another. Setting up paths that depend on resources may therefore not work.
Other than than, I'm open to any patch you want to propose.

This patch includes the updated versions of the maven poms.
I also added minor changes to run the jetty-runner module by invoking "mvn exec:exec" on the command line (or eclipse).

There is still an issue with the end-to-end test, which requires a more detailed look into the code base. Invoking more than one test ends up in a database not found error. Your supplied "test_reset.patch" does not fix the issue. Maybe you can have a look on it.

Tobias Rübner
added a comment - 19/Jul/11 16:29 This patch includes the updated versions of the maven poms.
I also added minor changes to run the jetty-runner module by invoking "mvn exec:exec" on the command line (or eclipse).
There is still an issue with the end-to-end test, which requires a more detailed look into the code base. Invoking more than one test ends up in a database not found error. Your supplied "test_reset.patch" does not fix the issue. Maybe you can have a look on it.

The stuff under jetty-runner won't work fully, because the connectors.xml file needs to be modified based on what connectors you actually build. That in turn depends on what third party libraries you have. However, as a lowest-common-denominator solution, I'm willing to commit it.

Karl Wright
added a comment - 19/Jul/11 16:52 The stuff under jetty-runner won't work fully, because the connectors.xml file needs to be modified based on what connectors you actually build. That in turn depends on what third party libraries you have. However, as a lowest-common-denominator solution, I'm willing to commit it.

So let me be sure I understand the model. These tests are all executing in one JVM, correct? Can you attach a stack trace? I suspect that the issue has to do with setup/teardown of the database; I believe that each test's cleanup method removes the database, so if the sequence looks like this, for tests A, B, and C:

Karl Wright
added a comment - 19/Jul/11 17:10 Invoking more than one test ends up in a database not found error.
So let me be sure I understand the model. These tests are all executing in one JVM, correct? Can you attach a stack trace? I suspect that the issue has to do with setup/teardown of the database; I believe that each test's cleanup method removes the database, so if the sequence looks like this, for tests A, B, and C:
setup (A)
setup (B)
setup (C)
(A)
(B)
(C)
cleanup (C)
cleanup (B)
cleanup (A)
... then this could happen. But if the sequence is:
setup (A)
(A)
cleanup (A)
etc.
... then it is a complete mystery. I should be able to tell what sequence it is from a trace though.

I tried to simulate what maven does by changing the ant build's junit invocation from "fork="true"" to "fork="false"". When I do this without the patch, I get the same symptom as you see under Maven. With the patch, however, it works fine.

I think perhaps there is a problem with your testing procedure? I'm going to commit the patch changes now - could you synch up and try them again under maven?

Karl Wright
added a comment - 19/Jul/11 17:53 I tried to simulate what maven does by changing the ant build's junit invocation from "fork="true"" to "fork="false"". When I do this without the patch, I get the same symptom as you see under Maven. With the patch, however, it works fine.
I think perhaps there is a problem with your testing procedure? I'm going to commit the patch changes now - could you synch up and try them again under maven?
r1148443.

I looked in the documentation of the maven surefire plugin, which executes the tests.
Per default, maven also runs the tests in a separate process.
The execution procedure is sequential. Each tests runs to the whole lifecycle, before an other test starts.

I synced with the repository and run the tests again.
Now I get a timeout exception (I also tried a larger values).

Tobias Rübner
added a comment - 20/Jul/11 09:10 I looked in the documentation of the maven surefire plugin, which executes the tests.
Per default, maven also runs the tests in a separate process.
The execution procedure is sequential. Each tests runs to the whole lifecycle, before an other test starts.
I synced with the repository and run the tests again.
Now I get a timeout exception (I also tried a larger values).
Here is the error stack trace:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.apache.manifoldcf.filesystem_tests.ExpirationTest
Configuration file successfully read
2011-07-20 09:26:50.333:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2011-07-20 09:26:50.385:INFO::jetty-6.1.26
2011-07-20 09:26:50.436:INFO::Extract ../../framework/dist/web/war/mcf-crawler-ui.war to /tmp/Jetty_0_0_0_0_8346_mcf.crawler.ui.war__mcf.crawler.ui__b94r7w/webapp
2011-07-20 09:26:51.565:INFO::Extract ../../framework/dist/web/war/mcf-authority-service.war to /tmp/Jetty_0_0_0_0_8346_mcf.authority.service.war__mcf.authority.service__.3vgkks/webapp
2011-07-20 09:26:52.237:INFO::Extract ../../framework/dist/web/war/mcf-api-service.war to /tmp/Jetty_0_0_0_0_8346_mcf.api.service.war__mcf.api.service__.67gzyk/webapp
2011-07-20 09:26:52.953:INFO::Started SocketConnector@0.0.0.0:8346
2011-07-20 09:29:39.757:INFO::Stopped SocketConnector@0.0.0.0:8346
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 176.237 sec
Running org.apache.manifoldcf.filesystem_tests.APISanityTest
Configuration file successfully read
2011-07-20 09:29:43.742:INFO::jetty-6.1.26
2011-07-20 09:29:43.747:INFO::Extract ../../framework/dist/web/war/mcf-crawler-ui.war to /tmp/Jetty_0_0_0_0_8346_mcf.crawler.ui.war__mcf.crawler.ui__b94r7w/webapp
2011-07-20 09:29:44.798:INFO::Extract ../../framework/dist/web/war/mcf-authority-service.war to /tmp/Jetty_0_0_0_0_8346_mcf.authority.service.war__mcf.authority.service__.3vgkks/webapp
2011-07-20 09:29:45.422:INFO::Extract ../../framework/dist/web/war/mcf-api-service.war to /tmp/Jetty_0_0_0_0_8346_mcf.api.service.war__mcf.api.service__.67gzyk/webapp
2011-07-20 09:29:46.086:INFO::Started SocketConnector@0.0.0.0:8346
org.apache.manifoldcf.core.interfaces.ManifoldCFException: ManifoldCF did not terminate in the allotted time of 180000 milliseconds
at org.apache.manifoldcf.filesystem_tests.APISanityTest.waitJobInactive(APISanityTest.java:386)
at org.apache.manifoldcf.filesystem_tests.APISanityTest.sanityCheck(APISanityTest.java:225)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)

So does it start the process, run all the tests, and shut the process down? Or does it start a process for each test?

The execution procedure is sequential. Each tests runs to the whole lifecycle, before an other test starts.

Ok, that's a relief.

Other than trying to run these tests myself under maven, I can't think of any other way to proceed other than to ask you to figure out a way to get at the manifoldcf.log output for the test that fails. The timeout is happening because the crawl it sets up is never finishing. This could well be due to some static objects hanging around from one cycle to the next, but I'm never going to be able to tell without some work. I would have thought using ant with fork="false" would exercise the same path, but clearly Maven is doing something different from that.

Maybe the best way forward is to give me detailed instructions on how to set maven up in the way you have it, so I can debug at length.

Karl Wright
added a comment - 20/Jul/11 11:22 Per default, maven also runs the tests in a separate process.
So does it start the process, run all the tests, and shut the process down? Or does it start a process for each test?
The execution procedure is sequential. Each tests runs to the whole lifecycle, before an other test starts.
Ok, that's a relief.
Other than trying to run these tests myself under maven, I can't think of any other way to proceed other than to ask you to figure out a way to get at the manifoldcf.log output for the test that fails. The timeout is happening because the crawl it sets up is never finishing. This could well be due to some static objects hanging around from one cycle to the next, but I'm never going to be able to tell without some work. I would have thought using ant with fork="false" would exercise the same path, but clearly Maven is doing something different from that.
Maybe the best way forward is to give me detailed instructions on how to set maven up in the way you have it, so I can debug at length.

Karl Wright
added a comment - 20/Jul/11 13:33 I tried running mvn on the pom's currently checked in and I get this:
[ERROR] Failed to execute goal on project mcf-core: Could not resolve dependenci
es for project org.apache.manifoldcf:mcf-core:jar:0.3.0-SNAPSHOT: Could not find
artifact com.bitmechanic:jdbcpool:jar:0.99 in central ( http://repo1.maven.org/m
aven2) -> [Help 1]
[ERROR]
Do you see this error too?

We use a repository manager to proxy all dependency requests.
So it is possible to use many remote repositories at the same time (maven cental, sonatype, apache, ...).
This dependency was already manually deployed to our maven repository.

Tobias Rübner
added a comment - 20/Jul/11 14:01 If a dependency is not in your repository, you need to install in manually.
For installing jdbcpool into your local repository try
mvn install:install-file -Dfile=<path-to-file> -DgroupId=com.bitmechanic \
-DartifactId=jdbcpool -Dversion=0.99 -Dpackaging=jar
We use a repository manager to proxy all dependency requests.
So it is possible to use many remote repositories at the same time (maven cental, sonatype, apache, ...).
This dependency was already manually deployed to our maven repository.

Karl Wright
added a comment - 20/Jul/11 14:23 - edited With that import and a few other similar imports, I was able to get further. Now I am stopped by the following error, which looks like something new:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-dependency-plugin:
2.1:copy (copy-war) on project mcf-jettyrunner: Unable to find artifact. Could n
ot find artifact org.apache.manifoldcf:mcf-api-service:war:0.3.0-SNAPSHOT
[ERROR]
This is the result of "mvn test".
Thoughts? (I'm keeping all this information around in order to update the how-to-build-and-deploy page, FWIW.)

Tobias Rübner
added a comment - 20/Jul/11 14:50 I deleted mcf modules installed in my local repo and run into the same issue.
The jetty-runner is something like the final product and has a lot of dependencies from both the framework and the connectors. So, it must be build as the last module.
Maybe it should be separated from the framework to a single toplevel module (webapp?).

Tobias Rübner
added a comment - 20/Jul/11 14:53 For building the framework with maven, you just need to invoke
mvn clean install
on the root level of the project.
for running the jetty-runner app invoke
mvn exec:exec
in the jetty-runner module.

I'm not attempting to run anything but clearly the dependencies don't work consistently at this time, just for building.

The jetty-runner jar can be BUILT right where it is, but it cannot be RUN until the wars are all available. The directory where all this is assembled under ant is based on jetty-example, and is separate from jetty-runner for this very reason. Is there a way to make a similar separation in Maven?

java.io.FileNotFoundException: ../../framework/dist/web/war/mcf-authority-servic
e.war
at org.mortbay.jetty.webapp.WebAppContext.resolveWebApp(WebAppContext.ja
va:997)
at org.mortbay.jetty.webapp.WebAppContext.getWebInf(WebAppContext.java:8
32)
at org.mortbay.jetty.webapp.WebInfConfiguration.configureClassLoader(Web
InfConfiguration.java:62)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:489
)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:
50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection
.java:152)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:
50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:
130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:
50)
at org.apache.manifoldcf.filesystem_tests.Base.setUp(Base.java:308)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(Framework
Method.java:44)

... and others, indicating that the war files the tests are looking for are not in place. We need to figure out how to get that to work under Maven.

Karl Wright
added a comment - 26/Jul/11 14:33 The dependencies still seem incorrect. On a fresh checkout, with no ant-built artifacts, I get this when the tests are run:
2011-07-26 09:29:46.423:WARN::Web application not found ../../framework/dist/web
/war/mcf-authority-service.war
2011-07-26 09:29:46.423:WARN::Failed startup of context org.mortbay.jetty.webapp
.WebAppContext@15151aa
{/mcf-authority-service,../../framework/dist/web/war/mcf-a
uthority-service.war}
java.io.FileNotFoundException: ../../framework/dist/web/war/mcf-authority-servic
e.war
at org.mortbay.jetty.webapp.WebAppContext.resolveWebApp(WebAppContext.ja
va:997)
at org.mortbay.jetty.webapp.WebAppContext.getWebInf(WebAppContext.java:8
32)
at org.mortbay.jetty.webapp.WebInfConfiguration.configureClassLoader(Web
InfConfiguration.java:62)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:489
)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:
50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection
.java:152)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:
50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:
130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:
50)
at org.apache.manifoldcf.filesystem_tests.Base.setUp(Base.java:308)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(Framework
Method.java:44)
... and others, indicating that the war files the tests are looking for are not in place. We need to figure out how to get that to work under Maven.

I'm not sure, that packages not available at Maven central, or other repositories, should be used in pom's - in Tika project another approach is used - all needed jars are promoted to repository first, and only after it are used...

Alex Ott
added a comment - 20/Sep/11 19:19 I'm not sure, that packages not available at Maven central, or other repositories, should be used in pom's - in Tika project another approach is used - all needed jars are promoted to repository first, and only after it are used...

I'm not sure, that packages not available at Maven central, or other repositories, should be used in pom's - in Tika project another approach is used - all needed jars are promoted to repository first, and only after it are used...

If you want to create an example patch that shows how you think we should do it, I'd certainly have a look at it. But I think you might want to open a new JIRA ticket for this issue first.

Karl Wright
added a comment - 20/Sep/11 19:23 I'm not sure, that packages not available at Maven central, or other repositories, should be used in pom's - in Tika project another approach is used - all needed jars are promoted to repository first, and only after it are used...
If you want to create an example patch that shows how you think we should do it, I'd certainly have a look at it. But I think you might want to open a new JIRA ticket for this issue first.