Patterns of Enterprise Deployment – Big Bang

August 18, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary
You have several interdependent applications. They are typically client-server. You shut down all of the services and make them unavailable then deploy all the updates in the MaintenanceWindow. When the applications are able to run again, all the versions of applications are updated. For instance, in a 2-tier client-server application, you need to make the changes to the database schema and the application at the same time. In order to prevent users entering bad data yuo take the database server offline and perform the schema changes. Then ensure that all clients are updated before you re-enable the database.

This kind of change is high-risk; you should ensure that you CommunicateChanges and ensure that you have a RollbackPlan.

Difficulty
Medium; this is very simple, but the risk can make it harder than it looks.

Advantages

  • simple to understand.
  • few, if any, changes are required to the application to make it more deployable

Disadvantages

  • downtime is essential, and may be quite long if the deployment doesn’t go to plan
  • if there are instance of the one of the application that are missed then there may be trouble; if you have used a VersionedContract or a BackwardsCompatibleContract then things may be OK. Worst case is that the contract is compatible from  technical point of view but the meaning of the fields in the contract has drifted.

Use when

  • The users are tolerant of downtime
  • you don’t have time or inclination to implement a graceful deployment strategy
  • there are only a few applications to update
  • the deployment process is repeatable; preferably an AutomatedDeployment or a DeployFromSourceControl
  • if changes are very rare; for instance a new office requires a server move or a major piece of middleware is being upgraded. For instance, a change of SQL server version.

Don’t use

  • If the opposite is true! high-availability, poorly controlled deployments with many interlocking applications will be too much work to do this more than once!
  • there is more than one change happening; for instance, a new office and a new version of SQL server.

My experiences
Working in a small company where users are always clamoring for features and are sophisticated enough to survive bugs, you see this a lot! If the pressure is on to deploy then you simply take the server out and the users have to accept the downtime. The problems come if there are several teams working on different parts of the application stack. Then every team deploys and – as far as the user is concerned – takes out ‘the system’ in entireity. You can’t do this too often and expect people to be tolerant for long. If this is the case, the you need a WeeklyMaintenanceWindow.

Patterns of Enterprise Deployment: Application-updater shim

August 18, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary
This is a small application that sits on the running machine and gets launched instead of the real application. Its only action is to check if there is a later version of the application, and retrieve it if there is. It then seamlessly launches the real application. In the case of user applications on client machines, users may not even be aware that there is another application there.

Also known as the self-updating application, there are technologies available that mean you can make an application update without coding it yourself.

Difficulty
Low

Advantages

  • The application updates on all machines as soon as there is a new version available and the application is used
  • decentralised deployment: you don’t need to keep a central list of all instances, and you don’t need to deploy to all of them in one go

Disadvantages

  • if you deploy a broken version, all the clients will be updated to it. It is hard to prevent this from happening in an uncontrolled way except by saying “don’t start the application”. In some cases it will be simple to prevent the new version from being downloaded but you should have a simple rollback plan ready to implement
  • can be annoyingly slow if there are many new versions to deploy
  • if the application is client-server, then you won’t be able to update the server and client unless the client application are forced to update. If they aren’t forced to get the new version immediately then running client applications may fail when the server is updated. The fix is obviously to restart the client app, at which point the new version will be downloaded. However, if you force clients to update you will lose some of the “as needed” goodness of the pattern; this is not a big deal as this will only apply to running client apps. However, if the change in behaviour is a breaking change, but the contract between client and server is not altered (for instance, an integer field is changed to be only positive integers) this may lead to perplexing bugs or bad data being inserted to the database.

Use when

  • pretty much any time you have a large number of users running your application and don’t want to push the version to each machine

Don’t use when

  • precise control of when the update occurs is required by users
  • for server-side applications

