C++ routine to delete data from database - googletest

Is there a mechanism in googletest framework that allows the test to clear the data even after a test fails (The code throws an exception and stops further execution (of clearing the data) if a test fails.
Thanks!

Run the tests on a temporary, in-memory database.

Since SQLite operates from a single file, you can use SetUp() in a test fixture to copy a pre configured database file to where your program expects the database to be, overwriting the "runtime" database file with the pre configured one before every test.
That way every test gets a completely fresh database, initialized with all tables and possibly base data of your choice without running any database creation scripts. That should keep test runs speedy.

Related

How to automate source control with Oracle database

I work in an Oracle instance that has hundreds of schemas and multiple developers. We have a development instance where developers can integrate their work before test or production.
We want to have source control for all the DDL run in this integrated development database. Currently this is done through a product Red Gate which we run manually after we make a change to the database. Redgate finds the changes between what is in the schema and what was last checked into source control and makes a script of the differences and puts this into source control.
The problem however is of course that running regdate can take some time and people run it infrequently or not at all for small changes. Also redgate will only look in one schema at a time and it would be VERY time consuming to manually run it against all schemas to guarantee that they are up to date. However if the source controlled code cannot be relied upon it becomes less useful...
What would seem to be ideal would be to have some software that could periodically (even once a day), or when triggered by DDL being run, update the source control (preferably github as this is used by other teams) from all the schemas.
I cannot seem to see any existing software which can be simply used to do this.
Is there a problem with doing this? (there is no need to address multiple developers overwriting each others work on the same day as we have this covered in a separate process) Is anyone doing this? Can anyone recommend a way to do this?
We do this with help of a PL/SQL function, a python script and a shell script:
The PL/SQL function can generate the DDL of a whole schema and returns this as CLOB
The python script connects to the database, fetches the DDL and stores it in files
The shell script runs the Source Control to add the modifications (we use Bazaar here).
You can see the scripts on PasteBin:
The PL/SQL function is here: http://pastebin.com/AG2Fa9zL
The python program (schema_exporter.py): http://pastebin.com/nd8Lf0gK
The shell script:
The shell script:
python schema_exporter.py
d=$(date +%Y-%m-%d__%H_%M_%S)
bzr add
bzr st | grep -q -E 'added|modified' && commit -m "Database objects on $d"
exit 0
This shell script is configured to run from cron every day.
Being in the database version control space for 5 years (as director of product management at DBmaestro) and having worked as a DBA for over two decades, I can tell you the simple fact that you cannot treat the database objects as you treat your Java, C# or other files and save the changes in simple DDL scripts.
There are many reasons and I'll name a few:
Files are stored locally on the developer’s PC and the change s/he
makes do not affect other developers. Likewise, the developer is not
affected by changes made by her colleague. In database this is
(usually) not the case and developers share the same database
environment, so any change that were committed to the database affect
others.
Publishing code changes is done using the Check-In / Submit Changes /
etc. (depending on which source control tool you use). At that point,
the code from the local directory of the developer is inserted into
the source control repository. Developer who wants to get the latest
code need to request it from the source control tool. In database the
change already exists and impacts other data even if it was not
checked-in into the repository.
During the file check-in, the source control tool performs a conflict
check to see if the same file was modified and checked-in by another
developer during the time you modified your local copy. Again there
is no check for this in the database. If you alter a procedure from
your local PC and at the same time I modify the same procedure with
code form my local PC then we override each other’s changes.
The build process of code is done by getting the label / latest
version of the code to an empty directory and then perform a build –
compile. The output are binaries in which we copy & replace the
existing. We don't care what was before. In database we cannot
recreate the database as we need to maintain the data! Also the
deployment executes SQL scripts which were generated in the build
process.
When executing the SQL scripts (with the DDL, DCL, DML (for static
content) commands) you assume the current structure of the
environment match the structure when you create the scripts. If not,
then your scripts can fail as you are trying to add new column which
already exists.
Treating SQL scripts as code and manually generating them will cause
syntax errors, database dependencies errors, scripts that are not
reusable which complicate the task of developing, maintaining,
testing those scripts. In addition, those scripts may run on an
environment which is different from the one you though it would run
on.
Sometimes the script in the version control repository does not match
the structure of the object that was tested and then errors will
happen in production!
There are many more, but I think you got the picture.
What I found that works is the following:
Use an enforced version control system that enforces
check-out/check-in operations on the database objects. This will
make sure the version control repository matches the code that was
checked-in as it reads the metadata of the object in the check-in
operation and not as a separated step done manually. This also allow
several developers to work in parallel on the same database while
preventing them to accidently override each other code.
Use an impact analysis that utilize baselines as part of the
comparison to identify conflicts and identify if a difference (when
comparing the object's structure between the source control
repository and the database) is a real change that origin from
development or a difference that was origin from a different path and
then it should be skipped, such as different branch or an emergency
fix.
Use a solution that knows how to perform Impact Analysis for many
schemas at once, using UI or using API in order to eventually
automate the build & deploy process.
An article I wrote on this was published here, you are welcome to read it.
To me it seems like your way of working is backwards: developers run DDL against the DB in an unordered fashion and then you need an automated tool for inferring the changes (and the DDL) that was run.
The process would be in better control if you did the following instead:
Developers write DDL as SQL scripts, preferably using a migration tool such as Flyway (http://flywaydb.org/documentation/migration/sql.html).
Migration scripts are checked into version control
Migration scripts are periodically run against the DB (e.g. by the migration tool)
In this workflow, the DB would only get altered through automated migration scripts and no-one is allowed to do changes manually. Could this work for you?
(I develop the Oracle tools for Redgate)
Actually using the tools you can already what I think you're asking for using Schema Compare for Oracle.
You can compare multiple schemas either in the UI or via the command line - I think what you're after is automating the command line tool which can create difference scripts, sync between source and destination (live, snapshot or scripts) and generate reports.
You can automate the command line to sync to a scripts folder which is your source code checkout and then subsequently run a command to commit the changes.
I think that's all good :)
We built a commerical tool that bridges Oracle with Git. It helps you manage your database objects with Git. Basically, the database becomes the working directory for the developer. You can perform git operations in the database such as reset, commit, branch, merge etc... and the database code is updated automatically. It might be worth taking a look: https://www.gitora.com

Resetting the DB after each test run

I have following problem:
I have a DB pre-filled with lot of test data. After each test run I would like to throw away changes made by the test procedure. I already tried to do this with an embedded H2 DB. I would just overwrite the DB files with the original ones and the problem would be solved. But another problem emerged: H2 doesn't support multi-threading without running as a server.
After that I looked at HSQLDB. If I understand it correctly, if it is used as normal file DB (not in-memory) it will still load the contents of the DB into the memory and persist the changed to disk after some time.
Is there any possibility to just read the file DB into memory, use it there and throw away any changes at the end? This would be perfect. A solution using rollbacks would be great too.
Thanks,
Daniel
For the H2 database:
To load a database from script, append ;INIT=runscript from '~/create.sql' to the database URL. You could also load the script from a resource in the classpath; for this replace ~/create.sql with classpath:/com/acme/init/create.sql. You can use that in combination of an in-memory database (jdbc:h2:mem:test;...) if you are not interested about the changes.
To use the H2 database in multi-threaded mode, append ;MULTI_THREADED=1 to the database URL. This applies to all modes (in-memory, embedded, client/server).
HSQLDB has an option for this usage.
After creating the test database, perform SHUTDOWN. You will have a .properties and .script files. In the .properties file add this line:
files_readonly=true
Then use this database for the tests. No rollback or any special action will be necessary when the app exits.
Alternatively, append this to your test application's connection URL, ;files_readonly=true
See this Chapter of the Guide:
http://www.hsqldb.org/doc/2.0/guide/dbproperties-chapt.html#dpc_db_file_mem
For multi-threaded application testing, the database transaction model is usually MVCC, which you set in the original database.

Make tests dependent and fail together in googletest?

In googletest, is there a way to make tests dependent on each other? I have one test (a database connection) for which if it fails, it doesn't make sense to run certain other tests (that use the DB). I'd like to make those dependent tests fail fast without executing.
I could put the assertion of the DB connection test into a test fixture, but since a new fixture object is constructed for every test, it will run a lot of times unnecessarily. Is there an elegant way to make all the DB using tests fail together?
You could use a googletest Environment to create the DB connection.
Or I guess you could set a global boolean when the test successfully makes the DB connection, and which is checked at the start of every other test.

Entity Framework Code First - Tests Overlapping Each Other

My integration tests are use a live DB that's generated using the EF initalizers. When I run the tests individually they run as expected. However when I run them all at once, I get a lot of failed tests.
I appear to have some overlapping going on. For example, I have two tests that use the same setup method. This setup method builds & populates the DB. Both tests perform the same test ACT which adds a handful of items to the DB (the same items), but what's unique is each test is looking for different calculations (instead of one big test that does a lot of things).
One way I could solve this is to do some trickery in the setup that creates a unique DB for each test that's run, that way everything stays isolated. However the EF initilization stuff isn't working when I do that because it is creating a new DB rather than dropping & replacing it iwth a new one (the latter triggers the seeding).
Ideas on how to address this? Seems like an organization of my tests... just not show how to best go about it and was looking for input. Really don't want to have to manually run each test.
Use test setup and tear down methods provided by your test framework and start transaction in test setup and rollback the transaction in test tear down (example for NUnit). You can even put setup and tear down method to the base class for all tests and each test will after that run in its own transaction which will rollback at the end of the test and put the database to its initial state.
Next to what Ladislav mentioned you can also use what's called a Delta Assertion.
For example, suppose you test adding a new Order to the SUT.
You could create a test that Asserts that there is exactly 1 Order in the database at the end of the test.
But you can also create a Delta Assertion by first checking how many Orders there are in the database at the start of the test method. Then after adding an Order to the SUT you test that there are NumberOfOrdersAtStart + 1 in the database.

SQL script initializing a database for the first time

I am writing Web app. My program creates relations itself when it is needed, basically when the program is deployed and run first time. But I see that it is very common to create SQL script and run it to initialize data-base for the first time. Is it compulsory to do this?
No, it is not compulsory for the database initialization script to be part of the "first run" of your application; preparing the database can be a deployment step. In fact, depending how long it takes to initialize the database, you might specifically want to avoid initializing the database on the first run, and instead make sure it is deployed and initialized before the first time the application is accessed.