Environment Variables - Dev/Test/Production?
Woody asks: "It's common knowledge that the development environment should be the same as the test environment which should mimic the production environment whenever possible. I'm currently working on a project where we develop on Dell, test on IBM, and the production system is up in the air. For embedded systems the differences can be running on a VM versus running on the actual hardware. What I want to know is what kind of problems have Slashdot readers been faced with because of different environments being used for different phase of their projects, and how have they been overcome?"
I've worked on several similar projects and one of the items that bit us was when the developers made assumptions based characteristics of the development platform that were somewhat radically different than the production platform. Assumptions around the size of data (not just word size, but buffer sizes for some text retrieved from "standard" libraries) caused a number of problems on several Java projects I've worked on (not to mention the ones in other languages). Data size seems to be one of the more commonly overlooked items in design and implementation, so I'd urge you to make sure that you've done your due diligence to ensure that you don't find those after the fact.
Another area is performance. For reasons I have yet to understand, there seems to be a prevalent myth that performance can be bolted on after the fact (the "make it work, then make it work fast" mindset). The truth of the matter is that performance has to be engineered in from the beginning or you simply spend a lot of time and money rewriting code that should never have been written in the first place. Sadly, educational institutions don't appear to place any emphasis on actual performance or teach the principles of performance tuning as part of their curricula.
The best approach is to create an environment variable that defines the development environment, example DEVENV=DEV, DEVENV=TEST, DEVENV=IT, DEVENV=QA, DEVENV=PROD (or not needed for production at all), and then elsewhere (controlled and basically kept hidden from the testers or users), other environment variables are set based upon the value of DEVENV. Examples of these environment variables would be your PATH variables, ORACLE_SID, etc.
Then, the final problem is educating the testers what DEVENV means, and more importantly, why that one has to be correct and that they should not mess with any other environment variables.
If the testers can't understand that, you need smarter testers.
You are being MICROattacked, from various angles, in a SOFT manner.
Repeat after me, it's not about the platform unless the production units are seriously constrained in some way that cannot be replicated on development or testing. The one thing that has consistantly hamstringed projects in the past is not being able to replicate a dataset that comes close to replicating production bugs on development and testing. Without having a full production dataset in either development or testing you push something out that works only to find that the data causes some completly unrelated thing to break.
This is of course assuming that the software platform is adequitly compatible not to introduce stupid bugs because of diffrences between servers.
What if you can't afford a second machine to cover the "duplicate" test environment?
About 95% of the time I hear this, it's false economy. Most hardware is pretty cheap these days, and good developers are very expensive. It takes very little time savings to justify the purchase of new hardware.
In the few cases where it's too expensive to duplicate hardware, then you can fall back on careful profiling and simulation. For example, if you know that your production hardware has X times the CPU and Y times the I/O bandwidth, you can set performance targets on your development environment that are much lower. Or if you can't afford a network of test boxes to develop your distributed app, then things like VMWare or User Mode Linux will let you find some things out.
Of course, every time your tests diverge from your production environment, you add risk. A classic mistake is to develop a multithreaded app on a single-processor box and then deploy it on a multiple-processor box. So as you get cost savings by reducing hardware, it's good to keep in mind the added cost of inadequate testing.
test environment: well, none.
Why wouldn't you have asserts in the production code?
If the code were properly designed to fail gracefully in production, a failed assertion isn't very graceful.
-- Microsoft is the most expensive commodity operating system and office suite vendor in the marketplace.
Well, maybe they'll read my post and you'll be able to chill out.
-Peter
And a different question: Why would you compile with different options in the test and production builds? That would kind of invalidate the testing.
You shouldn't compile with different options between test and production, but you should do so (for things like -DDEBUG) between dev and test... developers need their extra debugging statements, and asserts, but they interfere with appropriate user interfacing in production.
As I see it, the steps are:
1. Develop
2. Test in production mimiced environment with -DDEBUG (still part of development phase)
3. Hand off to QA phase to test in production mimiced environment without -DDEBUG ("production version")
4. Release "production version" to production.
(obligatory...
5. ???
6. CODE NIRVANA! )
"Go to CNN [for a] spell-checked, fact-checked summary" -- CmdrTaco
There's another myth about projects -- the requirements were actually correct.
Odds are, if someone is rushing for you to get a project done on an unrealistic timeline, they haven't done their analysis of the project correctly, either. Having _any_ prototype up there can help drive the requirements analysis, so that you can figure out what needs to be changed.
But yes, then you scrap that entire thing, so you can do it correctly.
If you're making minor modifications to an existing system, then yes, you most likely wouldn't need a whole new prototype, but then again, you'd not be designing from the ground up, either, I would hope. [unless you get one some idiot manager who decides a new language is better, or you have to make some sort of fundamental internal change]
Oh -- and if an outside contractor asks for a couple of weeks of logs of the former systems, get rid of them -- a couple of _months_ will not identify cyclic trends that may be present. [especially when you work for a university, and it's the summer]
But be realistic of your goals for the project -- sometimes you're working to optimize on CPU, optimize on memory, optimize on disk usage, or optimize on the programmer's time. Until you get _everything_ running, you won't know which one will be the bottleneck. [although prior experience can give clues]
Build it, and they will come^Hplain.
Now we have a number of environment-specific settings, for example database connection details, etc.
All environment-specific stuff goes into
Every successful build is tagged in CVS with an autoincrementing build number. When we have identified a release candidate, it is as simple as instructing anthill to (re)build a deployment bundle for a particular target with a specific build number. That deployment bundle (usually a
An additional benefit is that each environment's individual settings (including development machines) is always available to all developers for comparison and troubleshooting.
I guess the lesson learned is this:
I asked for a refund - and got my monkey back.
One of the worst problems I had was related to hyperthreading. Turned out an 3rd party component that was a black box was threadsafe, but not multi-processing safe.
When I finally figured it out (of course it happened only once in days, had to write and tune exercisers for weeks to get it to occur within minutes), an update became available.
(we nailed 4 from the 6 spots in that patch already ourselves by then)