My experiences
I’ve seen this implemented several times. Some as simple as a batch file that checks the date on the application binary that is in the deployment shared drive and then copy the whole thing down if the date is later. The most sophisticated is ClickOnce which uses a deployment URL or UNC path to be the source of the files. This was predated by the Microsoft application updater block, which is very similar to ClickOnce in many respect, but ClickOnce has more stuff “out of the box”.

Shocker: Changing my code broke my tests, a developer confesses

August 18, 2009 by NoMoreHacks

I hear a lot of objections to writing unit tests. They vary from “The test isn’t catching any bugs because the code is too simple.” to “The test is more complicated than the code, who is writing tests on the tests? ha ha ha!” However, the one I hear most often is “I changed my code and all my tests stopped compiling. Now I have to do much more work and I still didn’t catch any bugs.” This comes up so often that it really deserves to be thought about.

Here is the bad news: even though writing unit tests can improve the quality of your code No-One Said That It Was Going To Be Easy. The problem is, as some of the cynics point out, that test code is still code and it will need work.

We have 2 ways to tackle this:

1) increase the amount of worth of each unit test
2) decrease the amount of work required for writing and maintaining each unit test

Improving unit tests is a topic that can, and has, filled entire books. Writing the test in the first place can be hard mainly because we don’t know how to write them or what to test. The amount of work that is required for a unit test bites us in two ways: it bites when we write the test and it bites again and again and again when we change the code.  Maintaining the tests can also be hard and that is what often leads to dead tests and people either ignoring them or commenting them out so that the “real” code compiles.

There are two parts to how we address the length of time that it takes to write and maintain test code; but first, that bad news again: it will take longer to write software that is tested compared to just hammering it out with no tests. However, the fact is, that if it isn’t tested then it isn’t done. You can — and some of you will — argue that a test that is executed once via the GUI when you write the code is a valid test. You also probably argue that writing a unit test that is reliable enough to be run automatically is too much work and is slowing you down. Well, that is true. Writing no tests at all will certainly be faster… for the first hour. If you are unlucky enough to have a business-driven solution, it will be complex and subtle and your lack of tests will bite you before you even do the first release. The reality is that like using software to do anything else, writing software to test other pieces of software automatically will take time, effort and brains. The good news is that writing good test code is no different to writing any other sort of good code; you keep it simple, reduce duplication and so on.

However, we can write software so that testing it is easier and we should. When you write your unit tests, you are the first consumer of the code. If you can’t drive it from the outside, it is awkward to test. If it is awkward to test it will also be awkward to use. If the tests break when you change the code, then this will also happen to your “real” code. This isn’t about being test driven — although that helps — it is about writing genuinely OO software. OO code is naturally testable and doesn’t need to be redesigned for testability. That’s the funny thing, test code is also real code.

Let’s look at a couple of examples of common problems when creating and modifying code that has unit tests. First, the classic: adding a parameter to a method. I’ve heard this so many times: a developer modifies a small piece of a function and needs to add a parameter; therefore they have to modify 50 different test methods. I think that there are a few ways to deal with this depending on the situation:

1) Mechanically alter the tests
Be honest; if the tests are that mechanical then it will probably only take a few minutes to find and fix them. You are, however, then in the dangerous position of having altered your test code and your “real” (system under test, or SUT) code. Of course this one will come up sometimes, but it really isn’t the answer. If you had to do the same thing to real code, you might grin and bear it once, but if you left it alone it is probably because you were too scared to change it.

2) Restructure the tests
Test code with that much duplication in it is probably bad anyway. You should clean it up before you start the changes on the real code. Instead of calling the method in 50 different places, hand the task over to a single method then you only need to make the changes in one place.

If the test code is bad you end up with brittle tests that keep breaking the build. If you have tried to get that warm fuzzy feeling of “mmmm, lots of tests” by using cut ‘n’ paste then your tests are probably quite shallow anyway. If things are properly structured you shouldn’t see that kind of duplication.

