Representative Line: Destroying the Environment
Andrew H sends a line that isn't, on its own, terribly horrifying.
Utilities.isTestEnvironment = !"prd".equals(environment);
The underlying reason for this line is more disturbing: they've added code to their product which should only run in the test/dev environments. Andrew doesn't elaborate on what that code is, but what it has done is created situations where they can no longer test production behavior in the test environment, as in test, the code goes down different paths. Andrew's fix was to make this flag configurable, but it reminds me of some code I dealt with in the bad old days of the late 2000s.
The company I was with at the time had just started migrating to .NET, and was stubbornly insistent about not actually learning to do things correctly, and just pretending that it worked just like VB6. They also still ran 90% of their business through a mainframe with only two developers who actually knew how to do anything on that system.
This created all sorts of problems. For starters, no one actually knew how to create or run a test environment in the mainframe system. There was only a production environment. This meant that, by convention, if you wanted to test sending an invoice or placing an order, you needed to do the following:
- Get one of the two mainframe developers on the phone
- Prep the invoice/order in your application, and make sure the word "TEST" appears in the PO number field
- Make sure you're not near one of the mainframe processing windows which will automatically submit the invoice/order
- Submit the order
- Wait for the mainframe developer to confirm it arrived
- The mainframe developer deletes it before the next processing window
Much like in Andrew's case, our new .NET applications needed to not talk to the mainframe when in test, but they needed to actually talk to the mainframe in production. "Fortunately" for us, one of the first libraries someone wrote was an upgrade of a COM library they used in Classic ASP, called "Environment". In your code, you just called Environment.isProd or Environment.isTest, as needed.
I used those standard calls, but I didn't think too much about how they worked until I needed to test invoice sending from our test environment. You see, normally, changes to invoice processing would be quickly put in production, tested, and then reverted. But this change to invoice processing needed to be signed off on before the end of the month, but we were in the middle of month-end processing, which is when the users were hammering the system really hard to get their data in before the processing deadline.
So, I said to myself, "I mean, the Environment library must just be looking at a config flag or something, right?"
Well, sort of. You see, when any new server was provisioned, a text file would get dropped in C:\env.txt. It contained either "PROD" or "TEST". The Environment library just read that file when your application launched, and set its flags accordingly.
Given the choice of doing a quick custom build of Environment.isProd which always was true, or fighting with the ops team to get them to change the contents of the text file, I took the path of least resistance and made a custom build. Testing proceeded, and eventually, I managed to convince the organization that we should start using the built-in .NET configuration files to set our environment settings.
[Advertisement] Ensure your software is built only once and then deployed consistently across environments, by packaging your applications and components. Learn how today!