mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fix syntax error when creating new pgAgent schedules with a start
date/time and exception. Fixes #3638 - Fixed syntax error. - Update/Delete exceptions are not working, SQL is wrong. - Wrong exception time is shown, it should shown in UTC as datatype of the column is timestamp with out timezone. - Added test cases for Schedule and Steps of pgAgent Job.
This commit is contained in:
parent
6fa6939f52
commit
50738db2b8
@ -151,8 +151,8 @@ define('pgadmin.node.pga_schedule', [
|
|||||||
options: {format: 'HH:mm', buttons: {
|
options: {format: 'HH:mm', buttons: {
|
||||||
showToday: false,
|
showToday: false,
|
||||||
}}, displayFormat: 'HH:mm',
|
}}, displayFormat: 'HH:mm',
|
||||||
modelFormat: 'HH:mm:ss', displayInUTC: false, allowEmpty: true,
|
modelFormat: 'HH:mm:ss', displayInUTC: true, allowEmpty: true,
|
||||||
cellHeaderClasses:'width_percent_50', modalInUTC: false,
|
cellHeaderClasses:'width_percent_50', modalInUTC: true,
|
||||||
}],
|
}],
|
||||||
validate: function() {
|
validate: function() {
|
||||||
var self = this, exceptions = this.collection,
|
var self = this, exceptions = this.collection,
|
||||||
@ -356,7 +356,7 @@ define('pgadmin.node.pga_schedule', [
|
|||||||
}),
|
}),
|
||||||
schema:[{
|
schema:[{
|
||||||
id: 'jscweekdays', label: gettext('Week Days'), cell: 'select2',
|
id: 'jscweekdays', label: gettext('Week Days'), cell: 'select2',
|
||||||
group: gettext('Days'), control: 'select2',
|
group: gettext('Days'), control: 'select2', type: 'array',
|
||||||
select2: {
|
select2: {
|
||||||
first_empty: false,
|
first_empty: false,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
@ -372,7 +372,7 @@ define('pgadmin.node.pga_schedule', [
|
|||||||
options: BooleanArrayOptions,
|
options: BooleanArrayOptions,
|
||||||
},{
|
},{
|
||||||
id: 'jscmonthdays', label: gettext('Month Days'), cell: 'select2',
|
id: 'jscmonthdays', label: gettext('Month Days'), cell: 'select2',
|
||||||
group: gettext('Days'), control: 'select2',
|
group: gettext('Days'), control: 'select2', type: 'array',
|
||||||
select2: {
|
select2: {
|
||||||
first_empty: false,
|
first_empty: false,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
@ -387,7 +387,7 @@ define('pgadmin.node.pga_schedule', [
|
|||||||
selector: monthdays, options: BooleanArrayOptions,
|
selector: monthdays, options: BooleanArrayOptions,
|
||||||
},{
|
},{
|
||||||
id: 'jscmonths', label: gettext('Months'), cell: 'select2',
|
id: 'jscmonths', label: gettext('Months'), cell: 'select2',
|
||||||
group: gettext('Days'), control: 'select2',
|
group: gettext('Days'), control: 'select2', type: 'array',
|
||||||
select2: {
|
select2: {
|
||||||
first_empty: false,
|
first_empty: false,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
@ -406,7 +406,7 @@ define('pgadmin.node.pga_schedule', [
|
|||||||
group: gettext('Repeat'), mode: ['create', 'edit'],
|
group: gettext('Repeat'), mode: ['create', 'edit'],
|
||||||
schema:[{
|
schema:[{
|
||||||
id: 'jschours', label: gettext('Hours'), cell: 'select2',
|
id: 'jschours', label: gettext('Hours'), cell: 'select2',
|
||||||
group: gettext('Times'), control: 'select2',
|
group: gettext('Times'), control: 'select2', type: 'array',
|
||||||
select2: {
|
select2: {
|
||||||
first_empty: false,
|
first_empty: false,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
@ -421,7 +421,7 @@ define('pgadmin.node.pga_schedule', [
|
|||||||
selector: hours, options: BooleanArrayOptions,
|
selector: hours, options: BooleanArrayOptions,
|
||||||
},{
|
},{
|
||||||
id: 'jscminutes', label: gettext('Minutes'), cell: 'select2',
|
id: 'jscminutes', label: gettext('Minutes'), cell: 'select2',
|
||||||
group: gettext('Times'), control: 'select2',
|
group: gettext('Times'), control: 'select2', type: 'array',
|
||||||
select2: {
|
select2: {
|
||||||
first_empty: false,
|
first_empty: false,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
@ -7,18 +7,18 @@
|
|||||||
INSERT INTO pgagent.pga_exception (
|
INSERT INTO pgagent.pga_exception (
|
||||||
jexscid, jexdate, jextime
|
jexscid, jexdate, jextime
|
||||||
) VALUES (
|
) VALUES (
|
||||||
{% if jscid %}{{ jscid|qtLiteral }}{% else %}scid{% endif %}, {% if data.jexdate %}to_date({{ data.jexdate|qtLiteral }}, 'MM/DD/YYYY')::date{% else %}NULL::date{% endif %}, {% if data.jextime %}{{ data.jextime|qtLiteral }}::time without time zone{% else %}NULL::time without time zone{% endif %}
|
{% if jscid %}{{ jscid|qtLiteral }}{% else %}scid{% endif %}, {% if data.jexdate %}to_date({{ data.jexdate|qtLiteral }}, 'YYYY-MM-DD')::date{% else %}NULL::date{% endif %}, {% if data.jextime %}{{ data.jextime|qtLiteral }}::time without time zone{% else %}NULL::time without time zone{% endif %}
|
||||||
|
|
||||||
);
|
);
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
{% macro UPDATE(jscid, data) -%}
|
{% macro UPDATE(jscid, data) -%}
|
||||||
-- Updating an existing schedule exception (id: {{ data.jexid|qtLiteral }}, schedule: {{ jscid|qtLiteral }})
|
-- Updating an existing schedule exception (id: {{ data.jexid|qtLiteral }}, schedule: {{ jscid|qtLiteral }})
|
||||||
UPDATE pgagent.pga_exception SET
|
UPDATE pgagent.pga_exception SET
|
||||||
{% if 'jexdate' in data %}jexdate={% if data.jexdate %}to_date({{ data.jexdate|qtLiteral }}, 'MM/DD/YYYY')::date{% else %}NULL::date{% endif %}{% endif %}{% if 'jextime' in data%}{% if 'jexdate' in data %}, {% endif %}jextime={% if data.jextime %}{{ data.jextime|qtLiteral }}::time without time zone{% else %}NULL::time without time zone{% endif %}{% endif %}
|
{% if 'jexdate' in data %}jexdate={% if data.jexdate %}to_date({{ data.jexdate|qtLiteral }}, 'YYYY-MM-DD')::date{% else %}NULL::date{% endif %}{% endif %}{% if 'jextime' in data%}{% if 'jexdate' in data %}, {% endif %}jextime={% if data.jextime %}{{ data.jextime|qtLiteral }}::time without time zone{% else %}NULL::time without time zone{% endif %}{% endif %}
|
||||||
|
|
||||||
WHERE jexid={{ data.jexid|qtLiteral }}::integer AND jscid={{ jscid|qtLiteral }}::integer;
|
WHERE jexid={{ data.jexid|qtLiteral }}::integer AND jexscid={{ jscid|qtLiteral }}::integer;
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
{% macro DELETE(jscid, data) -%}
|
{% macro DELETE(jscid, data) -%}
|
||||||
-- Deleting a schedule exception (id: {{ data.jexid|qtLiteral }}, schedule: {{ jscid|qtLiteral }})
|
-- Deleting a schedule exception (id: {{ data.jexid|qtLiteral }}, schedule: {{ jscid|qtLiteral }})
|
||||||
DELETE FROM pgagent.pga_exception WHERE jexid={{ data.jexid|qtLiteral }}::integer AND jscid={{ jscid|qtLiteral }}::integer;
|
DELETE FROM pgagent.pga_exception WHERE jexid={{ data.jexid|qtLiteral }}::integer AND jexscid={{ jscid|qtLiteral }}::integer;
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
@ -23,7 +23,7 @@ INSERT INTO pgagent.pga_schedule(
|
|||||||
{{ data.jscmonthdays|qtLiteral }}::boolean[],
|
{{ data.jscmonthdays|qtLiteral }}::boolean[],
|
||||||
-- Months
|
-- Months
|
||||||
{{ data.jscmonths|qtLiteral }}::boolean[]
|
{{ data.jscmonths|qtLiteral }}::boolean[]
|
||||||
) RETURNING jscid {% if not jid %}INTO scid;{% endif %}{% if 'jscexceptions' in data %}
|
) RETURNING jscid INTO scid;{% if 'jscexceptions' in data %}
|
||||||
{% for exc in data.jscexceptions %}
|
{% for exc in data.jscexceptions %}
|
||||||
|
|
||||||
{{ EXCEPTIONS.INSERT(None, exc) }}{% endfor %}{% endif %}
|
{{ EXCEPTIONS.INSERT(None, exc) }}{% endfor %}{% endif %}
|
||||||
|
@ -1,2 +1,8 @@
|
|||||||
{% import 'macros/pga_schedule.macros' as SCHEDULE %}
|
{% import 'macros/pga_schedule.macros' as SCHEDULE %}
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
scid integer;
|
||||||
|
BEGIN
|
||||||
{{ SCHEDULE.INSERT(jid, data) }}
|
{{ SCHEDULE.INSERT(jid, data) }}
|
||||||
|
END
|
||||||
|
$$;
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
import uuid
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as pgagent_utils
|
||||||
|
|
||||||
|
|
||||||
|
class PgAgentAddScheduleTestCase(BaseTestGenerator):
|
||||||
|
"""This class will test the add schedule in the pgAgent job API"""
|
||||||
|
scenarios = [
|
||||||
|
('Create schedule with exception in pgAgent job', dict(
|
||||||
|
url='/browser/pga_schedule/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
flag, msg = pgagent_utils.is_valid_server_to_run_pgagent(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
flag, msg = pgagent_utils.is_pgagent_installed_on_server(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
name = "test_job_get%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.job_id = pgagent_utils.create_pgagent_job(self, name)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
# Check and Delete entry for pga_exception table for the above
|
||||||
|
# date and time as no primary key is defined for pga_exception table
|
||||||
|
# and there is a unique constraint for date and time. So when we run
|
||||||
|
# the test cases multiple time then it will fail with unique
|
||||||
|
# constraint error.
|
||||||
|
jexdate = '2050-01-01'
|
||||||
|
jextime = '12:00:00'
|
||||||
|
pgagent_utils.delete_pgagent_exception(self, jexdate, jextime)
|
||||||
|
|
||||||
|
self.pgagent_schedule_name = "test_sch_add%s" % str(uuid.uuid4())[1:8]
|
||||||
|
data = {
|
||||||
|
'jscjobid': self.job_id,
|
||||||
|
'jscenabled': True,
|
||||||
|
'jscdesc': '',
|
||||||
|
'jscname': self.pgagent_schedule_name,
|
||||||
|
'jscexceptions': [{'jexdate': jexdate,
|
||||||
|
'jextime': jextime}],
|
||||||
|
'jscstart': '2050-01-01 12:14:21 +05:30',
|
||||||
|
'jscend': '2050-03-01 12:14:21 +05:30',
|
||||||
|
'jscminutes': [False] * 60,
|
||||||
|
'jscweekdays': [True] * 7,
|
||||||
|
'jscmonthdays': [True] * 32,
|
||||||
|
'jschours': [False] * 24,
|
||||||
|
'jscmonths': [True] * 12
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.tester.post(
|
||||||
|
'{0}{1}/{2}/{3}/'.format(
|
||||||
|
self.url, str(utils.SERVER_GROUP), str(self.server_id),
|
||||||
|
str(self.job_id)
|
||||||
|
),
|
||||||
|
data=json.dumps(data),
|
||||||
|
content_type='html/json'
|
||||||
|
)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
|
response_data = json.loads(response.data)
|
||||||
|
self.schedule_id = response_data['node']['_id']
|
||||||
|
is_present = pgagent_utils.verify_pgagent_schedule(self)
|
||||||
|
self.assertTrue(
|
||||||
|
is_present, "pgAgent schedule was not created successfully"
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up code"""
|
||||||
|
pgagent_utils.delete_pgagent_job(self)
|
@ -0,0 +1,69 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
import uuid
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as pgagent_utils
|
||||||
|
|
||||||
|
|
||||||
|
class PgAgentAddStepTestCase(BaseTestGenerator):
|
||||||
|
"""This class will test the add step in the pgAgent job API"""
|
||||||
|
scenarios = [
|
||||||
|
('Create step for pgAgent job', dict(
|
||||||
|
url='/browser/pga_jobstep/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
flag, msg = pgagent_utils.is_valid_server_to_run_pgagent(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
flag, msg = pgagent_utils.is_pgagent_installed_on_server(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
name = "test_job_get%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.job_id = pgagent_utils.create_pgagent_job(self, name)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
self.pgagent_step_name = "test_step_add%s" % str(uuid.uuid4())[1:8]
|
||||||
|
data = {
|
||||||
|
'jstjobid': self.job_id,
|
||||||
|
'jstname': self.pgagent_step_name,
|
||||||
|
'jstdesc': '',
|
||||||
|
'jstenabled': True,
|
||||||
|
'jstkind': True,
|
||||||
|
'jstconntype': True,
|
||||||
|
'jstcode': 'SELECT 1;',
|
||||||
|
'jstconnstr': None,
|
||||||
|
'jstdbname': 'postgres',
|
||||||
|
'jstonerror': 'f',
|
||||||
|
'jstnextrun': '',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.tester.post(
|
||||||
|
'{0}{1}/{2}/{3}/'.format(
|
||||||
|
self.url, str(utils.SERVER_GROUP), str(self.server_id),
|
||||||
|
str(self.job_id)
|
||||||
|
),
|
||||||
|
data=json.dumps(data),
|
||||||
|
content_type='html/json'
|
||||||
|
)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
|
response_data = json.loads(response.data)
|
||||||
|
self.step_id = response_data['node']['_id']
|
||||||
|
is_present = pgagent_utils.verify_pgagent_step(self)
|
||||||
|
self.assertTrue(
|
||||||
|
is_present, "pgAgent step was not created successfully"
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up code"""
|
||||||
|
pgagent_utils.delete_pgagent_job(self)
|
@ -0,0 +1,52 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as pgagent_utils
|
||||||
|
|
||||||
|
|
||||||
|
class PgAgentDeleteScheduleTestCase(BaseTestGenerator):
|
||||||
|
"""This class will test the delete pgAgent job schedule API"""
|
||||||
|
scenarios = [
|
||||||
|
('Delete pgAgent Schedule', dict(url='/browser/pga_schedule/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
flag, msg = pgagent_utils.is_valid_server_to_run_pgagent(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
flag, msg = pgagent_utils.is_pgagent_installed_on_server(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
name = "test_job_delete%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.job_id = pgagent_utils.create_pgagent_job(self, name)
|
||||||
|
sch_name = "test_schedule_delete%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.schedule_id = pgagent_utils.create_pgagent_schedule(
|
||||||
|
self, sch_name, self.job_id)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will deletes pgAgent job schedule"""
|
||||||
|
response = self.tester.delete(
|
||||||
|
'{0}{1}/{2}/{3}/{4}'.format(
|
||||||
|
self.url, str(utils.SERVER_GROUP), str(self.server_id),
|
||||||
|
str(self.job_id), str(self.schedule_id)
|
||||||
|
),
|
||||||
|
content_type='html/json'
|
||||||
|
)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
is_present = pgagent_utils.verify_pgagent_schedule(self)
|
||||||
|
self.assertFalse(
|
||||||
|
is_present, "pgAgent schedule was not deleted successfully"
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up code"""
|
||||||
|
pgagent_utils.delete_pgagent_job(self)
|
@ -0,0 +1,52 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as pgagent_utils
|
||||||
|
|
||||||
|
|
||||||
|
class PgAgentDeleteStepTestCase(BaseTestGenerator):
|
||||||
|
"""This class will test the delete pgAgent job step API"""
|
||||||
|
scenarios = [
|
||||||
|
('Delete pgAgent Step', dict(url='/browser/pga_jobstep/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
flag, msg = pgagent_utils.is_valid_server_to_run_pgagent(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
flag, msg = pgagent_utils.is_pgagent_installed_on_server(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
name = "test_job_delete%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.job_id = pgagent_utils.create_pgagent_job(self, name)
|
||||||
|
step_name = "test_step_delete%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.step_id = pgagent_utils.create_pgagent_step(
|
||||||
|
self, step_name, self.job_id)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will deletes pgAgent job step"""
|
||||||
|
response = self.tester.delete(
|
||||||
|
'{0}{1}/{2}/{3}/{4}'.format(
|
||||||
|
self.url, str(utils.SERVER_GROUP), str(self.server_id),
|
||||||
|
str(self.job_id), str(self.step_id)
|
||||||
|
),
|
||||||
|
content_type='html/json'
|
||||||
|
)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
is_present = pgagent_utils.verify_pgagent_step(self)
|
||||||
|
self.assertFalse(
|
||||||
|
is_present, "pgAgent step was not deleted successfully"
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up code"""
|
||||||
|
pgagent_utils.delete_pgagent_job(self)
|
@ -0,0 +1,131 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
import uuid
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as pgagent_utils
|
||||||
|
|
||||||
|
|
||||||
|
class PgAgentPutScheduleTestCase(BaseTestGenerator):
|
||||||
|
"""This class will test the update pgAgent schedule API"""
|
||||||
|
scenarios = [
|
||||||
|
('Update schedule with start and end time', dict(
|
||||||
|
url='/browser/pga_schedule/obj/',
|
||||||
|
data={
|
||||||
|
'jscdesc': 'Test Schedule',
|
||||||
|
'jscstart': '2050-01-01 12:00:00 +05:30',
|
||||||
|
'jscend': '2050-01-20 12:00:00 +05:30',
|
||||||
|
})),
|
||||||
|
('Update schedule with repeat', dict(
|
||||||
|
url='/browser/pga_schedule/obj/',
|
||||||
|
data={
|
||||||
|
'jscmonthdays': '[true,false,true,false,true,false,false,'
|
||||||
|
'false,false,false,false,false,false,false,'
|
||||||
|
'false,false,false,false,false,false,false,'
|
||||||
|
'false,false,false,false,false,false,false,'
|
||||||
|
'false,false,false,false]',
|
||||||
|
'jscweekdays': '[true,false,false,true,false,false,false]',
|
||||||
|
'jscmonths': '[true,false,false,true,false,false,false,false,'
|
||||||
|
'false,false,false,false]',
|
||||||
|
'jschours': '[false,false,false,false,true,false,false,false,'
|
||||||
|
'false,false,false,false,false,false,false,false,'
|
||||||
|
'false,false,false,false,false,false,false,false]'
|
||||||
|
})),
|
||||||
|
('Update schedule add exception', dict(
|
||||||
|
url='/browser/pga_schedule/obj/',
|
||||||
|
data={
|
||||||
|
'jscexceptions': {
|
||||||
|
'added': [{'jexdate': '2050-01-01',
|
||||||
|
'jextime': '12:00:00'}]
|
||||||
|
}},
|
||||||
|
delete_existing_exception=True)),
|
||||||
|
('Update schedule change exception date and time', dict(
|
||||||
|
url='/browser/pga_schedule/obj/',
|
||||||
|
data={
|
||||||
|
'jscexceptions': {
|
||||||
|
'changed': [{'jexdate': '2050-01-31',
|
||||||
|
'jextime': '20:00:00'}]
|
||||||
|
}},
|
||||||
|
create_exception=True)),
|
||||||
|
('Update schedule delete exception', dict(
|
||||||
|
url='/browser/pga_schedule/obj/',
|
||||||
|
data={
|
||||||
|
'jscexceptions': {
|
||||||
|
'deleted': [{'jexdate': '2050-01-01',
|
||||||
|
'jextime': '12:00:00'}]
|
||||||
|
}},
|
||||||
|
create_exception=True,
|
||||||
|
is_delete=True)),
|
||||||
|
]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
flag, msg = pgagent_utils.is_valid_server_to_run_pgagent(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
flag, msg = pgagent_utils.is_pgagent_installed_on_server(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
name = "test_job_update%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.job_id = pgagent_utils.create_pgagent_job(self, name)
|
||||||
|
sch_name = "test_schedule_update%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.schedule_id = pgagent_utils.create_pgagent_schedule(
|
||||||
|
self, sch_name, self.job_id)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will update pgAgent schedule"""
|
||||||
|
|
||||||
|
# Check and Delete entry for pga_exception table for the specified
|
||||||
|
# date and time as no primary key is defined for pga_exception table
|
||||||
|
# and there is a unique constraint for date and time. So when we run
|
||||||
|
# the test cases multiple time then it will fail with unique
|
||||||
|
# constraint error.
|
||||||
|
if hasattr(self, 'delete_existing_exception'):
|
||||||
|
pgagent_utils.delete_pgagent_exception(
|
||||||
|
self, self.data['jscexceptions']['added'][0]['jexdate'],
|
||||||
|
self.data['jscexceptions']['added'][0]['jextime'])
|
||||||
|
|
||||||
|
# Create exception for update and delete
|
||||||
|
if hasattr(self, 'create_exception'):
|
||||||
|
date = None
|
||||||
|
time = None
|
||||||
|
if hasattr(self, 'is_delete'):
|
||||||
|
date = self.data['jscexceptions']['deleted'][0]['jexdate']
|
||||||
|
time = self.data['jscexceptions']['deleted'][0]['jextime']
|
||||||
|
else:
|
||||||
|
date = self.data['jscexceptions']['changed'][0]['jexdate']
|
||||||
|
time = self.data['jscexceptions']['changed'][0]['jextime']
|
||||||
|
|
||||||
|
self.excp_id = pgagent_utils.create_pgagent_exception(
|
||||||
|
self, self.schedule_id, date, time)
|
||||||
|
|
||||||
|
# Add created exception id in data
|
||||||
|
if hasattr(self, 'is_delete'):
|
||||||
|
self.data['jscexceptions']['deleted'][0]['jexid'] = \
|
||||||
|
self.excp_id
|
||||||
|
else:
|
||||||
|
self.data['jscexceptions']['changed'][0]['jexid'] = \
|
||||||
|
self.excp_id
|
||||||
|
|
||||||
|
self.data['jscid'] = str(self.schedule_id)
|
||||||
|
response = self.tester.put(
|
||||||
|
'{0}{1}/{2}/{3}/{4}'.format(
|
||||||
|
self.url, str(utils.SERVER_GROUP), str(self.server_id),
|
||||||
|
str(self.job_id), str(self.schedule_id)
|
||||||
|
),
|
||||||
|
data=json.dumps(self.data),
|
||||||
|
content_type='html/json'
|
||||||
|
)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up code"""
|
||||||
|
pgagent_utils.delete_pgagent_schedule(self)
|
||||||
|
pgagent_utils.delete_pgagent_job(self)
|
@ -0,0 +1,67 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
import uuid
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
from . import utils as pgagent_utils
|
||||||
|
|
||||||
|
|
||||||
|
class PgAgentPutStepTestCase(BaseTestGenerator):
|
||||||
|
"""This class will test the update pgAgent steps API"""
|
||||||
|
scenarios = [
|
||||||
|
('Update step with kind, description, code and error', dict(
|
||||||
|
url='/browser/pga_jobstep/obj/',
|
||||||
|
data={
|
||||||
|
'jstdesc': 'Test Steps',
|
||||||
|
'jstkind': False,
|
||||||
|
'jstcode': 'SELECT 12345',
|
||||||
|
'jstonerror': 'i'
|
||||||
|
})),
|
||||||
|
('Update step with connection type and string', dict(
|
||||||
|
url='/browser/pga_jobstep/obj/',
|
||||||
|
data={
|
||||||
|
'jstconntype': False,
|
||||||
|
'jstconnstr':
|
||||||
|
'host=localhost port=5432 dbname=mydb connect_timeout=10'
|
||||||
|
}))
|
||||||
|
]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
flag, msg = pgagent_utils.is_valid_server_to_run_pgagent(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
flag, msg = pgagent_utils.is_pgagent_installed_on_server(self)
|
||||||
|
if not flag:
|
||||||
|
self.skipTest(msg)
|
||||||
|
name = "test_job_update%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.job_id = pgagent_utils.create_pgagent_job(self, name)
|
||||||
|
step_name = "test_step_update%s" % str(uuid.uuid4())[1:8]
|
||||||
|
self.step_id = pgagent_utils.create_pgagent_step(
|
||||||
|
self, step_name, self.job_id)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""This function will update pgAgent steps"""
|
||||||
|
|
||||||
|
self.data['jstid'] = str(self.step_id)
|
||||||
|
response = self.tester.put(
|
||||||
|
'{0}{1}/{2}/{3}/{4}'.format(
|
||||||
|
self.url, str(utils.SERVER_GROUP), str(self.server_id),
|
||||||
|
str(self.job_id), str(self.step_id)
|
||||||
|
),
|
||||||
|
data=json.dumps(self.data),
|
||||||
|
content_type='html/json'
|
||||||
|
)
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up code"""
|
||||||
|
pgagent_utils.delete_pgagent_step(self)
|
||||||
|
pgagent_utils.delete_pgagent_job(self)
|
@ -151,7 +151,7 @@ def delete_pgagent_job(self):
|
|||||||
|
|
||||||
def verify_pgagent_job(self):
|
def verify_pgagent_job(self):
|
||||||
"""
|
"""
|
||||||
This function deletes the pgAgent job.
|
This function verifies the pgAgent job.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
connection = utils.get_db_connection(
|
connection = utils.get_db_connection(
|
||||||
@ -173,3 +173,236 @@ def verify_pgagent_job(self):
|
|||||||
return count is not None and int(count) != 0
|
return count is not None and int(count) != 0
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc(file=sys.stderr)
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def create_pgagent_schedule(self, sch_name, jobid):
|
||||||
|
"""
|
||||||
|
This function create the pgAgent schedule.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = """
|
||||||
|
INSERT INTO pgagent.pga_schedule(
|
||||||
|
jscname, jscjobid, jscenabled, jscdesc, jscstart, jscend
|
||||||
|
) VALUES (
|
||||||
|
'{0}'::text, {1}::int, true, '',
|
||||||
|
'2050-01-01 12:14:21 +05:30'::timestamp with time zone,
|
||||||
|
'2050-01-30 12:14:21 +05:30'::timestamp with time zone
|
||||||
|
) RETURNING jscid;
|
||||||
|
""".format(sch_name, jobid)
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
sch_id = pg_cursor.fetchone()
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
return sch_id[0]
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_pgagent_schedule(self):
|
||||||
|
"""
|
||||||
|
This function deletes the pgAgent schedule.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
pg_cursor.execute(
|
||||||
|
"DELETE FROM pgagent.pga_schedule "
|
||||||
|
"WHERE jscid = '%s'::integer;" % self.schedule_id
|
||||||
|
)
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_pgagent_schedule(self):
|
||||||
|
"""
|
||||||
|
This function verifies the pgAgent schedule.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
pg_cursor.execute(
|
||||||
|
"SELECT COUNT(*) FROM pgagent.pga_schedule "
|
||||||
|
"WHERE jscid = '%s'::integer;" % self.schedule_id
|
||||||
|
)
|
||||||
|
result = pg_cursor.fetchone()
|
||||||
|
count = result[0]
|
||||||
|
connection.close()
|
||||||
|
return count is not None and int(count) != 0
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_pgagent_exception(self, date, time):
|
||||||
|
"""
|
||||||
|
This function deletes the pgAgent exception.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = "DELETE FROM pgagent.pga_exception " \
|
||||||
|
"WHERE jexdate = to_date('{0}', 'YYYY-MM-DD') AND " \
|
||||||
|
"jextime = '{1}'::time without time zone;".format(date, time)
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
connection.close()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def create_pgagent_exception(self, schid, date, time):
|
||||||
|
"""
|
||||||
|
This function create the pgAgent exception.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Delete existing exception if already exists
|
||||||
|
delete_pgagent_exception(self, date, time)
|
||||||
|
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = """
|
||||||
|
INSERT INTO pgagent.pga_exception(jexscid, jexdate, jextime
|
||||||
|
) VALUES ({0},
|
||||||
|
to_date('{1}', 'YYYY-MM-DD'), '{2}'::time without time zone
|
||||||
|
) RETURNING jexid;
|
||||||
|
""".format(schid, date, time)
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
excep_id = pg_cursor.fetchone()
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
return excep_id[0]
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def create_pgagent_step(self, step_name, jobid):
|
||||||
|
"""
|
||||||
|
This function create the pgAgent step.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
query = """
|
||||||
|
INSERT INTO pgagent.pga_jobstep(
|
||||||
|
jstname, jstjobid, jstenabled, jstkind,
|
||||||
|
jstcode, jstdbname
|
||||||
|
) VALUES (
|
||||||
|
'{0}'::text, {1}::int, true, 's', 'SELECT 1', 'postgres'
|
||||||
|
) RETURNING jstid;
|
||||||
|
""".format(step_name, jobid)
|
||||||
|
pg_cursor.execute(query)
|
||||||
|
step_id = pg_cursor.fetchone()
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
return step_id[0]
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_pgagent_step(self):
|
||||||
|
"""
|
||||||
|
This function deletes the pgAgent step.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
old_isolation_level = connection.isolation_level
|
||||||
|
connection.set_isolation_level(0)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
pg_cursor.execute(
|
||||||
|
"DELETE FROM pgagent.pga_jobstep "
|
||||||
|
"WHERE jstid = '%s'::integer;" % self.step_id
|
||||||
|
)
|
||||||
|
connection.set_isolation_level(old_isolation_level)
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_pgagent_step(self):
|
||||||
|
"""
|
||||||
|
This function verifies the pgAgent step .
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
connection = utils.get_db_connection(
|
||||||
|
self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port'],
|
||||||
|
self.server['sslmode']
|
||||||
|
)
|
||||||
|
pg_cursor = connection.cursor()
|
||||||
|
pg_cursor.execute(
|
||||||
|
"SELECT COUNT(*) FROM pgagent.pga_jobstep "
|
||||||
|
"WHERE jstid = '%s'::integer;" % self.step_id
|
||||||
|
)
|
||||||
|
result = pg_cursor.fetchone()
|
||||||
|
count = result[0]
|
||||||
|
connection.close()
|
||||||
|
return count is not None and int(count) != 0
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
Loading…
Reference in New Issue
Block a user