Also, testing the same method over and over with the same parameters and playing with one of them; making it null, negative, out of range etc; that is just ONE test. The exception to this rule is on a class that represents an external, or public, interface. If for instance, you have made a class that is a web service and you have told your users that it is exception safe, it better be just that. And you better have lots of tests to back that up. Of course, if the interface changes then the tests may break, but that is OK as you can’t change it anyway as all those external people are using it! Of course there are ways to take that repetition out, like using reflection. Didn’t think of using reflection in test code? Hmm almost like it was “real” code. I remember working on the first project that I did using unit testing like this, and manually cranking out hundreds of these suckers. Ridiculous, but I’m stronger for it. :-)

But what if the changes mean that you can’t do the tests anymore? Well in that case it might be that the changes were bad!. If you make changes too deep, too fast you won’t be able to get it right tests or no tests. The answer: roll back your changes, read the refactoring book again, try again! Try making slow changes; and only one change at a time and test in between. Even if you haven’t got full test coverage this makes sense; and automated unit tests will be better than running up the GUI once per minute. If you need to change the test code and the SUT code then you are in trouble and you need to go even slower.  In this case I’d recommend refactoring the test code to a structure that allows you test the new structure, then changing the SUT code. In either case, you need to make some piece of code that is a scaffold that allows the one thing to be changed at a time, then when both are in the new form you can throw the scaffold away.

3) Restructure the real code
Maybe the problem in the breaking tests is not the tests. If you have a method that has more than 3 parameters on it, you are probably in trouble anyway. Don’t tell yourself that it is only one more parameter. It is time to get out your refactoring tool and use those tests — if they are worth anything — and change the interface to something that will tolerate changes. The simple one in this case is to replace the long list of parameters with a property bag, then when you need to add parameters, it won’t change the method signature and the tests won’t break.

Actually, in my experience, this is actually less likely than 2. But still possible… there are 2 chances here; 1 that you don’t really do TDD very well and you’ve made a set of classes that wasn’t well designed and now need to change them. When you’ve done a little more TDD you might either accept that things need to get thrown away or get annoyed and start making more flexible, testable code that requires you to throw away less.

The other chance is that you’ve made code that now doesn’t need testing; that is possible that you have refactored your code into being compile-safe. and there is no point in testing the compiler as it isn’t the SUT. Most people who have broken a set of tests like the idea that the new code doesn’t need testing; but don’t give me that “Look, the application works, I don’t need to run all the tests”. A working application is the weakest criterion for tested code and simply unacceptable for anything that is ever going to change and you will be responsible for it breaking.

Let’s look at a counter example where people think that they have done something OO and point to it as an example of how OO isn’t testable and how they have to “compromise” their OO design in order to make things testable,. The kind of thing they do — apart from just not testing — is to start making the internals of the class public or even worse, start using things like .Net private accessors or even reflection to get at the class internals. In my opinion, that isn’t sensible.

The classic example here is a an inheritance hierarchy where the sub-classes have to override an abstract/pure virtual/MustOverride method in the base class that does the real work. The function that does the real work is, of course, made protected so it can’t be called in the wrong way. How do we do test this without breaking into the class? Well there are a couple of things we can do. The first thing is don’t use inheritance unless you have to. It is one of the tightest ways to bind classes together and the problem of testability is entirely avoidable. For instance, you can inject a function pointer to change the behaviour of your class or extract the behaviour into an interface if there are multiple methods and inject an instance of that. Then the worker method is broken into its own class and becomes testable. OK, say you can’t refactor this way, what else can you do? You could use subclasses again; use a subclass to spy on the context that the work method is called from so you can test the base class behaviour. You can use a sub-sub-class to try and play the same trick on the worker class. You might be stuck though, and have to put up with obscure tests that run on big blobs of functionality. Oh well, tough luck. Like I said: No One Said It Would Be Easy and you’ll do it right next time.

