Move sql container runner into util function

This function is used to execute SQL-queries by using psql
in the postgres container.

Usage:

    from octane.util import sql

    sql_query = ...
    sql.run_psql_in_container(sql_query, container, db)

Change-Id: I180a0179f223fa59bd0a99cd90b093a153b6ddfe
This commit is contained in:
Sergey Abramov 2016-04-25 18:03:37 +03:00
parent 610b2479c3
commit b1c430528e
4 changed files with 85 additions and 46 deletions

View File

@ -27,6 +27,7 @@ from octane import magic_consts
from octane.util import docker
from octane.util import fuel_client
from octane.util import helpers
from octane.util import sql
from octane.util import subprocess
@ -122,15 +123,6 @@ class NailgunArchivator(PostgresArchivator):
finally:
docker.run_in_container("rsyslog", ["service", "rsyslog", "start"])
def _run_sql_in_container(self, sql):
sql_run_prams = [
"sudo", "-u", "postgres", "psql", "nailgun", "--tuples-only", "-c"]
results, _ = docker.run_in_container(
"postgres",
sql_run_prams + [sql],
stdout=subprocess.PIPE)
return results.strip().splitlines()
def _post_restore_action(self):
data, _ = docker.run_in_container(
"nailgun",
@ -157,19 +149,19 @@ class NailgunArchivator(PostgresArchivator):
env=self.context.get_credentials_env())
values = []
for line in self._run_sql_in_container(
"select id, generated from attributes;"):
for line in sql.run_psql_in_container(
"select id, generated from attributes;", self.db):
c_id, c_data = line.split("|", 1)
data = json.loads(c_data)
data["deployed_before"] = {"value": True}
values.append("({0}, '{1}')".format(c_id, json.dumps(data)))
if values:
self._run_sql_in_container(
sql.run_psql_in_container(
'update attributes as a set generated = b.generated '
'from (values {0}) as b(id, generated) '
'where a.id = b.id;'.format(','.join(values))
)
'where a.id = b.id;'.format(','.join(values)),
self.db)
self._create_links_on_remote_logs()

View File

@ -514,9 +514,8 @@ def test_post_restore_nailgun(mocker, mock_open, dump, calls, data_for_update):
mock_subprocess_call = mocker.patch("octane.util.subprocess.call")
run_in_container_mock = mocker.patch(
"octane.util.docker.run_in_container", return_value=(data, None))
run_sql_mock = mocker.patch.object(
postgres.NailgunArchivator,
"_run_sql_in_container",
run_sql_mock = mocker.patch(
"octane.util.sql.run_psql_in_container",
return_value=[data_for_update]
)
json_mock = mocker.patch("json.dumps")
@ -557,7 +556,7 @@ def test_post_restore_nailgun(mocker, mock_open, dump, calls, data_for_update):
json_mock.assert_called_with({"deployed_before": {"value": True}})
mock_links.assert_called_once_with()
run_sql_mock.assert_has_calls([
mock.call("select id, generated from attributes;"),
mock.call("select id, generated from attributes;", "nailgun"),
])
@ -650,31 +649,3 @@ def test_create_links_on_remote_logs(
assert [mock.call("rsyslog", ["service", "rsyslog", "stop"]),
mock.call("rsyslog", ["service", "rsyslog", "start"])] == \
run_in_container_mock.call_args_list
@pytest.mark.parametrize("sql_raw, result_data", [
("row_1|val_1\nrow_2|val_1\n", ["row_1|val_1", "row_2|val_1"]),
("", [])
])
def test_run_sql(mocker, sql_raw, result_data):
archivator = postgres.NailgunArchivator(None)
run_mock = mocker.patch(
"octane.util.docker.run_in_container",
return_value=(sql_raw, None))
test_sql = "test_sql"
results = archivator._run_sql_in_container(test_sql)
run_mock.assert_called_once_with(
"postgres",
[
"sudo",
"-u",
"postgres",
"psql",
"nailgun",
"--tuples-only",
"-c",
test_sql,
],
stdout=subprocess.PIPE
)
assert result_data == results

View File

@ -0,0 +1,44 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import pytest
from octane.util import sql
from octane.util import subprocess
@pytest.mark.parametrize("sql_raw, result_data", [
("row_1|val_1\nrow_2|val_1\n", ["row_1|val_1", "row_2|val_1"]),
("", [])
])
@pytest.mark.parametrize("db", ["nailgun", "keystone"])
def test_run_sql(mocker, sql_raw, result_data, db):
run_mock = mocker.patch(
"octane.util.docker.run_in_container",
return_value=(sql_raw, None))
test_sql = "test_sql"
results = sql.run_psql_in_container(test_sql, db)
run_mock.assert_called_once_with(
"postgres",
[
"sudo",
"-u",
"postgres",
"psql",
db,
"--tuples-only",
"--no-align",
"-c",
test_sql,
],
stdout=subprocess.PIPE
)
assert result_data == results

32
octane/util/sql.py Normal file
View File

@ -0,0 +1,32 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from octane.util import docker
from octane.util import subprocess
def run_psql_in_container(sql, db):
results, _ = docker.run_in_container(
"postgres",
[
"sudo",
"-u",
"postgres",
"psql",
db,
"--tuples-only",
"--no-align",
"-c",
sql,
],
stdout=subprocess.PIPE)
return results.strip().splitlines()