PostgreSQL: How can I create a temporary user and database for my unit tests? - c++

I'm developing a C++ web application and I'm using PostgreSQL with libpqxx, on Ubuntu 16.04. The issue I'm having is that I need a portable (over Linux systems) way to run my unit tests.
What I have now is a class that controls database calls. I'd like to test how this class acts under my unit tests. For that, for every time I run a unit test, I'd like to:
Create a temp user
Create a dummy db
run my tests on it
delete the db
delete the user
Now doing the steps is fine with Google tests. I can create a fixture that will do them all reproducibly. BUT...
How can I create a user with a password in one call (without being prompted for the password), so that I can create that user on the go and run my tests?
The manual doesn't seem to provide a way to provide the password in an argument. I was hoping to do something like this:
system("createuser " + username + " -password abcdefg");
where system() runs a terminal command. Then I can connect to the DB server with that username and password to do my unit tests.
Another failed attempt for me was to pass an sql query that would create the user through the terminal:
system("psql -c \"CREATE ROLE joe PASSWORD 'aabbccdd';\"")
When I do this, I get the error:
psql: FATAL: database "user" does not exist
where user is my unix username.
Remember that I cannot connect to the server with libpqxx because I don't have credentials yet (as the temporary user). Right? Please correct me if I'm wrong.
Is there any way to do what I'm planning here and make unit-tests runnable without user intervention?

The problem with the system("psql -c \"CREATE ROLE joe PASSWORD 'aabbccdd';\"") call is that it doesn't specify a database to connect to which will then default to trying a database of the same name as the user logging in. Try adding -d postgres and see if it works.
Please note that this only creates the user, it doesn't create any database or give privileges to anything.

Related

APEX_ADMINISTRATOR_ROLE in AWS RDS Oracle Instance

I am trying to install APEX on my AWS Oracle 12 RDS Instance. In order to achieve this, I am following these instructions : http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.APEX.HTML
However, I got stucked in step 7:
Step 7:
You must set a password for the APEX admin user. To do this, use
SQL*Plus to connect to your DB instance as the master user, and then
issue the following commands:
grant APEX_ADMINISTRATOR_ROLE to master;
#/home/apexuser/apex/apxchpwd.sql
Replace master with your master user name. When the apxchpwd.sql
script prompts you, type a new admin password
When I log into my my RDS Instance with my master user and execute this:
grant APEX_ADMINISTRATOR_ROLE to [mymasteruser];
I received this error:
ERROR at line 1:
ORA-01924: role 'APEX_ADMINISTRATOR_ROLE' not granted or does not exist
Can you please help me to solve this?
Edit 12/09/2017.
Using this post/answer:
https://serverfault.com/questions/276541/how-do-you-recover-you-rds-master-user-username
I understand my master user is shown in the following image. As I know, in RDS instance i have no access to sys or system user, so this is the only user i can use.
Many thanks
Edit 20/09/2017.
I applied Alex solution, and it works!!. However, some issues to comment:
The tutorial was changed, in fact the url changed, now is
http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.APEX.html (the last "html" was in uppercase before)
but is not reliable now, there are some points that should be fixed, e.g. it says now that RDS support Oracle APEX version 5.1.2, i tried with this versión and I got this error:
Also, some directories dont match with the previos step ....
So, I used the versión that the tutorial originally says : Oracle APEX version 4.2.6.v1
I had to execute both statements :
EXEC rdsadmin.rdsadmin_util.grant_apex_admin_role;
grant APEX_ADMINISTRATOR_ROLE to [master];
Then i could execute the apxchpwd.sql script successfully!!.
But, unfortunately, when I accessed to my apex home page and tried to create a new workspace "ws_prueba", I receive this error (Im trying to create it with my apex admin user):
Any ideas?
Use
EXEC rdsadmin.rdsadmin_util.grant_apex_admin_role;
instead. I have a case open on this with AWS and just asked them to update the documentation page.

Django admin how unlock your own account?