The funny thing is about writing unit tests is that you will start writing better units. Your code will become more inherently OO. That doesn’t meant that it will be better in itself but, after all, people invented OO because other approaches were insufficient. It has become the de-facto programming paradigm for software that has to cope with changes and develop rapidly; software that has to model things in the real world; and, of course, software development where cost is a factor. In other cases, like brutal high-performance, multi-threaded applications or running on embedded OSs or like deep-space satellites where there will be no updates and there simply can not be any errors, OO is less relevant and unit testing there would have to take a much different form.

Patterns of Enterprise Deployment: Setup Application

August 10, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary


Difficulty


Advantages

Disadvantages

Use when

Don’t use

My experiences

Patterns of Enterprise Deployment: Human Logger

August 10, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary


Difficulty


Advantages

Disadvantages

Use when

Don’t use

My experiences

Patterns of Enterprise Deployment: Communicate Changes

August 10, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary


Difficulty


Advantages

Disadvantages

Use when

Don’t use

My experiences

Patterns of Enterprise Deployment: The different types of pattern

August 10, 2009 by NoMoreHacks

In this series I think that there will be two types of pattern. The architectural patterns will focus on how you design yourself out of a difficult situation involving the deployment of software. The behavioural patterns will — obviously — be habits that will help.

The biggest concern of patterns is to recognise a problem that occurs again and again. Once a repeated problem has been recognised, it is often simple find a solution. The difficulty is recognising problems that are fundamental rather than incidental. It might also be possible to design a solution to problems that seem to be bad behaviours, if they are fundamental. However, this kind of pattern is hard to spot without breadth of experience and the time and inclination to be retrospective.

For instance, if you create a piece of software without a good redeployment strategy and that software has a lot of bugs, you might not come to the conclusion that you needed a deployment solution; you might just think that — in this case — there were a lot of bugs. Next time, you think, I won’t make so many bugs so I still won’t need a deployment system. This can happen over and over again; some people are reluctant to see that things are repeating and may think that concentrating harder is the answer.

The opposite can also be true; some people may do a thing badly and then think that either they need a new pattern or new piece of software to help; or they may think that “that way of doing things doesn’t work” when, in fact, other people can make it work. This can manifest itself as being “pattern happy” and trying to apply patterns when they aren’t appropriate or too many patterns at the same time.  For instance, it may be the case that someone wants to make changes to an interface; they make elaborate plans for logging and tracking changes; for rolling back the application and for publishing new versions of the schema. Then when the application is deployed they find there is only one other user, and they don’t even care about the changes! It takes 5 years to learn how to use patterns, and it will take another 10 to learn when not to use them.

Behavioural Patterns
These could be described as habits, but I want to put them on a level equal to patterns. Any habit that we have, and we don’t know why we have it, is a superstition. I think it is worth the effort to examine some of them and codify when they will and won’t work. There are some behavioural patterns that you might want to create a software solution to; to try and automate away the need for a human to be disciplined or precise. Computers are good at those things, people generally are not. However, just as there will always be a need for infantry, there are some things that need to be adaptable; and computers are bad at that (largely because it is so hard to make software adaptable). Some of the behviours will require interaction with other people; for instance,  CommunicateChanges requires software developers interacting with DBAs or the business stakeholders. Some will require nothing more than concentration while you are actually deploying; for instance HumanLogger. All of them require intelligence to be applied successfully.

Architectural Patterns
The problem with architectural patterns of all types is that they can seem like a sledgehammer to crack a nut. For people who are haven’t seen how complicated things can get in software that develops over years, they seem excessive and rather abstract. Implementing something which solves a problem that you don’t have is hard to justify, and rightly so. However, like OO design, if you understand the patterns well it should be no harder to use a pattern than to do it in a “hacky” way. Or at least, not much harder. It is quicker to hack, but not for long. It may take an hour to create a SetupApplication, but as soon as you have used it twice it has paid for itself. And as soon as it has prevented you from screwing up a manual installation it has paid for itself 10 times over.

