I want to catch the PostGres query results that gets executed in the remote server (passwordless-ssh) via expect command that is used to supply the password for the given PostGres user. Actually, there are two versions of our application, the older version does not require Postgres password where as the new version requires it. So the Testcase has to handle that
In older version (which does not require psql password) the cmd string to execute the query is very simple:
cmd = 'ssh ' + db_ip + ' "psql -h localhost -p 5434 -U perfmon -d network -c \\\"select count(*) from crm_customer_device_info;\\\""'
But for the new version (since password is enabled for psql), I have tried the following approaches, but timeout occurs
Approach 1: executing the query when the prompt appears
#! /usr/bin/python
import subprocess
def execute(cmd):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
_output, _error = proc.communicate()
_code = proc.returncode
return _output, _error, _code
def executeQuery(db_ip, db_user, db_name, db_pass, sql_query):
cmd = '''/usr/bin/expect -c 'spawn -noecho ssh -q {0} "psql -h localhost -p 5434 -U {1} -d {2}"
expect {{
-nocase "Password*" {{
send "{3}\r"
exp_continue
}}
"=# " {{
send "{4}"
set var $expect_out(buffer);
send "\q\n"
}}
}}
'
'''.format(db_ip, db_user, db_name, db_pass, sql_query)
return execute(cmd)
db_ip = "192.168.0.1"
db_user = "perfmon"
db_name = "network"
db_pass = "xxx"
sql_query = "select count(*) from crm_customer_device_info;"
_output, _error, return_code = executeQuery(db_ip, db_user, db_name, db_pass, sql_query)
Approach-2: executing the query using postgres -c option and handling timeout scenarios
def executeQuery(db_ip, db_user, db_name, db_pass, sql_query):
cmd = '''/usr/bin/expect -c 'spawn ssh {o} "psql -h localhost -p 5434 -U {1} -d {2} -c \\\'{4}\\\' "
expect {{
-nocase "Password*" {{
send -- "{3}\r"
exp_continue
}}
-nocase "permission denied" {{
exit 4
}}
-nocase "timed out" {{
exit 2
}}
timeout {{
exit 1
}}
}}
'
'''.format(db_ip, db_user, db_name, db_pass, sql_query)
return execute(cmd)
When I execute the below expect script directly on the server where psql is installed instead of remote ssh, then I manage to get output:
spawn -noecho psql -h localhost -p 5434 -U user -d db;
expect {
"^Password*" {
send -- "passwd\r"
exp_continue
}
"*=# " {
send -- "select now();\r\n"
set var $expect_out(buffer);
send "\\q\r\n"
exp_continue
}
}; #puts $var; #interact;