Mock Maven Release - maven

We have a basic Maven parent POM for all our projects, which is tested with integration tests. However a big part of the customization is for the Maven release plug-in:
<plugin>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tagBase>https://my-url</tagBase>
<preparationGoals>clean verify org.acme:my-plugin:my-goal</preparationGoals>
<completionGoals>org.acme:my-other-plugin:other-goal<completionGoals>
<resume>false</resume>
</configuration>
</plugin>
I tried testing it via "release:prepare" and got Can't release project due to non released dependencies for the parent POM, which can't even be removed via -DallowTimestampedSnapshots=true.
I could test via "release:prepare -DdryRun=true", but that doesn't even test the preparation goals. So the only other way I could think of was to release the POM and then try to release an arbitrary project. So now I'm at version 1.0.14 and have reverted about 50 times, and I don't think that's the right way anymore.
Is there any way to mock a Maven release? Maybe tell him to tag to a local path and have him commit changes there? And he shouldn't deploy to our Nexus either, but I'm at the point where I'm not picky anymore.

I also had a need to do this, and like you I was not interested in actually doing SVN commits or deploys to a remote repo - in my mind that verification was part of other integration tests. I figured that the maven-release-plugin developers would also have a similar need, and indeed they did. They wrote mock SCM and wagon providers.
You can see the mocks used in the release plugin POM profile with id run-its. Note the config uses setupIncludes to be sure the mocks are built and installed in the local repo prior to running any actual tests.
The projects themselves need to use the mocks. Look at one of the integration tests to see how to define the scm element and add the dependency on the Wagon mock.
I used a log verification technique to verify that the appropriate executions were run during the tests.
Note: There are 3 mocks in the setup directory I linked. I found I only needed to use two of them, the ones with suffix "-dummy."

Modularize your process with profiles. Have a profile that triggers your 'prepare' actions, and a profile that triggers your 'perform' actions, and test those instead of or before running the release plugin. Configure the release plugin to do these things by activating the profile.

Related

Triggering child builds with Bamboo automatic dependencies

We've configured Bamboo to use automatic dependencies based on Maven POM files. This appears to be working, insofar as the Bamboo interface correctly shows which the Maven artifacts required by and created by each plan, which upstream plans provide the dependencies and which downstream plans depend on the artifacts.
However, it also appears to not work, insofar as building an upstream artifact doesn't trigger a downstream build. Is it necessary to manually create child plans to trigger downstream builds -- an error-prone duplication of the information in the POM files? If so, the automatic dependency management isn't much use and it's hard to understand what the feature is for.
You can try adding a step in your parent build, using a script task to trigger whatever child build you'd like.
This way, you're not bounded by the Bamboo dependency/trigger mechanism.
https://answers.atlassian.com/questions/65517/trigger-bamboo-plan-via-rest-call
Hope this helps.

how is junit related to maven sure fire plugin

I am fairly new to writing Maven pom files and JUnit tests. I have following in my pom and it is calling my test scripts as expected.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
</plugin>
It seems JUnit is more popular than sure fire plugin.
1) How is JUnit similar/different from maven sure fire plugin's default behavior (that is working for me from above plugin configuration). I can imagine JUnit having additional API/library; but what do they give me in addition to sure fire plugin
2)what is the easiest way to change my current tests that are running with sure fire plugin to JUnit. I came across following link which sort of implies that adding few lines to pom would be sufficient (?)
http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html
3)about previous bullet, what benefits would I have if I convert sure fire plugin tests to JUnit.
Hopefully, I am unambiguous (with my intro background to maven and JUnit)
maven-surefire-plugin is not itself a test framework: it's a Maven plugin that will run tests written with a test framework, either JUnit or TestNG.
I have following in my pom and it is calling my test scripts as expected.
If this is already running your tests then, as Surefire only knows about those two test frameworks, it means you're already using either JUnit or TestNG. You should be able to tell which from the classes you're importing to write your test classes.
(that is working for me from above plugin configuration)
Unless you have a particular requirement there's little reason to move away from the framework you're already using; it doesn't sound like you need to change anything.
As it says right here:
To get started with JUnit, you need to add the required version of JUnit to your project ... This is the only step that is required to get started - you can now create tests in your test source directory (eg, src/test/java).
Your question is confusing and suggests you haven't done any preliminary research yet. When you say "surefire tests" you may mean Pojo tests. If you know what a JUnit test is, it's pretty common sense thing to convert the Pojo tests to JUnit tests. Just put #Test before the Pojo test methods. You may also want to convert assert into the appropriate JUnit assert methods. In summary, just read a JUnit tutorial and the rest will be straight forward.

Can you import a profile into a maven pom.xml?

A RESTful web service project that I'm working on needs to be deployed to a very unique environment (that requires a lot of custom configuration) in addition to the typical deployment environment and the integration test environment.
I have created a build profile for the unique environment, but the definition is REALLY long, full of Ant Tasks, etc. and I'd like to put it in its own file and import it into the pom.xml just to keep things clean.
Is that possible?
The only option with the latest version of Maven at the moment (3.0.5) is to put your profile into a parent POM and inherit from the children.
One day when it is finished, POM Mixins would help but this feature is not yet finished.

How to run tests after deployment using Maven?