Of course, like anything else, if you don’t know how to implement the pattern you will be fighting the tools and that can be an enormous time sink. If you don’t know what the tools already support you might be reinventing the wheel, and doing it quite poorly. However, don’t be afraid of DIY. You might be pulling off some obscure stuff with DCOM deployments by using scripting and all sorts of hacks and then someone comes along with 10 years in the DCOM game and says “Didn’t you know that you can…” but as long as you are conceptually correct a) you won’t have done a bad thing and b) it might be possible to replace your version with the “build in” version. And one other thing: even though many technologies come with deployment “magic”, in my experience making them work isn’t always easy and the hand-rolled, home-made version is more reliable and understandable because when the “magic” fails it fails stylishly and leaves you with a mess; but that might be because I’m not one of those fabled experts, just a luddite with a penchant for shell scripts. ;-)

I will be including some patterns that are obvious; for instance SetupApplication. Anyone who has used a computer in the last 10 years will recognise that. However, it is worth mentioning to put it in context with other solutions. Also, it needs discussion about when you shouldn’t use it. My intention is to present all the options, not just the “interesting” ones. Using the right pattern doesn’t mean using the coolest one, or the most enterprise-y one.

Having said that, one thing to consider when architecting deployments is that small applications can become big applications. Small user groups in one office can become international, multi-timezone, multi-language groups in just a few years. And if you think that a few years is a long time then you need to adapt to the speed at which applications change in serious enterprise infrastructures. Once an application’s contract has been woven into the fabric of the enterprise in several other applications it is then in messages and log files and web services and database schemas and reports and so on. Every one of those is maintained by a different group with a different release cycle. Not all of them will want the changes that you are making, few of them will have anything like adequate test coverage for you to be able to test before you go likve and none of them will have any resources to make the change.

If you expect to make a serious change in the public contract of an application you better start thinking about how you will deploy it before you go public. If you don’t you may find it difficult to retro-fit a deployment methodology. That is the point of this book; deploying can be harder than it looks and a small amount of thought may save a lot of pain later. Thinking about deployment before you have to deploy, just a little bit, can really pay off.

Patterns in the wild
Mostly you rarely see patterns in their purest forms. The point of a group of patterns is to allow us to create a set that can be built up and combined to form any solution to fit any technological or political situation. One example that I’ll discuss in another post is the Ubuntu Add/remove programs feature as it contains several patterns.

Patterns of Enterprise Deployment: Versioned Contract

July 6, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary

A contract is my word for anything that forms an agreement between two systems. It could be formed by database schema, message format or API.

You have a new version of a system that uses the same technologies as before but in the new version there are changes of usage or naming that makes the old version and the new version incompatible and confusing to compare. In order that you don’t have to do a BigBang deployment, your system continues to support both contracts. The new system maybe distinguished by a new name, version number, address, port number, GUID etc. Under these contracts, you may or may not decide to have one code base supporting all the requests. Ideally, there would be a single source for the data if the same data is accessible  via both contracts.

Many systems for doing remote invocation support VersionedContract as part of their architecture; e.g., DCOM, RMI, CORBA, .Net Remoting, .NET WCF.

Difficulty

Low

Advantages

  • Simple, quick to do
  • maintains old interface, callers don’t need to update

Disadvantages

  • leads to cluttered system interfaces
  • sometimes it just isn’t possible to clean out the old callers; that leaves you with version 2 and 3 as well
  • support burden can be onerous as the “old way” holds you back

Use when

  • You have a small new feature to implement and you can re-use the old contract as the implementation
  • it’s time to make a clean break with an old contract that is being stretched too thin
  • you just don’t know who calls your system or when

Don’t use

  • When you have already used it once.

My experiences

The classic instances of this, for me, come from the windows API. The one that stands out in my mind is the DCOM call CoCreateEx. The windows AP is full of this sort of thing because they fall under the “you don’t know who is calling you” advice. That is the one thing that MicroSoft do better than anyone else: backwards compatibility. They can support so many flavours of OS and the same damn code keeps on working. But you also see the burden of all those changes!

