Development only code
Occasionally I need to do development stuff things that are potentially destructive.
The ResetDatabase action will blow away the database, which I need to do for tests and when I am making big changes. But what I absolutely does not want is to have in production.
My method is to require three different things to be true to enable this:
- You must issue a local request (so you are physically on the machine where the system is sitting).
- You are logged on as a user and as an administrator (that is the superAdmin part).
- You are running on a debug build.
Hopefully, I won’t blow the production database.
Comments
I would never dare to do such considering our current process ( label/tag / documents up to date, yet the integration team didn't use the right files...).
I like the idea here, although I'm a bit confused as to why you're using a controller action to drop and recreate the db. Normally I would do that via some sort of script... I guess doing it your way adds some extra protection against dropping the production db, but at the cost of less scriptable dev and qa deployments.
Regardless, I like the idea of checking for a debug build before doing certain tasks.
Like unit tests, I like to keep this sort of thing in a module that is never deployed to production.
We do something similar so that our automated (selenium) tests can reset the database to a known state at will. The code that does the reset is hosted in a separate assembly that is not deployed to production.
I never do that because I don't deploy the test project where such kind of things happens.
I'd usually keep the Drop Database/Drop tables as a commented out script so in order to do it I need to open the file, uncomment, and run it. That way it's completely impossible to accidentally do that in production.
Of course, the commands to fix the database once it's dropped can be in a controller, assuming they're non-destructive. I usually work in WinForms now, so I'd make it a command that only works fixes an invalid state - I'd cause the invalid state manually for super protection.
Some time ago I've been doing some experimental changes to a test database before deploying it to production server. And I had two remote desktops open - one for test server and one for production. While overwriting some data I realized I'm in the wrong desktop, accidentally I have run some update on production. Spent rest of the night and half of next day cleaning up the mess. From that time all production server desktops have red background and test server desktops have green background (and I don't usually log on to test & production at the same time)
I do this using a "provisioning page", neatly titled provision.aspx. It exports the schema using NH and sticks default data in. I use a GUID to unlock the page, which much match the one in the web.config. There is a big ugly button which says "export schema" and a big label which displays the host name of the machine.
The main benefit is that when it has been provisioned, the provision.aspx file can be removed and there is no way to run the code at all.
I rarely update a schema so I haven't found the need to write some upgrade/migration scripts into it all.
This has been used to shift 5 products in the dev environment and in production now without any problems.
@configurator
What if you forget to comment it back?
Assuming one additional assertion:
That your development environment is physically unable to be connected to a production database.
Stuff like that has stung me in the past where to analyse a production system we could hook the dev environment in to production data. (Small company, no $ to set up more than bare-bones test environments.) If you can configure a connection string from a dev/testing environment to the production database then you'll probably want to consider that. Not that anyone would purposefully run that if testing against production, but what about when they forget to set it back.
I'd consider also asserting the connection settings against known test environment addresses/hosts.
Ha, I did that once, that wasn't a fun day....
And I had all those same constraints on that controller. Never underestimate the power of stupidity.
Is there any good link how to test against database? Sample?
No google answer please. I did.
Thanks.
This is very very very dangerous! My personal advice, remove it ASAP!
First of all, that's a very huge risk for a little convenience. A lot can go wrong. And secondly, even if the development-behavior is not critical, you are basically cheating your behavior by putting it into an ideal state instead of actual scenarios. If you're going to fake something, fake the collaborators/dependencies and not your actual system under test.
I would suggest you move that to a script somewhere. Also, I would highly advice that the db user you're going to be using does not have the permission to run such actions against your production database.
Lastly, I would suggest you do a bit of Unit Testing. Your unit tests would show you your unnecessary dependencies, forcing you to decouple them making it easier for testing (automated or manual).
There are several ways:
First, if you can decouple your code from the database - do so. It will make your testing easier & faster...not to mention you will have distinct separation of concerns (i.e. from business logic to datasource acess).
Secondly, if you're working on your actual database unit, there are several options you can choose from in terms of your setup-teardown:
Where to do setup-teardown:
a.) Before and after each tests,
b.) Before and after each group of tests (i.e. unit test suite, integration test modules, etc)
How to teardown
a.) You drop table/database and recreate (making sure that all data are deleted) with initial fixtures (safe but slow),
b.) You delete data that was inserted (this is hard to track. faster than a but less safe)
c.) Rollback (fastest way to teardown but hinders you from testing db units which does commits)
Also, if you're going to be doing database testing that inserts/updates data, I highly recommend you do it against a database you own / control. Doing it on a shared database (i.e. in your intra ) runs the risk of corrupting other people's data.
@Franz
A project I work on has unittests where the setup method drops and recreates the database. They run pretty quickly: 364 tests in 22 seconds. For most people, there's no need to worry about speeding up tests.
I personally prefer to use permissions, standard developer accounts cannot write to the production database.
The production web service doesn't have permission to alter the database structure, only manipulate the data in it.
Obviously this is an extra line of defense as I've found it to be better to not try and drop the production database in the first place.
Comment preview