I'm trying to decide how to create a set of Acceptance Tests for a Java-EE web application.
Here's the setup: Maven is used to generate a WAR file and deploy it into Glassfish. On deployment, the MySQL database schema is automatically updated from model classes using Hibernate ("hbm2ddl=auto" option).
The Acceptance Tests need to test the deployed code by invoking various methods and checking the results are as expected(*). We wrote an additional set of packages to hook into an existing system so the Acceptance Tests should show how these can be integrated into the existing codebase.
(*) This may sound more like Unit/Integration Testing but they are Acceptance Tests in the sense that they should prove what we did works and they need to be run after deployment so there is a database in place.
From the above, my current thinking is to use JUnit to check expected values etc. The bit I'm struggling with is how to invoke these tests after deployment. "deploy" is Maven's last phase so not sure if this is possible?
Just because that phase is called deploy doesn't mean that you have to use it for deploying your application for testing. In fact, it should only be used for "deploying" the artifact to a maven repository. Read through the description of the Maven lifecycle phases and you'll see that there are some phases dedicated to your use case:
pre-integration-test
integration-test
post-integration-test
Have a look at the Cargo Maven plugin. It's made to deploy your WAR file to various containers for testing. They definitely show demos of use cases like the one you describe on your site. I would expect that ultimately, you can be using Cargo to deploy to your container ( from one of the earlier phases like pre-integration-test )
Note, Jenkins also has a plugin that is a wrapper around the Cargo plugin. So you might do what you need via Jenkins. Also note, you don't need to run your Jenkins build job as mvn clean deploy. You could have one build job that just runs the integration tests, and fires another "deploy" job only when it succeeds.
If you really need to do stuff after deployment, then you can either run failsafe, and by implication JUnit) as part of the deploy phase.
What I usually do, if to have seperate module. So, you can have one maven project, which contains your project and a separate 'deployment test' project. Then, building the parent project will build and run your war and then run the deployment tests. You can use junit as normal.
The second fits better into jenkins because you'll still have a single project as well.

What is the "maven way" for this ant development workflow?

How can maven be configured to support this type of workflow:
One Time Setup Invoke maven to do one time setup of a developers machine such as
Create a custom version of tomcat configured for this application
Create a local postgres database on the developers machine
load sample data into the database
run a junit test to configure other resources needed to run the application
Integration Tests Invoke maven to do run integration tests which should do the following
Create an integration test db
setup the db
Run command line integration tests against the db
Run a test version of tomcat with the application in it
Run command line junit tests that test the restful services exposed by the application
Release Build Invoke maven to do a release build of the system
do all the steps for an integration test
generate resources and configurations that are used on the server rather than production
deposit the end result in a git repo, commit, and push the changes to production
Test Build Invoke maven to do a test build of the system
do all the steps of a release build but configure the test release package with test server configuration
The main thing I am struggling with is that maven has a single build life-cycle with a well defined sequence of phases not sure if the workflow I want to build is a good fit for maven.
Can maven be configured for this type of workflow? If yes what are the key features of maven that allow for the different configurations of the four main ways that I want to use maven?
Update What I mean by this workflow, is that I want to be able to do something like
mvn setup
mvn integration
mvn prod-release
mvn test-release
I know the above example look like ant, I am long time ant user and total noob with maven.
You could setup Maven to do all that...
You probably would use (shock horror) profiles to achieve some of this...
BUT you don't want to do that
You are following ANT style thinking... if you like that style of thinking then use ANT or Gradle and be happy.
If you want to follow the Maven way, then you will solve the problem differently.
Coming from the Maven way, here are my thoughts:
Why do you need one-time setup? I usually have a run profile that dynamically provisions the correct application server and starts it with the App deployed, tearing down everything afterwards when I hit ^C. Typically this involves starting up a database server or two... hence things I have developed like the cassandra-maven-plugin. That way when I am working on a different project (which could be in 10 minutes time) I don't have to worry about background database servers eating up all my laptop's ram.
Integration tests are actually trivial when you have the above working... in fact I created the Maven Failsafe Plugin to make it easy to have plugin execution tied to the appropriate phases for integration testing. The Maven convention is to have a profile called run-its for running integration tests.
Release builds being different from test builds... ugh! You should be building environment agnostic artifacts. Have them pick up their configuration from the environment they are deployed in. That removes the worry that something has changed between the "test" build and the "production" build. If you really need to bundle the config, then I usually would resort to a separate module for taking the agnostic artifact and rebundling with the required configuration. That way it is easy to prove that you have a reproducible transformation and that nothing has changed inbetween what went to QA vs what is going to Ops.
I always make the release builds include the integration testing.
So typically I have my projects such that
$ mvn -Prun
will fire up the application starting from zero. Hitting ^C will tear everything back down again, and mvn clean or in extreme situations if I have a more complex setup process and need some caching mvn post-clean (think really clean) will remove anything that the run profile put into play
To run the integration tests I typically do
$ mvn -Prun-its verify
To make a release I typically do
$ mvn release:prepare release:perform -B
That is (in my view) the ideal way of handling the above steps you need.
HTH.
BTW I have not had to use PostgreSQL specifically (typically my integration tests and run profile can get away with a pure java database such as derby or hsqldb and because the artifacts are environment agnostic it is easy to have the integration test/dev flyweight app server inject the correct JDBC url) so you may hit some issues with regard to PostgreSQL

Resources