Patterns of Enterprise Deployment: Automated Deployment

July 6, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary

An application to take the pre-built executable deployment package and dump it onto the target system in the correct state. The AutomatedDeployment may be as simple as a shell script to copy the binaries from your development machine to the test server; or, it might be consuming the output of a system that does a full clean build and migrates it onto the production server. This is somewhat different from an InstallerApplication as there is no interactive element and the emphasis is on rapidity and simplicity.

Difficulty

Medium

Advantages

  • repeatable
  • automation means you can concentrate on something else, especially if it is time consuming

Disadvantages

  • a fair amount of upfront work
  • slow to react to changes to the architecture of the system
  • can be dangerous; manual changes take time to be destructive; a deployment script that goes awry can wreck servers in seconds

Use when

  • there are several steps in the process of moving built executables to the running server
  • you perform the deployment many times; you may be deploying to a test server 20 times a day

Don’t use

  • When your project is changing so rapidly that you don’t know what it will produce
  • if you haven’t tested the automation very well and the target environment is unstable (e.g., many target machines and many versions of OS or other people are also using manual deployments)

My experiences

Coupled with a DeployFromSourceControl this is a good thing to have for agile developers who like to build the head of the trunk and stick if on the server. I also use it a lot when I’m working with a test server; i just want to grab the binaries that I just build and restart the service on the remote machine. It takes a few minutes to knock up a powershell script to do this, but it saves so much frustration and really, drag-n-drop is very slow! But, this really isn’t the same as a production quality script. If you have to use a script to deploy it is best if that is the only method to deploy the application; otherwise minor changes will creep in when people don’t follow the same pattern and the script won’t work properly. Worst case it will half-deploy and leave you with a system that you will have to recover by hand.

Patterns of Enterprise Deployment: Deploy From Source Control

July 6, 2009 by NoMoreHacks

This is part of the Patterns of Enterprise Deployment series.

Summary

DeployFromSourceControl is used when you are wish to create deployed packages only from source controlled code. Normally the pattern will be implemented by a system that will ensure that a known version of the source is obtained – often the latest – and then build into a deployable package. Many levels of sophistication are employed from batch scripts to full-blown event-driven service centres with web front-ends and deep integration with work-tracking project management systems that produce full audit trails.

Difficulty

Medium up to a full life’s work

Advantages

  • Repeatable
  • if it isn’t in source control then it won’t get built so there is no danger of losing changes when you re-deploy
  • you will, with varying levels of effort, be able to reconstruct any package that you build by examining source control timestamps

Disadvantages

  • a fair amount of upfront work
  • slow to react to changes to the architecture of the system; you need to make a second change to the deployment package builder
  • can be slow; developers must check in then wait for the changes to be build from source control

Use when

  • building the deployment package from source control is almost always essential on a serious enterprise project. In any case, this is valuable intellectual property; check it in!

Don’t use

  • When your project is changing so rapidly that you don’t know what it will produce

My experiences

This is a crucial one for any project, but don’t feel that you need to be constrained by the hoary old “build script”. As long as you are only building your deployment packages from something that is in source control you can do anything you like.  One nice twist that I’ve always wanted to try is to use a continous integration system – like CruiseControl.Net – to provide the built artefacts. You know that the stuff is in source control, just that it is a little fresher than normal! If you don’t like this and think that it is too unstable for releasing then you can run the CI build on a very stable branch that you only check into by merging in from the development brnaches.

If you can get a dedicated system for this then when you start integrating with the rest of your development process tools then things really start to look sweet. If you can get the whole TFS stack running well, then Team Build provides a huge amount of integration with work items and changesets/checkins and produces reports for each build in the staging area and means of tagging the build that is ready for deployment.

See also

AutomatedDeployment