We are using Liquibase now for almost one year in one of our current projects and it really worked out very well so far. We are basically using the “best practice” approach described in one of our previous blog posts here .
But … and isn’t there always a but? There is this one sentence in our project that -when being said during the daily standup or just written to the chat – is freezing your blood ice cold in pure horror. Ok, this might be slightly exaggerated :-).
The sentence is: We need a Liquibase restart!
This basically means there is no chance for us to make the required changes to the database using proper Liquibase changesets. But typically this ends up in taking a backup of the database, dropping the entire database, then setting it up again from scratch using Liquibase and then performing a data import again. Definitely not the nicest thing to do, right?
At some point of time this could become a real problem if your application is for example running for a larger customer base where those kind of things would impose a lot of work and a rather big risk. But let’s maybe start with the question how it comes to these situations where there is no moving back nor forth with Liquibase.
Incompatible Liquibase Changes
Ok, just a few nice examples and not all of them can be detected using testing in a CI-environment, but anyway. When starting the project we have assigned all database objects to a certain database user. But as we are part of a bigger project that user was used elsewhere and potentially even dropped there while our database objects still belong to that user. Well, bad luck that could probably not be prevented by testing, but only by thinking :-).
But there are other changes that are a problem and those are mainly making changes to already existing SQL-files which is not allowed in Liquibase and will result in an error during the next update. Another thing is missing rollback statements as we have a project agreement to deliver rollback statements for all our Liquibase changesets.
If those things are detected too late, which means a new Liquibase release is already in production it can be very hard to fix those still. This could lead up to the described process of recreating the database from scratch including a data export and import.
Best Practices Reloaded: Sometimes projects are working with Liquibase allowing incompatible changes until a delivery is really done into production. For our project we found this approach rather error-prone and time consuming as on all test systems and all developer machines the database needs to be recreated often which also typically means loosing all testdata.
Therefore we have the agreement to make all changes compatible changes directly. If we see for example a column was added that was not needed we create another changeset to drop that column again. In the end this is less work for us than informing everyone in the project that the next Liquibase update might fail. Of course there can be changes that are too complicated or even not possible. Then a small Liquibase Restart needs to be done that only affects our testing and development environments but not our productive installations. But this is really always only our last resort.
Continuous Integration to the Rescue
Being human (oh what a click bait, but the series is really cool :-)), well, means making mistakes. And as usual the earlier we notice those mistakes the better it is.
Therefore we have created two CI-jobs on our Jenkins that are dealing with our Liquibase installations.
Semantic & Syntactical Checks
The first one is a Perl-script – and I really still like Perl while my colleagues are hating me a little bit for writing that Script in Perl 😉 – that is performing a few simple semantic and syntactical checks on the Liquibase files. Those are:
- Simply checking that the first line in all SQL-files referenced from our Changeset-files is starting with “–liquibase formatted sql”.
- In the line after that one we are defining the name of the author and changeset. The script checks that the agreed naming conventions are followed here.
- Finally it checks that at least one “–rollback” section is found. Of course this cannot check if this is correct already, but this can already help missing the rollback accidentally completely.
This test is running with a frequent schedule and is this way checking our Liquibase files already shortly after a new check-in.
Liquibase Rollback Check
The second CI-job is running on a database instance we have installed on the Jenkins-server for this purpose. Again we are checking out the most recent version of our Liquibase scripts. Then we are dropping the database entirely and re-creating it again. Creating the database and the user is happening outside Liquibase in our project.
After that we are performing a Liquibase install. Then we are doing a rollback for the 10 latest changesets and then we are performing a Liquibase update again.
This is how this looks in the Jenkins-job. In this case it is tailored to a Postgres database, but of course it would also work similar with any other database.
1cd "/data/jenkins/jobs/Codecentric Liquibase Rollback Test/workspace/sample/" 2psql -q -U postgres -d postgres -c "DROP DATABASE codecentric" 3psql -U postgres -c "DROP ROLE codecentric" 4psql -U postgres -c "CREATE ROLE codecentric LOGIN INHERIT REPLICATION PASSWORD 'topsecret'" 5psql -q -U postgres -d postgres -c "CREATE DATABASE codecentric OWNER codecentric" 6java -jar ./liquibase-core-3.3.0.jar --driver=org.postgresql.Driver --classpath=postgresql-9.2-1002-jdbc4.jar --changeLogFile=./src/main/resources/liquibase/db.changelog.xml --url="jdbc:postgresql://localhost:5432/codecentric" --username=codecentric --password=topsecret update 7java -jar ./liquibase-core-3.3.0.jar --driver=org.postgresql.Driver --classpath=postgresql-9.2-1002-jdbc4.jar --changeLogFile=./src/main/resources/liquibase/db.changelog.xml --url="jdbc:postgresql://localhost:5432/codecentric" --username=codecentric --password=topsecret rollbackCount 10 8java -jar ./liquibase-core-3.3.0.jar --driver=org.postgresql.Driver --classpath=postgresql-9.2-1002-jdbc4.jar --changeLogFile=./src/main/resources/liquibase/db.changelog.xml --url="jdbc:postgresql://localhost:5432/codecentric" --username=codecentric --password=topsecret update
Together with the previous check we can be at least rather sure that some rollback statements are existing and that those are working if a rollback and update works properly.
Of course we are not at the end of possible tests here. For example we cannot detect this way if really all relevant rollback statements have been written. But it is a rather good compromise for us between effort and benefits.
For a complete rollback test you would need to probably install the latest release version and check all database elements to compare those with the results after some rollback. Would be maybe a nice project to do in some spare time :-), but the tests we implemented already help us a lot to prevent the one sentence we all fear. Liquibase restart no more!
Besuch beim Europäischen Go Kongress in Oberhof
Am vergangenem Wochenende habe ich die Chance genutzt und den europäischen Go Kongress in Oberhof besucht. Bevor es hier zu Verwirrungen kommt – wir sind hier ja auf einem IT-Blog – es geht um das Go-Spiel und nicht um die gleichnamige Programmiersprache...
3.8.2017 | 5 Minuten Lesezeit
JUnit Tests implementieren mit Mockito und PowerMock
Please find an English version of this blog post here. „Braucht die Welt wirklich einen weiteren Artikel über JUnit , Mockito und PowerMock ?“ Ich hatte da durchaus so meine Zweifel vor dem Schreiben dieses Artikels. Denn es gibt im Netz wirklich ...
25.5.2017 | 7 Minuten Lesezeit
What is Agile Testing? – A comparison with classical QA
When reading articles about Agile Testing the explanation often goes like this: Agile Testing means testing in an agile project environment. Followed by a lengthy description of what agile is (or is not). Hardly any further word on the testing aspect...
29.6.2014 | 7 Minuten Lesezeit
Struggling with Test Automation – Potential problems and how to approach...
Implementing automated acceptance or integration tests as part of a project is a very common thing to do nowadays. Even though already in “the earlier days” of software development often some scripting was done to automate certain testing functionality...
11.4.2013 | 10 Minuten Lesezeit
MongoDB: The Sixth Sense
Finally time for the almost final blog post on this series. It is the sixth lecture from the MongoDB course I am doing at 10gen education . As it is good tradition by now using film titles for the blog I will of course keep up this tradition . Nevertheless...
21.12.2012 | 11 Minuten Lesezeit
MongoDB: Supplemental – A complete Java Project – Part 1
What is the best way to start a blog post on MongoDB and Java programming? Any idea? Take your time, it also took me some time to figure out. And the answer is: Some really big relational table model of course :-). Relational Table View After being ...
16.11.2012 | 13 Minuten Lesezeit
MongoDB: Close Encounters of the Third Kind
Just with the first key strokes of this post I am entering the third week of my MongoDB developers course @ 10gen . Luckily I found another film title that fits in here, well one way or the other . Writing this blog series along with taking the lectures...
11.11.2012 | 15 Minuten Lesezeit
Robot Framework Generic Testdata Framework – From the Idea to the initial...
The basic idea for a Generic Testdata Framework as an extension to the Robot Framework was initially described here . Well, things have been proceeding since then and there is an initial release available for download. This is more then reason enough...
4.10.2012 | 4 Minuten Lesezeit
Robot Framework – Closing the Gap
Ever since I started working with the Robot Framework – already back in the days when I saw it evolving in the Nokia R & D – I am totally convinced of the power of its keyword-driven approach. It is an excellent example of the fact that the best solutions...
6.9.2012 | 8 Minuten Lesezeit
Automated Acceptance-Testing using Concordion
There are plenty of open-source tools available that are supporting the automation of acceptance tests. This also results in a lot of different concepts to do this. For example the Robot Framework is using a keyword-driven approach and offers a lot ...
- Software development
27.1.2012 | 8 Minuten Lesezeit
Executing tasks in parallel using Java Future
Recently I was attending a really interesting presentation by Adam Bien who was using Future as part of his demo application. Future offers a very elegant way to implement parallel execution of tasks in Java. As I found the concept quite interesting...
13.10.2011 | 5 Minuten Lesezeit
Robot Framework and RIDE – To Go
The Robot Framework is a mature tool to implement automated tests. With the help of the GUI application RIDE (= Robot IDE) and supported by its keyword-driven approach even less technical oriented people can start implementing testcases quite quickly...
1.5.2011 | 3 Minuten Lesezeit
Automatisierte Akzeptanz-Tests mit JBehave
Einleitung Im Open Source Bereich haben agile Teams mittlerweile die Auswahl zwischen einer Vielzahl von Werkzeugen für die Automatisierung von Akzeptanz-Tests. Dabei gibt es eine ganze Reihe unterschiedlicher Konzepte. FitNesse setzt für die Organisation...
25.3.2011 | 12 Minuten Lesezeit
Agile Testing Days Berlin 2010 – A Report from Day One
“Are you working as a tester or developer in your organization?” – Well, honestly this is a question I do not really have a good answer for at hand. I could say both, but that is sometimes bothering people as they tend to doubt this is possible. Another...
6.10.2010 | 11 Minuten Lesezeit
Robot Framework – Feature gefunden :-)
Passend zu Ostern bin ich gestern im Robot Framework genau über das Feature gestolpert, dass ich schon immer vermisst habe und welches dabei schon die ganze Zeit da war … aber eins nach dem anderen. Bei automatisierten Tests ist es eigentlich fast immer...
1.4.2010 | 1 Minuten Lesezeit
Agile Testing requires good Design
Automated tests are of upmost importance in agile projects. And automating tests means that those tests are developed; in a similar way than any other software is developed. This is a fundamental difference to manual testing, where tests are executed...
25.3.2010 | 3 Minuten Lesezeit
Database Library for the Robot Framework
We are using the Robot Framework for quite some time now for our automated acceptance tests with very good results. Personally I am using the Robot Framework already for a bit longer time and I find its fundametal concepts really extremely convincing...
27.2.2010 | 2 Minuten Lesezeit
Selenium and SSL Certificates
Selenium is a very efficient tool for testing web sites. The Selenium-IDE , that comes as a plugin to Firefox, makes it easy to record the required steps of a test. And to achieve real test automation Selenium is often integrated with some agile testing...
5.2.2010 | 4 Minuten Lesezeit
Selenium – Last Resort
14.12.2009 | 2 Minuten Lesezeit
Continuous Integration im Überblick
„Ihr seid doch agil, benutzt ihr auch den Hudson?“ Das ist eine gute Frage, die man – so oder so ähnlich – immer wieder von Leuten hört, die durchaus an agilen Themen interessiert sind, sich aber noch nicht wirklich weiter damit beschäftigt haben. Aber...
8.11.2009 | 5 Minuten Lesezeit
Pattern Matching – Java im Vergleich zu Perl
„Perl is born to pattern match.“ – Ich denke das kann man ohne Übertreibung so schreiben. Perl löst dieses Problem einfach extrem effizient und elegant. Das folgende kleine Skript zeigt ein paar Beispiele für reguläre Ausdrücke und deren Anwendung in...
30.10.2009 | 4 Minuten Lesezeit
Agile Testing by Example-driven Development
Agile Testing Days: The Missing Link for ATDD and Example-driven Development by Gojko Adzic This posting will be a small experiment using Twitter. As Gojko’s session was one of the most commented ones on Twitter I just distilled this blogpost out of ...
13.10.2009 | 2 Minuten Lesezeit
Testing Days Berlin – Key Note Mary and Tom Poppendieck
The One Thing You Need to Know … About Software Development Correctness can be confirmed at any time is the subtitle of Mary’s talk and it start off with the clear statement that Waterfall does simply not work. So let’s hear what works :-). The question...
- Software architecture
13.10.2009 | 5 Minuten Lesezeit
Agile Testing Days: Learning is the key to Agile success: Building a learning...
This was really an excellent session and it was especially great as the things teached do not only apply to one’s professional life, but can really be useful beyond. Probably I still have to do some thinking on this, but here is what I was able to note...
- Agile methods
13.10.2009 | 2 Minuten Lesezeit
Some days ago I checked the Google Testing Blog for some interesting new articles when I saw the article about Super Fast JS Testing . Well, basically I have to say “again” as I had read it already some time back, but had no time to really dig into ...
8.9.2009 | 3 Minuten Lesezeit
Eclipse: Resource is out of Sync (no more)
Probably everyone working with Eclipse knows the following message that shows up when a file that belongs to the Eclipse workspace is changed outside of Eclipse: Resource is out of sync with the file system: '' Press 'F5' or select File Refresh to refresh...
20.8.2009 | 1 Minuten Lesezeit
Agiles Testen – Das Herzstück agiler Softwareentwicklung
Agile Softwareentwicklung … Agilität hat zu einem neuen Ansatz in der Softwareentwicklung geführt. Der Kunde – und damit die Kundenwünsche – stehen nun wesentlich stärker im Mittelpunkt des Entwicklungsprozesses, als dies bei eher traditionellen Methoden...
- Agile Methoden
4.8.2009 | 6 Minuten Lesezeit
Dein Job bei codecentric?
Agile Developer & Consultant (w/d/m)
An allen Standorten
Gemeinsam bessere Projekte umsetzen
Wir helfen Deinem Unternehmen
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Do you still have questions? Just send me a message.