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?"
My company maintains a full Production, Disaster Recovery, UAT, Systems Test, and Development environment.
There are plenty of issues however, the breakdown is as such:
Dev: Development only. New code, new app, etc.
Systems Test: Dev+/Integration testing
UAT: Pre-production. Used for 'User Acceptence Testing' (Prod with stale data)
DR: Full mirror of production located 50 miles away.
PROD: Full production environment.
And misleadingly titled "Environmental Variables", no less.
The only kind of environmental variables I worry about are the ones preceeded by an "export" statement.
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.
What if you can't afford a second machine to cover the "duplicate" test environment?
Couldn't get the production build team to set -DNEBUG because it hadn't been done on development/test builds. SEI level whatever!
No amount of explaining or arguing could do it: the idea just broke their concept of software production, plain and simple.
Just had to pull the assert()s out.
When you're in an environment where you have to develop software for hardware that is also being developed internally, the problem gets much worse. You have to deal with the fact that the hardware you're developing on is pre-production hardware that is almost certain to be different from the shipping hardware.
There's not really too much to be done about it. We don't want to have the code check to see which hardware it's on, as that would make it easier to have more bugs. In some ways, this can be good, as dealing with buggy hardware is very similar to dealing with failing hardware, and we need to have robust code that can detect and handle hardware failures gracefully.
In fact, sometimes it is best to have different development and testing environments, as the differences will sometimes help obscure bugs to show up more easily on one platform so that they can be fixed earlier.
Its hard to test and hit every scenerio. That's just a fact of software development that we all have to live with. You cannot ever test every situation so you go with what you got.
At my current job, there is a HUGE difference between dev and prod, and QA is someone closer to prod, but still on a dev box. In our dev world out env vars are much different than our prod world. Also our boxes are not pristine, they have been used and abused.
Only 'flamers' flame!
Does slashdot hate my posts?
I'm not really understanding the title of this article.
But I always try and use the exact same environment for all three. Even buying the same machine as the client if necessary (I'm a consultant, who only uses FreeBSD and Linux, btw).
However don't let that stop you from writing your apps and code so they are completely "relocatable". For instance if you have a big web app, you should be able to check it out, set it up, and run unit tests *anywhere*. On your powerbook, on your Linux test machine, on your OpenBSD VMWare machine, whatever. I can't stress how nice it is to have everything self-contained. Be sure to write step-by-step install instructions and test them every now and then on a fresh vmware install of your client's OS.
It's great for testing and development, it makes sure you haven't "forgotten" any settings, and when the client says, "okay, we need 10 more machines like this", you can install from scratch with confidence (or you can ghost I guess).
Forcing your project to run in different environments is
- a real PITA.
- a great way to uncover problems in your project before release
Of course, sometimes the problems you uncover aren't in your project, but in the underlying platforms. Ugh."Provided by the management for your protection."
We were allocated only one development environment on JRun for this project, but we have to use it as a user test environment, so we develop and do QA on Tomcat 3.3 under Linux. Tomcat 3.3 and JRun 3.1 supposedly implement that same version of the JSP and Servlet specifications, but JRun 3.1 has a few bugs that we discovered when we first tested the half-developed application on JRun.
We use Apache Ant to build the application from source, and every test environment (we have one for each developer, plus one for QA, plus one for User Testing, plus another as Pre-Production) has a separate file of "environmental properties", that we substitute in several configuration files, so we can forget about different paths, JDBC URLs, JDK location, etc.
Running the application on different base software has some minor inconveniences, but most of the time it works fine everywhere, and it has a benefit: we definitely HAVE to make everything configurable and portable, and that forces us to do good design.
There is just one thing that we can't test accurately on Linux: SPEED. The HP-UX machines we use are *slow*, and we can't emulate that accurately.
Sometimes you just have to live with it and slog your way through.
Schedules and design reviews be dammed we have a product to deliver!
Design, document, go over hardware design docs, code, configure simulator to mimic the hardware, test and debug in sim, debug the sim configuration, build various utils that you expect to help test the hardware...It all sounds great and proper by the book but doesn't mean jack until you and the hardware EE get your hands on the real stuff. First you have to pass the smoke test, then the clocks, then flash preload. Does it boot? Can we reload the flash via JTAG? No, can you flash an LED? No, does the BDM work? No, what's the matter? Eventually you find that all of the address/data lines on the processor are hooked up backwards. Instead of signals 0-31 attached to pins 0-7, 8-15, 16-23 and 24-31 they are all reversed 31-24 0-7, etc. How you ask? It turns out that the intern who did such a standup job building the schematic capture symbols and package database back in the summertime(who is now back in school) screwed up. *Sigh* Arrgh Did anybody check his work? We should have done a line-by-line after we laid out the board. Are there any other errors? Can we re-map the hardware and the address decoders? Yes, thankfully most of it goes through an FPGA...
That's just the beginning of bringing up some new hardware.
Good judgement comes from experience, and experience comes from bad judgement.
- W. Wriston, former Citibank CEO
The next time the cluster tried to reconfigure, it failed mysteriously. Customer couldn't figure it out, local support people couldn't figure it out, I was one of those people but out of town (I'm convinced given the nature of the problem that I would have figured it out), so they ended up having higher level engineers driven in from 6 hours away to come look at why the cluster reconfiguration was failing.
They found the problem--apparently some part of the scripts that were running the cluster reconfiguration process trusted "ls" from the environment instead of calling /bin/ls directly (as any good security person would tell you is the right way to do it). The characters at the end of filenames confused the reconfiguration scripts, breaking them. And yes, that obvious failure on the clustering scripts was corrected, and that version of the clustering software is antique now anyway, so you needn't worry about whether what I'm talking about will affect you.
This isn't really a production/dev environment difference so much as a cautionary tale about how things in the environment you may not expect can still effect what's going on. Even the difference between "su oracle" vs logging in as oracle for example, could change your environment noticeably. I've had other customers make similar changes with unwanted effects, told them specifically to look at the root .profile etc. to see why two "identical" machines behaved differently, only to have them pooh pooh the whole idea until I had them send me the files in question and was able to prove to them that the cause was indeed in some environmental setup difference.
7 November 2006: The day Americans realized corruption and incompetence weren't addressing 11 September 2001
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?
If possible, convince management that your Test/Staging env needs to be beefy enough to function as an "emergency backup system" and GET the marginally equivalent hardware.
On the side, if your production DB server is a cluster and your development DB server is not then where is your DBA going to practice all those hideously complex operations like failover and zero downtime promotes? If that is your situation then that is asking for major trouble.
Vonnegut was right: Of all the words of mice and men, the saddest are, "It might have been."
But those are exactly the ones that should be analyzed and changed according to the environment you're working in.
For development, I write C code which is converted by a tool so that it compiles and work under Windows as a binary plugin for a simulator. The production system is an OS-less Big-Endian microcontroller. Since the simulator is running on a little-endian PC, the tool we wrote has to modify all the code so that it stores its working variables in Big-Endian format and converts it before use. It also has some cleverness to convert all the bit-fields so that their storage and access is the same on both systems. The code has to do a lot of IO with other systems (both simulated and not) so internally storing the data in Big Endian format on the Little Endian system prevents us from having to change the code much or adding special purpose Endian converters on all the IO interfaces. Since the production system is a few orders of magnitude slower than the simulator we don't care about wasting extra cycles there. Using this approach, we were able to convert the Big Endian code to work under simulator pretty quickly.
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.
test environment: well, none.
Please, take the effort to initialize a whole new instance of the database for each environment. Sure, it's a bit of work, but just don't go around stomping on each other's feet thinking it's more convenient. Yes, I have witnessed such stupidity before.
-- Microsoft is the most expensive commodity operating system and office suite vendor in the marketplace.
Its what real men do. Real men work in over-capacity, understaffed environments, where the "Test Lab" budget is instead spent on things like "Six Sigma Training" and "Employee Appreciation Week".
I want to delete my account but Slashdot doesn't allow it.
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.
I recall one chip that was shipping installed backwards. It happened it worked in most situations too - except for a few corner cases that was blamed on software for a long time. (I'm not an EE, so I can't give you any more detail)
Another time I spent a month chasing down bugs in my code only to discover all the test system was broke, but since it passed all other tests when the work around for my code not being done, they blamed me. It is not a good feeling to find out that your code was bug free after months of being yelled at for bugs in your code. (I'm not going to comment on the schedule that didn't tell me about that part of the code until a work around was needed - those problems always happen)
Where I work we have Dev, QA, and Production.
:)
All of it's Windows-based (this company drank the MS Kool-Aid), but all three platforms are basically equivalent.
The SQL servers are physically three different machines, but they're all clones of each other.
The web servers are either local machine running XP (Dev) or Web Farms running Win 2K3.
We have a transfer utility to facilitate moving the files back and forth, but it doesn't get everything. This is a mixed blessing, but it's handy when you DON'T want something to be pushed to one of the servers.
Generally that utility works only in one direction.
One exception: The business people work on QA. This means that sometimes we'll have to pull something down, but it does mean that they're discouraged from monkeying with the files directly on production.
Network setup can also be a difference that is difficult to emulate in development/test setups. You have to emulate network latency, bandwidth, packet drop etc. NIST Net looks good, but it is a bit heavyweight for everyday use. I usually stick to suspending servers/clients with kill -STOP in order to test latencies, packet drop, and timeouts. In one case where latencies really mattered, I ended up being granted access to development servers on 2 different cities and also using my home computer as a remote server.
Another area which can be difficult to emulate is the data size. One thing just generating enough data to match production environments, say 3 million records, but another is generate the data in such a way that the database becomes fragmented in the same way it does in production environments. No real way emulate this properly, except possibly mishandling the database setup to the horror of your DBA :-)
Related to the data size is the difference in data, that being the variation in usernames, the fraction of invalid passwords, fraction of unused accounts, usage patterns, etc. You have to know your customer's environment. Your own customer support people are your friend here, as you can rarely get a complete data dump and traffic logs for the whole week - it is usually sensitive data. The most productive way to handle this is getting a very good grasp of the production environment and the usage patterns, and then spending the time it takes develop a test tool that emulates it closely.
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.
It's common knowledge that the development environment should be the same as the test environment which should mimic the production environment whenever possible.
This is quite mixed up.
The test environment should always be *identical* to the production environment, in all aspects where it is feasably possible. Running tests in an environment that is in any way significantly different than your production environment is basically a waste of time and can lead to huge amounts of unforseen holes in the software.
Assuming the above, the development environment should then be *as close* to the test environment as is reasonable. However, this difference is always going to be somewhat substantial, since you are going to have development/debug copies of libraries, development software, probably more CPU/Ram/Disk on the box, etc. The important thing to remember is that the closer the development environment is to the test environment, the easier it will be for you to find, reproduce, and fix any problems that come up during testing.
I'm currently working on a project where we develop on Dell, test on IBM, and the production system is up in the air
To me, this sounds like a disaster in the making. I would really go straight to your manager and tell him that testing and production really *have* to be identical, or at least reasonably close. If they refuse to give you the resources, I would just reply that you can not not guarentee the testing, and save that email thread. If it impacts the timeline, or the project fails, at least you have an "out".
There is no way I would stand behind testing done on a totally different machine than the target platform.
As you will be running in a VM environment, I'm assuming it's Java. I develop on a Windows box, check into source control, build on a Solaris box, and deploy to Linux machines for some of our systems. Fun! Well, it's really not that big of a deal. Two major complaints.
/usr/bin/java on some systems, or /opt/java/..blah.. or C:\java etc. No fun.
One of the things that you will find as you migrate around different OS's is the default character set. Sometimes it's UTF-8, other's is ISO sets. You may even be Kanji or some other one that you're not prepared for if you distribute your system externally. Most VM's have a way to force a character set. Always use this.
The other thing I find frustrating is that start/stop scripts for servers. Windows uses their own system, as does Solaris and Linux. But, in Linux, you may want to take advantage of some of the tools, like chkconfig. Also, where your VM's are installed, you normally have
I've had to manage Java and .Net projects that dealt with corporate applications (no imbedded or driver-dependant routine), so take this comment for what it's worth...
My philosophy is to let developpers quite free. Of course, they have to get authorized to run a newer version of the VM (and that version has to be part of the roadmap), but I give them flexibility for their configuration. This is done with the vision of helping innovation through trial and mistake. The key there is to have clear guidelines and a published roadmap, so that "innovation" pays off!
When we hit the first beta, things get serions... They are deployed on test environment. At that point, there is no compromise: the environment has to be as similar as possible to the production environment. This attitude payed off time and time again.
By having the applications run in a production-like environment, from the first beta, it helped us isolate problems due to overly-optimistic configuration changes, very early in the game, when it doesn't cost too much to fix. We even had a time where we modified the roadmap to allow a new version of Tomcat earlier than planned, because tests demonstrated that the great new features were more costly to back-port than the cost of crushing a config change.
In summary:
- Development: Let them play, but with a nanny around;
- Test: Bring-in the confuguration-nazi;
- Production: This is what pays your salary, trust this anal administrator...
Where I work, pelople estarted using absolute paths for the new Java application. Dumb...
Moved to production server and it obviously did not work.
\m/
I've had far more problems because of 'bad' developers who do things use single character variable names, fail to add up accounting systems or code using local dates so that we have to make sure out SQL servers run US local.
Embedded systems and blackbox development all have there problems, but you should be able recognise them and compensate, having a few experienced engineers on the team will help everything go smoothly (and tell you when it's not)
First off,
Make sure your procedures are reasonally well tied down, automation helps a lot since people always forget to cross the t's.
Then make sure that you development environment is robust, put in good revision management software and make sure it intergrates properly with the feature tracking and bug software.
Make sure the flow of communication between production and QA, QA and developement is good, if possible try to give production 'some' access to the bug-feature tracking system.
Finally,
Make sure that as much as possible is proofed, bugs should have test cases (where possible), and releases should be 'delta' and have rollbacks. Try to test the rollout before going gold. You don't need the entire production environment just a few boxes.
In the past I've done sandboxed and VM based testing, I've also used a small server in the production environment to test rollouts and preform regression testing that the software could switch to allow the clients QA team to perform testing.
Portability and migration issues never amount to the problems you get from poor initial design, programmers who don't get enough sleep or failing to hire enough experienced employees.
thank God the internet isn't a human right.
I work at a web development shop. We have (depending on the client), up to four different environments: dev, preview, qa, and production.
We write code on dev, push to preview for the clients to view, double check on QA (it's on the premisis with the production machines and maintained by the client's IT staff), and finally move things to production when it's time to go live.
The client is a big media company, and accepts tar files and SQL scripts from us. All changes must go through dev -> preview -> qa -> production, without any exceptions.
The transfer of files from dev to preview is automated using a web based internal tool. Every time files are transferred, a uniquely numbered tar file is created and placed on an FTP server. When we want to move something live, we ask the client's IT staff to grab the tar file from our FTP server and move it to QA and then production.
At first it took a lot of getting used to not having access to the production machines, but now we just have to factor in the extra time it takes to move things live. Since our client's IT department is the one who requires these changes, it doesn't reflect badly on us, and lets us go home if the live servers crash.
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)
In my experience, the kinds of problems you run into are differences in:
- shared libraries
- OS configurations
- users/groups
- differences in external resources within the tiers (dev/prod databases, app servers, etc)
Well, how long do you have?
- C programs with host names hard-coded in #ifdef...#else...#endif blocks that aren't compiled with the right macro defined for the given environment.
- 20-character wide terminal device that vomited all over itself when the program tried to display a 21 character string, which we only tested on 80 character terms before sending to production
- Intermittent communication failures because of a different version of firmware on a network device in production versus dev/QA.
- WAR files that won't deploy in production because prod runs SunONE and dev runs WSAD.
- System commands not behaving the same because dev was Linux and prod was Unix.
- Integration test failures because someone copied the production encryption key to one dev/test server but not the other.
- Programmers forgot to take the hacks out of the makefile so the program will run in their little world before they compiled the test/QA version of the program.
- Version management commands that are different on different OSes.
- Automated test scripts fail because of some minute difference between dev, test, and QA (that one really pisses me off).
Shall I continue?
I work in an office of some 30-40 people. We are just all smart people :P You can cut some things back, but not testing. It would be better to cut back on developer's machines than to have a sub-standard testing environment that doesn't match production.
Improper testing and QA procedures is a major cause of failure for startups. Your product needs to be *rock solid*. In order to do this, you should **always** be running QA testing on your target platform. Anything else could lead to improper assumptions, which in turn could lead to lost sales, and eventual failure of the company.
I develop Java/J2EE apps on a Dell and our test and production environments are AIX. Other than filenames, which can be stored in a persistence layer, there's rarely any changes that have to be made between environments. I guess one answer is, use the appropriate tool for the job. I see a lot of pissing and moaning about Java not being truly portable, but unless you are using bleeding-edge libraries like non-blocking I/O (JDK 1.4.x revisions have had all kinds of inconsistencies with this), you are very unlikely to run into problems. I've been doing this for 3 years now, and NIO was the only thing to give me problems.
Development
Fully patched Windows XP or Windows 2000 Workstations, installed with all the development tools we need. Developed applications are _NEVER_ executed on the development workstations; this keeps the development platforms from being 'corrupted' by miscoded applications.
Testing
VMware server, running a simulated NT domain as well as simulated test platforms. Our VMware simulated test platforms are 'out of the box(OEM)' Windows or Linux images as well as images which match the Pre-Production environment. As the Pre-Production Acceptance environment changes, we can simulate those changes in the test environment to see how our applications may break. We then work on a solution. When we find a solution, we commit the Pre-Production Acceptance environment changes to the test platforms. Applications which pass the Q/A tests, are then sent to the Pre-Production Acceptance.
Pre-Production Acceptance
The Pre-Production Acceptance is an environment managed by the Production team (not the developers!). This is where Application bugs found in the Pre-Production Acceptance environment are sent back down as reports to the Developers. This is where the application is integrated, and the latency and load testing are done, using real production data and load which is replicated from the Production environment.
Production
Applications that pass the Pre-Production Acceptance finally are integrated here by the Production Team.
The main problem I have faced with development projects were groups/teams work on different environments is:
Having to deal with compatiblity issues on my own due to a variety of environments and having this workload not properlly being tagged as part of the development of the product (just-fix-it-don't-want -to-hear-about-it syndrome).
In the embedded arena, powerful+expensive tools like Windriver Tornado tackle this problem quite well. Support..support..support.
Whith less sophisticated tools the amount of work related to tackle down compatibility issues (works fine in my system thank-you-very-much) is usually ignored and management tends to squint to much attempting to assess/understand the overall impact...(is that really a problem?).
That being said, multiplataform development is not a curse but a given in the embedded development arena.
The solution is again, buy expensive tools were the paid support takes care of cross-plataform issues or build a well-disciplined cross-department environment control group/resolution team.
Either way costs money.
cheers.
- these are not the droids you are looking for -
<sarcasm>You mean the ones besides %windir%, %tmp% and %systemroot%?</sarcasm>
In my case, home, home, and, um...oh yeah, home.
Problems? Well, on Windows, errors, the occasional 0xC0000005 and the occasional total system crash; on Linux? I'm still learning, ask again in a few years...yes, I just program for fun. I'll go now...
You can hold down the "B" button for continuous firing.