In Django admin I have by mistake locked myself by attempting the wrong password.
I later of deleted the user and created another one using manage.py createsuperuser. However, it still says that I'm locked. How do I unlock myself?
It gives the following error when I try to log in using Django admin..
Account locked: too many login attempts. Contact an admin to unlock your account.
Given your error message and 3 strike policy, I assume you have django-axes in your project. You may have it configured to block by IP, regardless of user. That would explain why creating a new user did not work.
Djang-axes documentation gives you an outline of how to clear lockouts.
manage.py axes_reset will reset all lockouts and access records.
If you are currently in production and do not want to risk resetting any valid lockouts, you could try resetting for just your ip
manage.py axes_reset ip will clear lockout/records for ip
So, for example on if you are logged in on the same computer your server is on, you can use localhost:
manage.py axes_reset ip 127.0.0.1
If for some reason that doesn't work, you still have the option of manually deleting your AccessAttempt from your database. This assumes, of course, that you have access to your database, that your user has delete privileges, you are comfortable with sql, and you have not changed the default table name from django-axes.
delete from axes_accessattempt where username ='your_username'; where 'your_username' is the account you wish to unlock.
This can also by done by ip:
delete from axes_accessattempt where ip_address='your_ip'; where 'your_ip' is the ip address from the computer you are using.
Resetting attempts from command line:
python manage.py axes_reset
will reset all lockouts and access records.
python manage.py axes_reset_ip [ip ...]
will clear lockouts and records for the given IP addresses.
python manage.py axes_reset_username [username ...]
will clear lockouts and records for the given usernames.
python manage.py axes_reset_logs (age)
will reset (i.e. delete) AccessLog records that are older than the given age where the default is 30 days.
Yep here's how I did it.. Go to the shell using python manage.py shell
There enter the following commands
from axes.models import AccessAttempt
AccessAttempt.objects.all().delete()
If however the data is needed you must then delete only the object containing your username by
for obj in AccessAttempt.objects.all():
if obj.username == your_username:
obj.delete()

Rails 4: run migrations as separate DB user

The situation I have is our normal Rails DB user has full ownership in order to run migrations.
However, we use a shared DB for development, so we can't run "destructive" DB tasks against the development DB, such as rake db:drop/reset/etc....
My thought is to create 2 DB users:
rails-service
rails-migrator
The service user is the "normal" web app user that connects to the DB when the app is live. This DB user would only have standard CRUD privileges but no dropping rights.
The migrator user is the "admin" user that is only used for running migrations. This DB user would have normal "full" access to the DB such that it "could" drop the DB if that command were executed.
Question: Is there a clean way to tell Rails migrations to run as the rails-migrator user? I'm not sure how I would accomplish this aside from somehow altering the connection strings for every rails migration file, which seems like a bad idea.
In tandem with the above, I'm going to "delete" the destructive rake tasks so that a developer can't even run them.
# lib/tasks/db.rake
# See: https://coderwall.com/p/jt4e1q/disable-destructive-rake-tasks-by-environment
tasks = Rake.application.instance_variable_get '#tasks'
tasks.delete 'db:reset'
tasks.delete 'db:drop'
namespace :db do
desc 'db:reset not available in this environment'
task :reset do
puts 'db:reset has been disabled'
end
desc 'db:drop not available in this environment'
task :drop do
puts 'db:drop has been disabled'
end
end
I refer you to the answer of Matthew Rudy Jacobs from 2007 (!) https://www.ruby-forum.com/topic/123618
Lucky enough it works also now :)
I just changed DEFINED? and the rest to ENV['AS_DB_ADMIN'] and used it to separate migration access to another user.
On migration I used
set :default_env, { as_db_admin: true }

How do you use inspectdb in Django?

I am just starting with Django, and I would like to make an app that uses my existing sqlite db.
I read the docs and I found that you can create models from a db, using inspectdb; altho I can't find an example of how you use that command, on an existing db.
I copied the db file inside the directory of my project, ran the command and I see that a sqlite3 file is created in my directory project.
Altho the file has nothing to do with the database that I made. I tried to pass the db name to the inspectdb command but it says that it doesn't accept parameters.
So how can I actually tell the command to use my db to create the model for my app?
There must be some obvious step that I am missing...this is what I did:
-created the project
-created the app
-copied my db inside the project folder
-ran inspectdb
But I see the model empty, and a new db called db.sqlite3 created
Found the answer: there is a variable that has to be set, to define which one is the db that the application will use. the default is set to "db.sqlite3", which explain why I am getting this behavior.
Once you modify the name with the database that I already made, the command run without issues.
Not sure if it is just me getting stomped, but this info about the name that has to be changed was not mentioned anywhere...
Thanks

Codeception - HTML report generation seems slow?

I am using Codeception to run three acceptance tests which basically are as follows:-
Check the email address 'admin#admin.com' exists
Create a new user account
Login to the website
Obviously this requires the database so I have added 'Db' to the list of modules in the acceptance.suite.yml, however the generation of the report takes sometime, is this normal or do I have something wrong with my setup?
Below is the report (and time taken for each according to the html file it is generating)
check admin#admin.com account exists (AdminCept.php) (0.01s)
create new user account (CreateUserCept.php) (19.1s)
log in to the website (LoginCept.php) (21.72s)
Approx 40 seconds in total (although the command line states 1:02 - I guess as it replaces the mock database dump.sql back into the database as well)
Can anybody shed any light on the matter?
Not really an answer but closing this off - simply put the report generation takes time.