public inbox for [email protected]  
help / color / mirror / Atom feed
[pgadmin4][Patch]: Test cases for the backup module
29+ messages / 4 participants
[nested] [flat]

* [pgadmin4][Patch]: Test cases for the backup module
@ 2018-04-25 09:20 Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-04-25 09:20 UTC (permalink / raw)
  To: pgadmin-hackers

Hi,

Please find the attached patch which covers test cases for the backup
module (RM #3206).

1. Unit test cases
2. End to end regression test cases
3. Feature test cases

Thanks,
Khushboo


Attachments:

  [text/x-patch] RM_3206.patch (31.2K, 3-RM_3206.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_test.py
new file mode 100644
index 0000000..feca43a
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_test.py
@@ -0,0 +1,82 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities", dict())
+    ]
+
+    def before(self):
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "acceptance_test_db")
+
+        test_utils.create_database(self.server, "acceptance_test_db")
+        test_utils.create_table(self.server, "acceptance_test_db", "acceptance_test_table")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 10)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('acceptance_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        time.sleep(0.5)
+
+        self.page.fill_input_by_field_name("file", "test_backup_file")
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'acceptance_test_db'", str(command))
+        self.assertIn("test_backup_file", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "acceptance_test_db")
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..780106e
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,148 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                    '--file',
+                    "backup_file",
+                    '--host',
+                    "localhost",
+                    '--port',
+                    "5444",
+                    '--username',
+                    "postgres",
+                    '--no-password',
+                    '--database',
+                    "postgres"
+                ],
+                 cmd = "/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" --no-password --database "postgres"'
+
+         )),
+        ('When backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" --no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server 'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" --no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    def runTest(self, current_user_mock, server_mock):
+        current_user_mock = 1
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'], self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..aab5fd1
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,216 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                    '--file',
+                    "backup_file",
+                    '--host',
+                    "localhost",
+                    '--port',
+                    "5444",
+                    '--username',
+                    "postgres",
+                    '--no-password',
+                    '--database',
+                    "postgres"
+                ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd, ' --file "backup_file" --host "{0}" '
+                                           '--port "{1}" --username "{2}" '
+                                           '--no-password --database "{3}"'.format(
+                self.class_params['host'], self.class_params['port'],
+                self.class_params['username'], self.class_params['database']
+            ))
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock, process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [TestMockProcess(backup_obj,
+                                                                    self.class_params['args'],
+                                                                    self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
+
+
+
+
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..6c6e58e
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,371 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import config
+
+from flask import Response
+import simplejson as json
+from pickle import dumps, loads
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+from flask import current_app
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=0
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the object with format tar',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=0
+         )),
+        ('When backup the server',
+         dict(
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=None
+         )),
+        ('When backup globals',
+         dict(
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=None
+         ))
+    ]
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        self.assertEqual(self.expected_exit_code, process_list[0]['exit_code'])
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = BackupJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index 1de9823..99846c1 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -72,6 +72,13 @@ config.UPGRADE_CHECK_ENABLED = False
 
 pgadmin_credentials = test_setup.config_data
 
+config.DEFAULT_BINARY_PATHS = {
+    "pg": pgadmin_credentials['DEFAULT_BINARY_PATHS']['pg'],
+    "ppas": pgadmin_credentials['DEFAULT_BINARY_PATHS']['ppas'],
+    "gpdb": ""
+}
+
+
 # Set environment variables for email and password
 os.environ['PGADMIN_SETUP_EMAIL'] = ''
 os.environ['PGADMIN_SETUP_PASSWORD'] = ''
@@ -112,6 +119,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index 47f8499..41f4dd0 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -28,5 +28,9 @@
     {
       "comment": "This is test update comment"
     }
-  ]
+  ],
+  "DEFAULT_BINARY_PATHS": {
+     "pg": "",
+     "ppas": ""
+  }
 }


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-04-25 16:10 ` Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Joao De Almeida Pereira @ 2018-04-25 16:10 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: pgadmin-hackers

Hi Khushboo,

We reviewed the patch and it is very nice to see some more coverage in this
area. Good job :D

We passed the tests through our CI the feature tests are not passing, but
the linter fails:

./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line
too long (91 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line
too long (104 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line
too long (85 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line
too long (96 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line
too long (91 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line
too long (118 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121]
continuation line under-indented for hanging indent
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122]
continuation line missing indentation or outdented
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251]
unexpected spaces around keyword / parameter equals
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251]
unexpected spaces around keyword / parameter equals
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line
too long (91 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line
too long (94 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line
too long (108 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line
too long (113 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line
too long (94 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line
too long (108 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line
too long (100 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line
too long (94 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line
too long (108 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line
too long (93 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121]
continuation line under-indented for hanging indent
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122]
continuation line missing indentation or outdented
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line
too long (80 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line
too long (83 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122]
continuation line missing indentation or outdented
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122]
continuation line missing indentation or outdented
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122]
continuation line missing indentation or outdented
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line
too long (81 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line
too long (80 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128]
continuation line under-indented for visual indent
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line
too long (94 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128]
continuation line under-indented for visual indent
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line
too long (94 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank
line at end of file
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501]
line too long (97 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too
many blank lines (2)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501]
line too long (84 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391]
blank line at end of file
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
2       E121 continuation line under-indented for hanging indent
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
5       E122 continuation line missing indentation or outdented
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
2       E128 continuation line under-indented for visual indent
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
2       E251 unexpected spaces around keyword / parameter equals
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
1       E303 too many blank lines (2)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
24      E501 line too long (91 > 79 characters)
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
2       W391 blank line at end of file
 <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
38


For the feature tests, we realized we had to update the configuration, and
we did that, but we get the following error attached. We spent some time
trying to understand the problem but we were not successful.


Codewise:
- We just found some One Letter Variables in the code...
- Looks like there is a bug report in this area of the code and we do not
have coverage for it: https://redmine.postgresql.org/issues/3232
  Looks like in some of the unit tests we only have happy path tests, maybe
we should see if there are any sad paths that also need coverage.

The configuration change, maybe need to be updated. When we install
multiple versions of postgres the binaries live in
`/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that this
configuration should live near the server configuration, maybe? Also to
maintain coherency on the naming maybe we should make it all lower case.
Just as an aside, you can add the gpdb configuration as well in you patch.

Thanks
Victoria & Joao

On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
[email protected]> wrote:

> Hi,
>
> Please find the attached patch which covers test cases for the backup
> module (RM #3206).
>
> 1. Unit test cases
> 2. End to end regression test cases
> 3. Feature test cases
>
> Thanks,
> Khushboo
>


Attachments:

  [image/png] PGUtilitiesBackupFeatureTest-2018.04.25_12.05.19-Python-3.6.4.png (111.4K, 3-PGUtilitiesBackupFeatureTest-2018.04.25_12.05.19-Python-3.6.4.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
@ 2018-05-28 12:09   ` Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-05-28 12:09 UTC (permalink / raw)
  To: pgadmin-hackers

Hi,

please find the attached updated patch for the test cases of Backup,
Restore and Maintenance modules which includes:

1. Unit test cases
2. End to end regression test cases
3. Feature test cases

Thanks,
Khushboo




On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
[email protected]> wrote:

> Hi Khushboo,
>
> We reviewed the patch and it is very nice to see some more coverage in
> this area. Good job :D
>
> We passed the tests through our CI the feature tests are not passing, but
> the linter fails:
>
> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 2       E121 continuation line under-indented for hanging indent
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 5       E122 continuation line missing indentation or outdented
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 2       E128 continuation line under-indented for visual indent
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 2       E251 unexpected spaces around keyword / parameter equals
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 1       E303 too many blank lines (2)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 24      E501 line too long (91 > 79 characters)
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 2       W391 blank line at end of file
>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
> 38
>
>
> For the feature tests, we realized we had to update the configuration, and
> we did that, but we get the following error attached. We spent some time
> trying to understand the problem but we were not successful.
>
>
> Codewise:
> - We just found some One Letter Variables in the code...
> - Looks like there is a bug report in this area of the code and we do not
> have coverage for it: https://redmine.postgresql.org/issues/3232
>   Looks like in some of the unit tests we only have happy path tests,
> maybe we should see if there are any sad paths that also need coverage.
>
> The configuration change, maybe need to be updated. When we install
> multiple versions of postgres the binaries live in
> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that this
> configuration should live near the server configuration, maybe? Also to
> maintain coherency on the naming maybe we should make it all lower case.
> Just as an aside, you can add the gpdb configuration as well in you patch.
>
> Thanks
> Victoria & Joao
>
> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi,
>>
>> Please find the attached patch which covers test cases for the backup
>> module (RM #3206).
>>
>> 1. Unit test cases
>> 2. End to end regression test cases
>> 3. Feature test cases
>>
>> Thanks,
>> Khushboo
>>
>


Attachments:

  [text/x-patch] RM_3206.patch (103.3K, 3-RM_3206.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py b/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py
index 5ad0469..c3be213 100644
--- a/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py
+++ b/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py
@@ -36,5 +36,5 @@ class ServersAddTestCase(BaseTestGenerator):
         utils.write_node_info("sid", server_dict)
 
     def tearDown(self):
-        """This function delete the server from SQLite """
+        """This function delete the server from SQLite"""
         utils.delete_server_with_api(self.tester, self.server_id)
diff --git a/web/pgadmin/browser/server_groups/servers/types.py b/web/pgadmin/browser/server_groups/servers/types.py
index d0bea4f..159c860 100644
--- a/web/pgadmin/browser/server_groups/servers/types.py
+++ b/web/pgadmin/browser/server_groups/servers/types.py
@@ -61,7 +61,6 @@ class ServerType(object):
         for key in cls.registry:
             st = cls.registry[key]
             default_path = config.DEFAULT_BINARY_PATHS.get(st.stype, "")
-
             st.utility_path = paths.register(
                 'bin_paths', st.stype + '_bin_dir',
                 st.UTILITY_PATH_LABEL,
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..c8cbe28
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,127 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 10)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(
+            EC.element_to_be_clickable((By.NAME, 'file'))
+        )
+
+        self.page.fill_input_by_field_name("file", "test_backup_file")
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup_file", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(
+            EC.element_to_be_clickable((By.NAME, 'file'))
+        )
+
+        self.page.fill_input_by_field_name("file", "test_backup_file")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup_file", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..83f3736
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 10)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..1ff608b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,458 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    def runTest(self, batch_process_mock, filename_mock,
+                backup_message_mock, current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..761d286
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,158 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    def runTest(self, current_user_mock, server_mock):
+        current_user_mock = 1
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..3c0c98c
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..8cba9be
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,219 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..d9f0531
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,58 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_utils.run_backup_job(self.tester,
+                                    job_id,
+                                    self.expected_params,
+                                    self.assertIn,
+                                    self.assertNotIn
+                                    )
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..a424920
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,142 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        utils.set_preference(self.server['DEFAULT_BINARY_PATHS'])
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..6cf0465
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,195 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    def runTest(self, batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        print(batch_process_mock.call_args_list[0][1]['args'])
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index f6f92b9..460d01f 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -192,6 +192,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..3c674e1
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,161 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..64b12b6
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,196 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        backup_utils.run_backup_job(self.tester, job_id,
+                                    self.backup_options['expected_params'],
+                                    self.assertIn, self.assertNotIn)
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        print(process_list[0])
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def after(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..0cf315f
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,313 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['DEFAULT_BINARY_PATHS'] is None:
+            self.skipTest(
+                "DEFAULT_BINARY_PATHS is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    def runTest(self, batch_process_mock, filename_mock,
+                restore_message_mock, current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..0b3e09d
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,85 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    def runTest(self, current_user_mock, server_mock):
+        current_user_mock = 1
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..d61c5d8 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "DEFAULT_BINARY_PATHS": srv.get('DEFAULT_BINARY_PATHS', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,47 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..21e4e35 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,15 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['DEFAULT_BINARY_PATHS'] is not None:
+                test_utils.set_preference(server['DEFAULT_BINARY_PATHS'])
+
+                config.DEFAULT_BINARY_PATHS = {
+                    "pg": str(server['DEFAULT_BINARY_PATHS']['pg']),
+                    "ppas": str(server['DEFAULT_BINARY_PATHS']['ppas']),
+                    "gpdb": ""
+                }
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..cb6b98c 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "DEFAULT_BINARY_PATHS": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-05-29 19:35     ` Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Dave Page @ 2018-05-29 19:35 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: pgadmin-hackers

Hi

On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
[email protected]> wrote:

> Hi,
>
> please find the attached updated patch for the test cases of Backup,
> Restore and Maintenance modules which includes:
>
> 1. Unit test cases
> 2. End to end regression test cases
> 3. Feature test cases
>

Thanks. I've yet to be able to run the feature tests successfully. Here's
what I've found so far:

1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON config
file.

2) I've hit screensize related issues:

======================================================================

ERROR: runTest
(pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)

Test for PG maintenance: database

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
line 56, in runTest

    self._open_maintenance_dialogue()

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
line 75, in _open_maintenance_dialogue

    "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
line 80, in click

    self._execute(Command.CLICK_ELEMENT)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
line 628, in _execute

    return self._parent.execute(command, params)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
line 312, in execute

    self.error_handler.check_response(response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
line 242, in check_response

    raise exception_class(message, screen, stacktrace)

WebDriverException: Message: unknown error: Element <span
class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
element would receive the click: <div class="wcFrameCenter
wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
0px; bottom: 0px;">...</div>

  (Session info: chrome=66.0.3359.181)

  (Driver info: chromedriver=2.38.552518
(183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6 x86_64)

3) One time the test did start, but then I saw this failure:

======================================================================

ERROR: runTest
(pgadmin.feature_tests.pg_utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)

Test for PG utilities - Backup and Restore

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
line 93, in runTest

    self.page.fill_input_by_field_name("file", "test_backup_file")

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 211, in fill_input_by_field_name

    self.wait_for_input_field_content(field_name, field_content)

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 251, in wait_for_input_field_content

    "field to contain '" + str(content) + "'", input_field_has_content

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 337, in _wait_for

    "Timed out waiting for " + waiting_for_message

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
line 80, in until

    raise TimeoutException(message, screen, stacktrace)

TimeoutException: Message: Timed out waiting for field to contain
'test_backup_file'



(with screenshot attached)

Thanks.





>
> Thanks,
> Khushboo
>
>
>
>
> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
> [email protected]> wrote:
>
>> Hi Khushboo,
>>
>> We reviewed the patch and it is very nice to see some more coverage in
>> this area. Good job :D
>>
>> We passed the tests through our CI the feature tests are not passing, but
>> the linter fails:
>>
>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 2       E121 continuation line under-indented for hanging indent
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 5       E122 continuation line missing indentation or outdented
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 2       E128 continuation line under-indented for visual indent
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 2       E251 unexpected spaces around keyword / parameter equals
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 1       E303 too many blank lines (2)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 24      E501 line too long (91 > 79 characters)
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 2       W391 blank line at end of file
>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>> 38
>>
>>
>> For the feature tests, we realized we had to update the configuration,
>> and we did that, but we get the following error attached. We spent some
>> time trying to understand the problem but we were not successful.
>>
>>
>> Codewise:
>> - We just found some One Letter Variables in the code...
>> - Looks like there is a bug report in this area of the code and we do not
>> have coverage for it: https://redmine.postgresql.org/issues/3232
>>   Looks like in some of the unit tests we only have happy path tests,
>> maybe we should see if there are any sad paths that also need coverage.
>>
>> The configuration change, maybe need to be updated. When we install
>> multiple versions of postgres the binaries live in
>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that this
>> configuration should live near the server configuration, maybe? Also to
>> maintain coherency on the naming maybe we should make it all lower case.
>> Just as an aside, you can add the gpdb configuration as well in you patch.
>>
>> Thanks
>> Victoria & Joao
>>
>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi,
>>>
>>> Please find the attached patch which covers test cases for the backup
>>> module (RM #3206).
>>>
>>> 1. Unit test cases
>>> 2. End to end regression test cases
>>> 3. Feature test cases
>>>
>>> Thanks,
>>> Khushboo
>>>
>>
>


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Attachments:

  [image/png] PGUtilitiesBackupFeatureTest-2018.05.29_15.15.59-Python-2.7.10.png (302.4K, 3-PGUtilitiesBackupFeatureTest-2018.05.29_15.15.59-Python-2.7.10.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
@ 2018-05-30 04:43       ` Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-05-30 04:43 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: pgadmin-hackers

On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:

> Hi
>
> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi,
>>
>> please find the attached updated patch for the test cases of Backup,
>> Restore and Maintenance modules which includes:
>>
>> 1. Unit test cases
>> 2. End to end regression test cases
>> 3. Feature test cases
>>
>
> Thanks. I've yet to be able to run the feature tests successfully. Here's
> what I've found so far:
>
> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON config
> file.
>
> Will do.

> 2) I've hit screensize related issues:
>
> ======================================================================
>
> ERROR: runTest (pgadmin.feature_tests.pg_utilities_maintenance_test.
> PGUtilitiesMaintenanceFeatureTest)
>
> Test for PG maintenance: database
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_maintenance_test.py", line 56, in runTest
>
>     self._open_maintenance_dialogue()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_maintenance_test.py", line 75, in _open_maintenance_dialogue
>
>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 80, in click
>
>     self._execute(Command.CLICK_ELEMENT)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
>
>     return self._parent.execute(command, params)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
>
>     self.error_handler.check_response(response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/errorhandler.py", line 242, in
> check_response
>
>     raise exception_class(message, screen, stacktrace)
>
> WebDriverException: Message: unknown error: Element <span
> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
> element would receive the click: <div class="wcFrameCenter
> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
> 0px; bottom: 0px;">...</div>
>
>   (Session info: chrome=66.0.3359.181)
>
>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
> OS X 10.12.6 x86_64)
>
> 3) One time the test did start, but then I saw this failure:
>
> ======================================================================
>
> ERROR: runTest (pgadmin.feature_tests.pg_utilities_backup_restore_test.
> PGUtilitiesBackupFeatureTest)
>
> Test for PG utilities - Backup and Restore
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_backup_restore_test.py", line 93, in runTest
>
>     self.page.fill_input_by_field_name("file", "test_backup_file")
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 211, in fill_input_by_field_name
>
>     self.wait_for_input_field_content(field_name, field_content)
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 251, in wait_for_input_field_content
>
>     "field to contain '" + str(content) + "'", input_field_has_content
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>
>     "Timed out waiting for " + waiting_for_message
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/support/wait.py", line 80, in until
>
>     raise TimeoutException(message, screen, stacktrace)
>
> TimeoutException: Message: Timed out waiting for field to contain
> 'test_backup_file'
>
>
>
> (with screenshot attached)
>
> Thanks.
>
> I have ran the feature tests with multiple servers many times but didn't
get a single failure.
I have asked Akshay to run on his machine, let see what he gets.

>
>
>
>
>>
>> Thanks,
>> Khushboo
>>
>>
>>
>>
>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>> [email protected]> wrote:
>>
>>> Hi Khushboo,
>>>
>>> We reviewed the patch and it is very nice to see some more coverage in
>>> this area. Good job :D
>>>
>>> We passed the tests through our CI the feature tests are not passing,
>>> but the linter fails:
>>>
>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 2       E121 continuation line under-indented for hanging indent
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 5       E122 continuation line missing indentation or outdented
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 2       E128 continuation line under-indented for visual indent
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 1       E303 too many blank lines (2)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 24      E501 line too long (91 > 79 characters)
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 2       W391 blank line at end of file
>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>> 38
>>>
>>>
>>> For the feature tests, we realized we had to update the configuration,
>>> and we did that, but we get the following error attached. We spent some
>>> time trying to understand the problem but we were not successful.
>>>
>>>
>>> Codewise:
>>> - We just found some One Letter Variables in the code...
>>> - Looks like there is a bug report in this area of the code and we do
>>> not have coverage for it: https://redmine.postgresql.org/issues/3232
>>>   Looks like in some of the unit tests we only have happy path tests,
>>> maybe we should see if there are any sad paths that also need coverage.
>>>
>>> The configuration change, maybe need to be updated. When we install
>>> multiple versions of postgres the binaries live in
>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that
>>> this configuration should live near the server configuration, maybe? Also
>>> to maintain coherency on the naming maybe we should make it all lower case.
>>> Just as an aside, you can add the gpdb configuration as well in you
>>> patch.
>>>
>>> Thanks
>>> Victoria & Joao
>>>
>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>>
>>>> Please find the attached patch which covers test cases for the backup
>>>> module (RM #3206).
>>>>
>>>> 1. Unit test cases
>>>> 2. End to end regression test cases
>>>> 3. Feature test cases
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>
>>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-05-31 05:16         ` Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-05-31 05:16 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: pgadmin-hackers

Hi,

Please find the attached updated patch with the fixes.
The test cases were only failing on MAC not on Linux.

Thanks,
Khushboo

On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
[email protected]> wrote:

>
>
> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:
>
>> Hi
>>
>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi,
>>>
>>> please find the attached updated patch for the test cases of Backup,
>>> Restore and Maintenance modules which includes:
>>>
>>> 1. Unit test cases
>>> 2. End to end regression test cases
>>> 3. Feature test cases
>>>
>>
>> Thanks. I've yet to be able to run the feature tests successfully. Here's
>> what I've found so far:
>>
>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON config
>> file.
>>
>> Will do.
>
>> 2) I've hit screensize related issues:
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.feature_tests.pg_util
>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>
>> Test for PG maintenance: database
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 56, in runTest
>>
>>     self._open_maintenance_dialogue()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 75, in _open_maintenance_dialogue
>>
>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 80, in click
>>
>>     self._execute(Command.CLICK_ELEMENT)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 628, in _execute
>>
>>     return self._parent.execute(command, params)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>
>>     self.error_handler.check_response(response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/errorhandler.py", line 242, in
>> check_response
>>
>>     raise exception_class(message, screen, stacktrace)
>>
>> WebDriverException: Message: unknown error: Element <span
>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>> element would receive the click: <div class="wcFrameCenter
>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>> 0px; bottom: 0px;">...</div>
>>
>>   (Session info: chrome=66.0.3359.181)
>>
>>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
>> OS X 10.12.6 x86_64)
>>
>> 3) One time the test did start, but then I saw this failure:
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.feature_tests.pg_util
>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>
>> Test for PG utilities - Backup and Restore
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>> line 93, in runTest
>>
>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 211, in fill_input_by_field_name
>>
>>     self.wait_for_input_field_content(field_name, field_content)
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 251, in wait_for_input_field_content
>>
>>     "field to contain '" + str(content) + "'", input_field_has_content
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>
>>     "Timed out waiting for " + waiting_for_message
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>
>>     raise TimeoutException(message, screen, stacktrace)
>>
>> TimeoutException: Message: Timed out waiting for field to contain
>> 'test_backup_file'
>>
>>
>>
>> (with screenshot attached)
>>
>> Thanks.
>>
>> I have ran the feature tests with multiple servers many times but didn't
> get a single failure.
> I have asked Akshay to run on his machine, let see what he gets.
>
>>
>>
>>
>>
>>>
>>> Thanks,
>>> Khushboo
>>>
>>>
>>>
>>>
>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>> [email protected]> wrote:
>>>
>>>> Hi Khushboo,
>>>>
>>>> We reviewed the patch and it is very nice to see some more coverage in
>>>> this area. Good job :D
>>>>
>>>> We passed the tests through our CI the feature tests are not passing,
>>>> but the linter fails:
>>>>
>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 2       E121 continuation line under-indented for hanging indent
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 5       E122 continuation line missing indentation or outdented
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 2       E128 continuation line under-indented for visual indent
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 1       E303 too many blank lines (2)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 24      E501 line too long (91 > 79 characters)
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 2       W391 blank line at end of file
>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>> 38
>>>>
>>>>
>>>> For the feature tests, we realized we had to update the configuration,
>>>> and we did that, but we get the following error attached. We spent some
>>>> time trying to understand the problem but we were not successful.
>>>>
>>>>
>>>> Codewise:
>>>> - We just found some One Letter Variables in the code...
>>>> - Looks like there is a bug report in this area of the code and we do
>>>> not have coverage for it: https://redmine.postgresql.org/issues/3232
>>>>   Looks like in some of the unit tests we only have happy path tests,
>>>> maybe we should see if there are any sad paths that also need coverage.
>>>>
>>>> The configuration change, maybe need to be updated. When we install
>>>> multiple versions of postgres the binaries live in
>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that
>>>> this configuration should live near the server configuration, maybe? Also
>>>> to maintain coherency on the naming maybe we should make it all lower case.
>>>> Just as an aside, you can add the gpdb configuration as well in you
>>>> patch.
>>>>
>>>> Thanks
>>>> Victoria & Joao
>>>>
>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> Please find the attached patch which covers test cases for the backup
>>>>> module (RM #3206).
>>>>>
>>>>> 1. Unit test cases
>>>>> 2. End to end regression test cases
>>>>> 3. Feature test cases
>>>>>
>>>>> Thanks,
>>>>> Khushboo
>>>>>
>>>>
>>>
>>
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>
>


Attachments:

  [application/octet-stream] RM_3206_ver1.patch (103.0K, 3-RM_3206_ver1.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py b/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py
index 5ad0469..c3be213 100644
--- a/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py
+++ b/web/pgadmin/browser/server_groups/servers/tests/test_server_add.py
@@ -36,5 +36,5 @@ class ServersAddTestCase(BaseTestGenerator):
         utils.write_node_info("sid", server_dict)
 
     def tearDown(self):
-        """This function delete the server from SQLite """
+        """This function delete the server from SQLite"""
         utils.delete_server_with_api(self.tester, self.server_id)
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..b4c1bb2
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..1f908f0
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,458 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    def runTest(self, batch_process_mock, filename_mock,
+                backup_message_mock, current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..761d286
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,158 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    def runTest(self, current_user_mock, server_mock):
+        current_user_mock = 1
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..3c0c98c
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..8cba9be
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,219 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..d76a3c7
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,58 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_utils.run_backup_job(self.tester,
+                                    job_id,
+                                    self.expected_params,
+                                    self.assertIn,
+                                    self.assertNotIn
+                                    )
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..5b98b09
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,195 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    def runTest(self, batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        print(batch_process_mock.call_args_list[0][1]['args'])
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index f6f92b9..460d01f 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -192,6 +192,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..3c674e1
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,161 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..b7e01e4
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,196 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        backup_utils.run_backup_job(self.tester, job_id,
+                                    self.backup_options['expected_params'],
+                                    self.assertIn, self.assertNotIn)
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        print(process_list[0])
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def after(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..212039e
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,313 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    def runTest(self, batch_process_mock, filename_mock,
+                restore_message_mock, current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..0b3e09d
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,85 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    def runTest(self, current_user_mock, server_mock):
+        current_user_mock = 1
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..d5d3a0f 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,47 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..0a1d48e 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,15 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
+                config.DEFAULT_BINARY_PATHS = {
+                    "pg": str(server['default_binary_paths']['pg']),
+                    "ppas": str(server['default_binary_paths']['ppas']),
+                    "gpdb": ""
+                }
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-05-31 16:30           ` Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Victoria Henry @ 2018-05-31 16:30 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Dave Page <[email protected]>; pgadmin-hackers

Hi there,

We've been noticing some issues with the tests on both our CI and local Mac
workstations.

   1. When the following code blocks are invoked - we get plenty of
   app.context() issues. It must not be valid when running tests.

​

from pgadmin.utils.driver import get_driver
driver = get_driver(PG_DEFAULT_DRIVER)
manager = driver.connection_manager(self.sid)

host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
port = manager.local_bind_port if manager.use_ssh_tunnel else s.port

2. When we finally enable

"default_binary_paths": {

in our test_config, we get more failing tests that look like:

======================================================================
FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
When restore object with option - Miscellaneous
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py",
line 1179, in patched
    return func(*args, **keywargs)
  File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py",
line 295, in runTest
    self.assertEquals(response.status_code, 200)
AssertionError: 410 != 200

And

When restore object with the sections options ... 2018-05-31
12:24:42,988: ERROR    pgadmin:    illegal environment variable name
Traceback (most recent call last):
  File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py",
line 352, in create_restore_job
    manager.export_password_env(p.id)
  File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py",
line 365, in export_password_env
    os.environ[str(env)] = password
  File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py",
line 675, in __setitem__
    self.putenv(key, value)
ValueError: illegal environment variable name
FAIL

​

Sincerely,

Victoria && Anthony

On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
[email protected]> wrote:

> Hi,
>
> Please find the attached updated patch with the fixes.
> The test cases were only failing on MAC not on Linux.
>
> Thanks,
> Khushboo
>
> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>>
>>
>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:
>>
>>> Hi
>>>
>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>>
>>>> please find the attached updated patch for the test cases of Backup,
>>>> Restore and Maintenance modules which includes:
>>>>
>>>> 1. Unit test cases
>>>> 2. End to end regression test cases
>>>> 3. Feature test cases
>>>>
>>>
>>> Thanks. I've yet to be able to run the feature tests successfully.
>>> Here's what I've found so far:
>>>
>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>> config file.
>>>
>>> Will do.
>>
>>> 2) I've hit screensize related issues:
>>>
>>> ======================================================================
>>>
>>> ERROR: runTest
>>> (pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>
>>> Test for PG maintenance: database
>>>
>>> ----------------------------------------------------------------------
>>>
>>> Traceback (most recent call last):
>>>
>>>   File
>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>> line 56, in runTest
>>>
>>>     self._open_maintenance_dialogue()
>>>
>>>   File
>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>> line 75, in _open_maintenance_dialogue
>>>
>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>
>>>   File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>> line 80, in click
>>>
>>>     self._execute(Command.CLICK_ELEMENT)
>>>
>>>   File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>> line 628, in _execute
>>>
>>>     return self._parent.execute(command, params)
>>>
>>>   File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>> line 312, in execute
>>>
>>>     self.error_handler.check_response(response)
>>>
>>>   File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>> line 242, in check_response
>>>
>>>     raise exception_class(message, screen, stacktrace)
>>>
>>> WebDriverException: Message: unknown error: Element <span
>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>> element would receive the click: <div class="wcFrameCenter
>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>> 0px; bottom: 0px;">...</div>
>>>
>>>   (Session info: chrome=66.0.3359.181)
>>>
>>>   (Driver info: chromedriver=2.38.552518
>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6 x86_64)
>>>
>>> 3) One time the test did start, but then I saw this failure:
>>>
>>> ======================================================================
>>>
>>> ERROR: runTest
>>> (pgadmin.feature_tests.pg_utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>
>>> Test for PG utilities - Backup and Restore
>>>
>>> ----------------------------------------------------------------------
>>>
>>> Traceback (most recent call last):
>>>
>>>   File
>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>> line 93, in runTest
>>>
>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>
>>>   File
>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>> line 211, in fill_input_by_field_name
>>>
>>>     self.wait_for_input_field_content(field_name, field_content)
>>>
>>>   File
>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>> line 251, in wait_for_input_field_content
>>>
>>>     "field to contain '" + str(content) + "'", input_field_has_content
>>>
>>>   File
>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>> line 337, in _wait_for
>>>
>>>     "Timed out waiting for " + waiting_for_message
>>>
>>>   File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>> line 80, in until
>>>
>>>     raise TimeoutException(message, screen, stacktrace)
>>>
>>> TimeoutException: Message: Timed out waiting for field to contain
>>> 'test_backup_file'
>>>
>>>
>>>
>>> (with screenshot attached)
>>>
>>> Thanks.
>>>
>>> I have ran the feature tests with multiple servers many times but didn't
>> get a single failure.
>> I have asked Akshay to run on his machine, let see what he gets.
>>
>>>
>>>
>>>
>>>
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>>
>>>>
>>>>
>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Khushboo,
>>>>>
>>>>> We reviewed the patch and it is very nice to see some more coverage in
>>>>> this area. Good job :D
>>>>>
>>>>> We passed the tests through our CI the feature tests are not passing,
>>>>> but the linter fails:
>>>>>
>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 1       E303 too many blank lines (2)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 2       W391 blank line at end of file
>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>> 38
>>>>>
>>>>>
>>>>> For the feature tests, we realized we had to update the configuration,
>>>>> and we did that, but we get the following error attached. We spent some
>>>>> time trying to understand the problem but we were not successful.
>>>>>
>>>>>
>>>>> Codewise:
>>>>> - We just found some One Letter Variables in the code...
>>>>> - Looks like there is a bug report in this area of the code and we do
>>>>> not have coverage for it: https://redmine.postgresql.org/issues/3232
>>>>>   Looks like in some of the unit tests we only have happy path tests,
>>>>> maybe we should see if there are any sad paths that also need coverage.
>>>>>
>>>>> The configuration change, maybe need to be updated. When we install
>>>>> multiple versions of postgres the binaries live in
>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that this
>>>>> configuration should live near the server configuration, maybe? Also to
>>>>> maintain coherency on the naming maybe we should make it all lower case.
>>>>> Just as an aside, you can add the gpdb configuration as well in you
>>>>> patch.
>>>>>
>>>>> Thanks
>>>>> Victoria & Joao
>>>>>
>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Please find the attached patch which covers test cases for the backup
>>>>>> module (RM #3206).
>>>>>>
>>>>>> 1. Unit test cases
>>>>>> 2. End to end regression test cases
>>>>>> 3. Feature test cases
>>>>>>
>>>>>> Thanks,
>>>>>> Khushboo
>>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>> Dave Page
>>> Blog: http://pgsnake.blogspot.com
>>> Twitter: @pgsnake
>>>
>>> EnterpriseDB UK: http://www.enterprisedb.com
>>> The Enterprise PostgreSQL Company
>>>
>>
>>
>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
@ 2018-06-01 11:06             ` Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-01 11:06 UTC (permalink / raw)
  To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; pgadmin-hackers

Hi Victoria,

Thanks for reviewing the patch.
The tests were failing due to the latest commit
#2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
backup/restore/maintenance work via SSH tunnels. Fixes #3355

I have fixed the issues and attached the updated patch.

Thanks,
Khushboo

On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]> wrote:

> Hi there,
>
> We've been noticing some issues with the tests on both our CI and local
> Mac workstations.
>
>    1. When the following code blocks are invoked - we get plenty of
>    app.context() issues. It must not be valid when running tests.
>
> ​
>
> from pgadmin.utils.driver import get_driver
> driver = get_driver(PG_DEFAULT_DRIVER)
> manager = driver.connection_manager(self.sid)
>
> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>
> 2. When we finally enable
>
> "default_binary_paths": {
>
> in our test_config, we get more failing tests that look like:
>
> ======================================================================
> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
> When restore object with option - Miscellaneous
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>     return func(*args, **keywargs)
>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>     self.assertEquals(response.status_code, 200)
> AssertionError: 410 != 200
>
> And
>
> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
> Traceback (most recent call last):
>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>     manager.export_password_env(p.id)
>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>     os.environ[str(env)] = password
>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>     self.putenv(key, value)
> ValueError: illegal environment variable name
> FAIL
>
> ​
>
> Sincerely,
>
> Victoria && Anthony
>
> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi,
>>
>> Please find the attached updated patch with the fixes.
>> The test cases were only failing on MAC not on Linux.
>>
>> Thanks,
>> Khushboo
>>
>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:
>>>
>>>> Hi
>>>>
>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> please find the attached updated patch for the test cases of Backup,
>>>>> Restore and Maintenance modules which includes:
>>>>>
>>>>> 1. Unit test cases
>>>>> 2. End to end regression test cases
>>>>> 3. Feature test cases
>>>>>
>>>>
>>>> Thanks. I've yet to be able to run the feature tests successfully.
>>>> Here's what I've found so far:
>>>>
>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>>> config file.
>>>>
>>>> Will do.
>>>
>>>> 2) I've hit screensize related issues:
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.feature_tests.pg_utilities_maintenance_test.
>>>> PGUtilitiesMaintenanceFeatureTest)
>>>>
>>>> Test for PG maintenance: database
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>> utilities_maintenance_test.py", line 56, in runTest
>>>>
>>>>     self._open_maintenance_dialogue()
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>> utilities_maintenance_test.py", line 75, in _open_maintenance_dialogue
>>>>
>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/remote/webelement.py", line 80, in click
>>>>
>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/remote/webelement.py", line 628, in
>>>> _execute
>>>>
>>>>     return self._parent.execute(command, params)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>>>
>>>>     self.error_handler.check_response(response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/remote/errorhandler.py", line 242, in
>>>> check_response
>>>>
>>>>     raise exception_class(message, screen, stacktrace)
>>>>
>>>> WebDriverException: Message: unknown error: Element <span
>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>> element would receive the click: <div class="wcFrameCenter
>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>> 0px; bottom: 0px;">...</div>
>>>>
>>>>   (Session info: chrome=66.0.3359.181)
>>>>
>>>>   (Driver info: chromedriver=2.38.552518 (
>>>> 183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6
>>>> x86_64)
>>>>
>>>> 3) One time the test did start, but then I saw this failure:
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.feature_tests.pg_utilities_backup_restore_test.
>>>> PGUtilitiesBackupFeatureTest)
>>>>
>>>> Test for PG utilities - Backup and Restore
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>> utilities_backup_restore_test.py", line 93, in runTest
>>>>
>>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 211, in fill_input_by_field_name
>>>>
>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 251, in wait_for_input_field_content
>>>>
>>>>     "field to contain '" + str(content) + "'", input_field_has_content
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 337, in _wait_for
>>>>
>>>>     "Timed out waiting for " + waiting_for_message
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/support/wait.py", line 80, in until
>>>>
>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>
>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>> 'test_backup_file'
>>>>
>>>>
>>>>
>>>> (with screenshot attached)
>>>>
>>>> Thanks.
>>>>
>>>> I have ran the feature tests with multiple servers many times but
>>> didn't get a single failure.
>>> I have asked Akshay to run on his machine, let see what he gets.
>>>
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>> Thanks,
>>>>> Khushboo
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Khushboo,
>>>>>>
>>>>>> We reviewed the patch and it is very nice to see some more coverage
>>>>>> in this area. Good job :D
>>>>>>
>>>>>> We passed the tests through our CI the feature tests are not passing,
>>>>>> but the linter fails:
>>>>>>
>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 1       E303 too many blank lines (2)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 2       W391 blank line at end of file
>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>> 38
>>>>>>
>>>>>>
>>>>>> For the feature tests, we realized we had to update the
>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>
>>>>>>
>>>>>> Codewise:
>>>>>> - We just found some One Letter Variables in the code...
>>>>>> - Looks like there is a bug report in this area of the code and we do
>>>>>> not have coverage for it: https://redmine.postgresql.org/issues/3232
>>>>>>   Looks like in some of the unit tests we only have happy path tests,
>>>>>> maybe we should see if there are any sad paths that also need coverage.
>>>>>>
>>>>>> The configuration change, maybe need to be updated. When we install
>>>>>> multiple versions of postgres the binaries live in
>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that
>>>>>> this configuration should live near the server configuration, maybe? Also
>>>>>> to maintain coherency on the naming maybe we should make it all lower case.
>>>>>> Just as an aside, you can add the gpdb configuration as well in you
>>>>>> patch.
>>>>>>
>>>>>> Thanks
>>>>>> Victoria & Joao
>>>>>>
>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>> backup module (RM #3206).
>>>>>>>
>>>>>>> 1. Unit test cases
>>>>>>> 2. End to end regression test cases
>>>>>>> 3. Feature test cases
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Khushboo
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Dave Page
>>>> Blog: http://pgsnake.blogspot.com
>>>> Twitter: @pgsnake
>>>>
>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>> The Enterprise PostgreSQL Company
>>>>
>>>
>>>
>>


Attachments:

  [text/x-patch] RM_3206_ver2.patch (107.0K, 3-RM_3206_ver2.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..b4c1bb2
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..3c0c98c
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..d76a3c7
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,58 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_utils.run_backup_job(self.tester,
+                                    job_id,
+                                    self.expected_params,
+                                    self.assertIn,
+                                    self.assertNotIn
+                                    )
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..64d0d1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,199 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        print(batch_process_mock.call_args_list[0][1]['args'])
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..0953544
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,194 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        backup_utils.run_backup_job(self.tester, job_id,
+                                    self.backup_options['expected_params'],
+                                    self.assertIn, self.assertNotIn)
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def after(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..d5d3a0f 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,47 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..0a1d48e 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,15 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
+                config.DEFAULT_BINARY_PATHS = {
+                    "pg": str(server['default_binary_paths']['pg']),
+                    "ppas": str(server['default_binary_paths']['ppas']),
+                    "gpdb": ""
+                }
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-01 21:31               ` Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Dave Page @ 2018-06-01 21:31 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Victoria Henry <[email protected]>; pgadmin-hackers

Hi

This looks good, except that it's leaving the test_restore_database behind.
Can we clean that up please?

Thanks.

On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
[email protected]> wrote:

> Hi Victoria,
>
> Thanks for reviewing the patch.
> The tests were failing due to the latest commit #
> 2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>
> I have fixed the issues and attached the updated patch.
>
> Thanks,
> Khushboo
>
> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
> wrote:
>
>> Hi there,
>>
>> We've been noticing some issues with the tests on both our CI and local
>> Mac workstations.
>>
>>    1. When the following code blocks are invoked - we get plenty of
>>    app.context() issues. It must not be valid when running tests.
>>
>> ​
>>
>> from pgadmin.utils.driver import get_driver
>> driver = get_driver(PG_DEFAULT_DRIVER)
>> manager = driver.connection_manager(self.sid)
>>
>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>
>> 2. When we finally enable
>>
>> "default_binary_paths": {
>>
>> in our test_config, we get more failing tests that look like:
>>
>> ======================================================================
>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>> When restore object with option - Miscellaneous
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>     return func(*args, **keywargs)
>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>     self.assertEquals(response.status_code, 200)
>> AssertionError: 410 != 200
>>
>> And
>>
>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>> Traceback (most recent call last):
>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>     manager.export_password_env(p.id)
>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>     os.environ[str(env)] = password
>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>     self.putenv(key, value)
>> ValueError: illegal environment variable name
>> FAIL
>>
>> ​
>>
>> Sincerely,
>>
>> Victoria && Anthony
>>
>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi,
>>>
>>> Please find the attached updated patch with the fixes.
>>> The test cases were only failing on MAC not on Linux.
>>>
>>> Thanks,
>>> Khushboo
>>>
>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> please find the attached updated patch for the test cases of Backup,
>>>>>> Restore and Maintenance modules which includes:
>>>>>>
>>>>>> 1. Unit test cases
>>>>>> 2. End to end regression test cases
>>>>>> 3. Feature test cases
>>>>>>
>>>>>
>>>>> Thanks. I've yet to be able to run the feature tests successfully.
>>>>> Here's what I've found so far:
>>>>>
>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>>>> config file.
>>>>>
>>>>> Will do.
>>>>
>>>>> 2) I've hit screensize related issues:
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>
>>>>> Test for PG maintenance: database
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>> line 56, in runTest
>>>>>
>>>>>     self._open_maintenance_dialogue()
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>> line 75, in _open_maintenance_dialogue
>>>>>
>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/remote/webelement.py", line 80, in click
>>>>>
>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/remote/webelement.py", line 628, in _execute
>>>>>
>>>>>     return self._parent.execute(command, params)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>>>>
>>>>>     self.error_handler.check_response(response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/remote/errorhandler.py", line 242, in
>>>>> check_response
>>>>>
>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>
>>>>> WebDriverException: Message: unknown error: Element <span
>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>> element would receive the click: <div class="wcFrameCenter
>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>> 0px; bottom: 0px;">...</div>
>>>>>
>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>
>>>>>   (Driver info: chromedriver=2.38.552518
>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6
>>>>> x86_64)
>>>>>
>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>
>>>>> Test for PG utilities - Backup and Restore
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>> line 93, in runTest
>>>>>
>>>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 211, in fill_input_by_field_name
>>>>>
>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 251, in wait_for_input_field_content
>>>>>
>>>>>     "field to contain '" + str(content) + "'", input_field_has_content
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 337, in _wait_for
>>>>>
>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>
>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>
>>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>>> 'test_backup_file'
>>>>>
>>>>>
>>>>>
>>>>> (with screenshot attached)
>>>>>
>>>>> Thanks.
>>>>>
>>>>> I have ran the feature tests with multiple servers many times but
>>>> didn't get a single failure.
>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Khushboo
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Khushboo,
>>>>>>>
>>>>>>> We reviewed the patch and it is very nice to see some more coverage
>>>>>>> in this area. Good job :D
>>>>>>>
>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>> passing, but the linter fails:
>>>>>>>
>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 2       W391 blank line at end of file
>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>> 38
>>>>>>>
>>>>>>>
>>>>>>> For the feature tests, we realized we had to update the
>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>
>>>>>>>
>>>>>>> Codewise:
>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>> - Looks like there is a bug report in this area of the code and we
>>>>>>> do not have coverage for it: https://redmine.postgresql
>>>>>>> .org/issues/3232
>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>> coverage.
>>>>>>>
>>>>>>> The configuration change, maybe need to be updated. When we install
>>>>>>> multiple versions of postgres the binaries live in
>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that
>>>>>>> this configuration should live near the server configuration, maybe? Also
>>>>>>> to maintain coherency on the naming maybe we should make it all lower case.
>>>>>>> Just as an aside, you can add the gpdb configuration as well in you
>>>>>>> patch.
>>>>>>>
>>>>>>> Thanks
>>>>>>> Victoria & Joao
>>>>>>>
>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>>> backup module (RM #3206).
>>>>>>>>
>>>>>>>> 1. Unit test cases
>>>>>>>> 2. End to end regression test cases
>>>>>>>> 3. Feature test cases
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Khushboo
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Dave Page
>>>>> Blog: http://pgsnake.blogspot.com
>>>>> Twitter: @pgsnake
>>>>>
>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>> The Enterprise PostgreSQL Company
>>>>>
>>>>
>>>>
>>>
>


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
@ 2018-06-04 05:35                 ` Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-04 05:35 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Victoria Henry <[email protected]>; pgadmin-hackers

On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:

> Hi
>
> This looks good, except that it's leaving the test_restore_database
> behind. Can we clean that up please?
>
> PFA updated patch.

> Thanks.
>
> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi Victoria,
>>
>> Thanks for reviewing the patch.
>> The tests were failing due to the latest commit
>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>
>> I have fixed the issues and attached the updated patch.
>>
>> Thanks,
>> Khushboo
>>
>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
>> wrote:
>>
>>> Hi there,
>>>
>>> We've been noticing some issues with the tests on both our CI and local
>>> Mac workstations.
>>>
>>>    1. When the following code blocks are invoked - we get plenty of
>>>    app.context() issues. It must not be valid when running tests.
>>>
>>> ​
>>>
>>> from pgadmin.utils.driver import get_driver
>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>> manager = driver.connection_manager(self.sid)
>>>
>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>
>>> 2. When we finally enable
>>>
>>> "default_binary_paths": {
>>>
>>> in our test_config, we get more failing tests that look like:
>>>
>>> ======================================================================
>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>> When restore object with option - Miscellaneous
>>> ----------------------------------------------------------------------
>>> Traceback (most recent call last):
>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>     return func(*args, **keywargs)
>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>     self.assertEquals(response.status_code, 200)
>>> AssertionError: 410 != 200
>>>
>>> And
>>>
>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>> Traceback (most recent call last):
>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>     manager.export_password_env(p.id)
>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>     os.environ[str(env)] = password
>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>     self.putenv(key, value)
>>> ValueError: illegal environment variable name
>>> FAIL
>>>
>>> ​
>>>
>>> Sincerely,
>>>
>>> Victoria && Anthony
>>>
>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>>
>>>> Please find the attached updated patch with the fixes.
>>>> The test cases were only failing on MAC not on Linux.
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> please find the attached updated patch for the test cases of Backup,
>>>>>>> Restore and Maintenance modules which includes:
>>>>>>>
>>>>>>> 1. Unit test cases
>>>>>>> 2. End to end regression test cases
>>>>>>> 3. Feature test cases
>>>>>>>
>>>>>>
>>>>>> Thanks. I've yet to be able to run the feature tests successfully.
>>>>>> Here's what I've found so far:
>>>>>>
>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>>>>> config file.
>>>>>>
>>>>>> Will do.
>>>>>
>>>>>> 2) I've hit screensize related issues:
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>
>>>>>> Test for PG maintenance: database
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>> line 56, in runTest
>>>>>>
>>>>>>     self._open_maintenance_dialogue()
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>
>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/remote/webelement.py", line 80, in click
>>>>>>
>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/remote/webelement.py", line 628, in _execute
>>>>>>
>>>>>>     return self._parent.execute(command, params)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>>>>>
>>>>>>     self.error_handler.check_response(response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/remote/errorhandler.py", line 242, in
>>>>>> check_response
>>>>>>
>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>
>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>
>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>
>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6
>>>>>> x86_64)
>>>>>>
>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>
>>>>>> Test for PG utilities - Backup and Restore
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>> line 93, in runTest
>>>>>>
>>>>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 211, in fill_input_by_field_name
>>>>>>
>>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 251, in wait_for_input_field_content
>>>>>>
>>>>>>     "field to contain '" + str(content) + "'",
>>>>>> input_field_has_content
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 337, in _wait_for
>>>>>>
>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>>
>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>
>>>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>>>> 'test_backup_file'
>>>>>>
>>>>>>
>>>>>>
>>>>>> (with screenshot attached)
>>>>>>
>>>>>> Thanks.
>>>>>>
>>>>>> I have ran the feature tests with multiple servers many times but
>>>>> didn't get a single failure.
>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Khushboo
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Khushboo,
>>>>>>>>
>>>>>>>> We reviewed the patch and it is very nice to see some more coverage
>>>>>>>> in this area. Good job :D
>>>>>>>>
>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>> passing, but the linter fails:
>>>>>>>>
>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>> 38
>>>>>>>>
>>>>>>>>
>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>
>>>>>>>>
>>>>>>>> Codewise:
>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>> - Looks like there is a bug report in this area of the code and we
>>>>>>>> do not have coverage for it: https://redmine.postgresql
>>>>>>>> .org/issues/3232
>>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>>> coverage.
>>>>>>>>
>>>>>>>> The configuration change, maybe need to be updated. When we install
>>>>>>>> multiple versions of postgres the binaries live in
>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think
>>>>>>>> that this configuration should live near the server configuration, maybe?
>>>>>>>> Also to maintain coherency on the naming maybe we should make it all lower
>>>>>>>> case.
>>>>>>>> Just as an aside, you can add the gpdb configuration as well in you
>>>>>>>> patch.
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Victoria & Joao
>>>>>>>>
>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>>>> backup module (RM #3206).
>>>>>>>>>
>>>>>>>>> 1. Unit test cases
>>>>>>>>> 2. End to end regression test cases
>>>>>>>>> 3. Feature test cases
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Khushboo
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Dave Page
>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>> Twitter: @pgsnake
>>>>>>
>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>> The Enterprise PostgreSQL Company
>>>>>>
>>>>>
>>>>>
>>>>
>>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


Attachments:

  [application/octet-stream] RM_3206_ver3.patch (107.0K, 3-RM_3206_ver3.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..b4c1bb2
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..3c0c98c
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..d76a3c7
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,58 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_utils.run_backup_job(self.tester,
+                                    job_id,
+                                    self.expected_params,
+                                    self.assertIn,
+                                    self.assertNotIn
+                                    )
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..64d0d1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,199 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        print(batch_process_mock.call_args_list[0][1]['args'])
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..1a0c90b
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,194 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        backup_utils.run_backup_job(self.tester, job_id,
+                                    self.backup_options['expected_params'],
+                                    self.assertIn, self.assertNotIn)
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..d5d3a0f 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,47 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..0a1d48e 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,15 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
+                config.DEFAULT_BINARY_PATHS = {
+                    "pg": str(server['default_binary_paths']['pg']),
+                    "ppas": str(server['default_binary_paths']['ppas']),
+                    "gpdb": ""
+                }
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-04 15:11                   ` Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Joao De Almeida Pereira @ 2018-06-04 15:11 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Dave Page <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers

Hi Khushboo,

Some tests are failing in greenplum:
https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-tests/builds/108
The piece of code responsible for the error is:

if server['default_binary_paths'] is not None:
    test_utils.set_preference(server['default_binary_paths'])

    config.DEFAULT_BINARY_PATHS = {
        "pg": str(server['default_binary_paths']['pg']),
        "ppas": str(server['default_binary_paths']['ppas']),
        "gpdb": ""
    }


test_backup_utils.py file name is misleading, these are not tests, are
helpers.
​


Thanks
Victoria & Joao

On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
[email protected]> wrote:

>
>
> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>
>> Hi
>>
>> This looks good, except that it's leaving the test_restore_database
>> behind. Can we clean that up please?
>>
>> PFA updated patch.
>
>> Thanks.
>>
>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi Victoria,
>>>
>>> Thanks for reviewing the patch.
>>> The tests were failing due to the latest commit
>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>
>>> I have fixed the issues and attached the updated patch.
>>>
>>> Thanks,
>>> Khushboo
>>>
>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
>>> wrote:
>>>
>>>> Hi there,
>>>>
>>>> We've been noticing some issues with the tests on both our CI and local
>>>> Mac workstations.
>>>>
>>>>    1. When the following code blocks are invoked - we get plenty of
>>>>    app.context() issues. It must not be valid when running tests.
>>>>
>>>> ​
>>>>
>>>> from pgadmin.utils.driver import get_driver
>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>> manager = driver.connection_manager(self.sid)
>>>>
>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>
>>>> 2. When we finally enable
>>>>
>>>> "default_binary_paths": {
>>>>
>>>> in our test_config, we get more failing tests that look like:
>>>>
>>>> ======================================================================
>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>> When restore object with option - Miscellaneous
>>>> ----------------------------------------------------------------------
>>>> Traceback (most recent call last):
>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>     return func(*args, **keywargs)
>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>     self.assertEquals(response.status_code, 200)
>>>> AssertionError: 410 != 200
>>>>
>>>> And
>>>>
>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>> Traceback (most recent call last):
>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>     manager.export_password_env(p.id)
>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>     os.environ[str(env)] = password
>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>     self.putenv(key, value)
>>>> ValueError: illegal environment variable name
>>>> FAIL
>>>>
>>>> ​
>>>>
>>>> Sincerely,
>>>>
>>>> Victoria && Anthony
>>>>
>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> Please find the attached updated patch with the fixes.
>>>>> The test cases were only failing on MAC not on Linux.
>>>>>
>>>>> Thanks,
>>>>> Khushboo
>>>>>
>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]> wrote:
>>>>>>
>>>>>>> Hi
>>>>>>>
>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>
>>>>>>>> 1. Unit test cases
>>>>>>>> 2. End to end regression test cases
>>>>>>>> 3. Feature test cases
>>>>>>>>
>>>>>>>
>>>>>>> Thanks. I've yet to be able to run the feature tests successfully.
>>>>>>> Here's what I've found so far:
>>>>>>>
>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>>>>>> config file.
>>>>>>>
>>>>>>> Will do.
>>>>>>
>>>>>>> 2) I've hit screensize related issues:
>>>>>>>
>>>>>>>
>>>>>>> ======================================================================
>>>>>>>
>>>>>>> ERROR: runTest
>>>>>>> (pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>
>>>>>>> Test for PG maintenance: database
>>>>>>>
>>>>>>>
>>>>>>> ----------------------------------------------------------------------
>>>>>>>
>>>>>>> Traceback (most recent call last):
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>> line 56, in runTest
>>>>>>>
>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>
>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>> line 80, in click
>>>>>>>
>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>> line 628, in _execute
>>>>>>>
>>>>>>>     return self._parent.execute(command, params)
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>> line 312, in execute
>>>>>>>
>>>>>>>     self.error_handler.check_response(response)
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>> line 242, in check_response
>>>>>>>
>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>
>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>
>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>
>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6 x86_64)
>>>>>>>
>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>
>>>>>>>
>>>>>>> ======================================================================
>>>>>>>
>>>>>>> ERROR: runTest
>>>>>>> (pgadmin.feature_tests.pg_utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>
>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>
>>>>>>>
>>>>>>> ----------------------------------------------------------------------
>>>>>>>
>>>>>>> Traceback (most recent call last):
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>> line 93, in runTest
>>>>>>>
>>>>>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>> line 211, in fill_input_by_field_name
>>>>>>>
>>>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>> line 251, in wait_for_input_field_content
>>>>>>>
>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>> input_field_has_content
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>> line 337, in _wait_for
>>>>>>>
>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>
>>>>>>>   File
>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>> line 80, in until
>>>>>>>
>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>
>>>>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>>>>> 'test_backup_file'
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> (with screenshot attached)
>>>>>>>
>>>>>>> Thanks.
>>>>>>>
>>>>>>> I have ran the feature tests with multiple servers many times but
>>>>>> didn't get a single failure.
>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Khushboo
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Khushboo,
>>>>>>>>>
>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>
>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>> passing, but the linter fails:
>>>>>>>>>
>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>> 38
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Codewise:
>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>> - Looks like there is a bug report in this area of the code and we
>>>>>>>>> do not have coverage for it:
>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>>>> coverage.
>>>>>>>>>
>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that this
>>>>>>>>> configuration should live near the server configuration, maybe? Also to
>>>>>>>>> maintain coherency on the naming maybe we should make it all lower case.
>>>>>>>>> Just as an aside, you can add the gpdb configuration as well in
>>>>>>>>> you patch.
>>>>>>>>>
>>>>>>>>> Thanks
>>>>>>>>> Victoria & Joao
>>>>>>>>>
>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>>>>> backup module (RM #3206).
>>>>>>>>>>
>>>>>>>>>> 1. Unit test cases
>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Khushboo
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Dave Page
>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>> Twitter: @pgsnake
>>>>>>>
>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>
>>
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>
>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
@ 2018-06-05 03:39                     ` Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-05 03:39 UTC (permalink / raw)
  To: Joao De Almeida Pereira <[email protected]>; +Cc: Dave Page <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers

On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
[email protected]> wrote:

> Hi Khushboo,
>
> Some tests are failing in greenplum:
> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/
> pipelines/pgadmin-patch/jobs/run-tests/builds/108
> The piece of code responsible for the error is:
>
> if server['default_binary_paths'] is not None:
>     test_utils.set_preference(server['default_binary_paths'])
>
>     config.DEFAULT_BINARY_PATHS = {
>         "pg": str(server['default_binary_paths']['pg']),
>         "ppas": str(server['default_binary_paths']['ppas']),
>         "gpdb": ""
>     }
>
>
> Can you send me the test_config.json file?  The above code sets the paths
to the SQLite database and through the logs couldn't figure out the exact
failure.

> test_backup_utils.py file name is misleading, these are not tests, are
> helpers.
> ​
>
>
> Thanks
> Victoria & Joao
>
> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
> [email protected]> wrote:
>
>>
>>
>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>>
>>> Hi
>>>
>>> This looks good, except that it's leaving the test_restore_database
>>> behind. Can we clean that up please?
>>>
>>> PFA updated patch.
>>
>>> Thanks.
>>>
>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi Victoria,
>>>>
>>>> Thanks for reviewing the patch.
>>>> The tests were failing due to the latest commit #
>>>> 2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>
>>>> I have fixed the issues and attached the updated patch.
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
>>>> wrote:
>>>>
>>>>> Hi there,
>>>>>
>>>>> We've been noticing some issues with the tests on both our CI and
>>>>> local Mac workstations.
>>>>>
>>>>>    1. When the following code blocks are invoked - we get plenty of
>>>>>    app.context() issues. It must not be valid when running tests.
>>>>>
>>>>> ​
>>>>>
>>>>> from pgadmin.utils.driver import get_driver
>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>> manager = driver.connection_manager(self.sid)
>>>>>
>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>
>>>>> 2. When we finally enable
>>>>>
>>>>> "default_binary_paths": {
>>>>>
>>>>> in our test_config, we get more failing tests that look like:
>>>>>
>>>>> ======================================================================
>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>> When restore object with option - Miscellaneous
>>>>> ----------------------------------------------------------------------
>>>>> Traceback (most recent call last):
>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>     return func(*args, **keywargs)
>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>     self.assertEquals(response.status_code, 200)
>>>>> AssertionError: 410 != 200
>>>>>
>>>>> And
>>>>>
>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>> Traceback (most recent call last):
>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>     manager.export_password_env(p.id)
>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>     os.environ[str(env)] = password
>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>     self.putenv(key, value)
>>>>> ValueError: illegal environment variable name
>>>>> FAIL
>>>>>
>>>>> ​
>>>>>
>>>>> Sincerely,
>>>>>
>>>>> Victoria && Anthony
>>>>>
>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Please find the attached updated patch with the fixes.
>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>
>>>>>> Thanks,
>>>>>> Khushboo
>>>>>>
>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi
>>>>>>>>
>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>
>>>>>>>>> 1. Unit test cases
>>>>>>>>> 2. End to end regression test cases
>>>>>>>>> 3. Feature test cases
>>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks. I've yet to be able to run the feature tests successfully.
>>>>>>>> Here's what I've found so far:
>>>>>>>>
>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>>>>>>> config file.
>>>>>>>>
>>>>>>>> Will do.
>>>>>>>
>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==========
>>>>>>>>
>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_
>>>>>>>> utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>
>>>>>>>> Test for PG maintenance: database
>>>>>>>>
>>>>>>>> ------------------------------------------------------------
>>>>>>>> ----------
>>>>>>>>
>>>>>>>> Traceback (most recent call last):
>>>>>>>>
>>>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>>>>>> utilities_maintenance_test.py", line 56, in runTest
>>>>>>>>
>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>
>>>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>>>>>> utilities_maintenance_test.py", line 75, in
>>>>>>>> _open_maintenance_dialogue
>>>>>>>>
>>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>>
>>>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>>>>>> packages/selenium/webdriver/remote/webelement.py", line 80, in
>>>>>>>> click
>>>>>>>>
>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>
>>>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>>>>>> packages/selenium/webdriver/remote/webelement.py", line 628, in
>>>>>>>> _execute
>>>>>>>>
>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>
>>>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>>>>>> packages/selenium/webdriver/remote/webdriver.py", line 312, in
>>>>>>>> execute
>>>>>>>>
>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>
>>>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>>>>>> packages/selenium/webdriver/remote/errorhandler.py", line 242, in
>>>>>>>> check_response
>>>>>>>>
>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>
>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>
>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>
>>>>>>>>   (Driver info: chromedriver=2.38.552518 (
>>>>>>>> 183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X
>>>>>>>> 10.12.6 x86_64)
>>>>>>>>
>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==========
>>>>>>>>
>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_
>>>>>>>> utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>
>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>
>>>>>>>> ------------------------------------------------------------
>>>>>>>> ----------
>>>>>>>>
>>>>>>>> Traceback (most recent call last):
>>>>>>>>
>>>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>>>>>> utilities_backup_restore_test.py", line 93, in runTest
>>>>>>>>
>>>>>>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>>>>>>
>>>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>>> line 211, in fill_input_by_field_name
>>>>>>>>
>>>>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>>>>
>>>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>>> line 251, in wait_for_input_field_content
>>>>>>>>
>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>> input_field_has_content
>>>>>>>>
>>>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>>> line 337, in _wait_for
>>>>>>>>
>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>
>>>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>>>>>> packages/selenium/webdriver/support/wait.py", line 80, in until
>>>>>>>>
>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>
>>>>>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>>>>>> 'test_backup_file'
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> (with screenshot attached)
>>>>>>>>
>>>>>>>> Thanks.
>>>>>>>>
>>>>>>>> I have ran the feature tests with multiple servers many times but
>>>>>>> didn't get a single failure.
>>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Khushboo
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>
>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>
>>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>>> passing, but the linter fails:
>>>>>>>>>>
>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>> 38
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Codewise:
>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>> - Looks like there is a bug report in this area of the code and
>>>>>>>>>> we do not have coverage for it: https://redmine.
>>>>>>>>>> postgresql.org/issues/3232
>>>>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>> coverage.
>>>>>>>>>>
>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think
>>>>>>>>>> that this configuration should live near the server configuration, maybe?
>>>>>>>>>> Also to maintain coherency on the naming maybe we should make it all lower
>>>>>>>>>> case.
>>>>>>>>>> Just as an aside, you can add the gpdb configuration as well in
>>>>>>>>>> you patch.
>>>>>>>>>>
>>>>>>>>>> Thanks
>>>>>>>>>> Victoria & Joao
>>>>>>>>>>
>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>>>>>> backup module (RM #3206).
>>>>>>>>>>>
>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Khushboo
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Dave Page
>>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>>> Twitter: @pgsnake
>>>>>>>>
>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>
>>>
>>>
>>> --
>>> Dave Page
>>> Blog: http://pgsnake.blogspot.com
>>> Twitter: @pgsnake
>>>
>>> EnterpriseDB UK: http://www.enterprisedb.com
>>> The Enterprise PostgreSQL Company
>>>
>>
>>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-05 08:06                       ` Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Dave Page @ 2018-06-05 08:06 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Joao De Almeida Pereira <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers

Hi

On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
[email protected]> wrote:

>
>
> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
> [email protected]> wrote:
>
>> Hi Khushboo,
>>
>> Some tests are failing in greenplum:
>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>> /pgadmin-patch/jobs/run-tests/builds/108
>> The piece of code responsible for the error is:
>>
>> if server['default_binary_paths'] is not None:
>>     test_utils.set_preference(server['default_binary_paths'])
>>
>>     config.DEFAULT_BINARY_PATHS = {
>>         "pg": str(server['default_binary_paths']['pg']),
>>         "ppas": str(server['default_binary_paths']['ppas']),
>>         "gpdb": ""
>>     }
>>
>>
>> Can you send me the test_config.json file?  The above code sets the paths
> to the SQLite database and through the logs couldn't figure out the exact
> failure.
>

It seems clear from the code shown that it's not setting the binary paths
for gpdb database servers. Shouldn't it be something like:

    config.DEFAULT_BINARY_PATHS = {
        "pg": str(server['default_binary_paths']['pg']),
        "ppas": str(server['default_binary_paths']['ppas']),
        "gpdb": str(server['default_binary_paths']['gpdb'])
    }




> test_backup_utils.py file name is misleading, these are not tests, are
>> helpers.
>> ​
>>
>>
>> Thanks
>> Victoria & Joao
>>
>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>>>
>>>> Hi
>>>>
>>>> This looks good, except that it's leaving the test_restore_database
>>>> behind. Can we clean that up please?
>>>>
>>>> PFA updated patch.
>>>
>>>> Thanks.
>>>>
>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Victoria,
>>>>>
>>>>> Thanks for reviewing the patch.
>>>>> The tests were failing due to the latest commit
>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>
>>>>> I have fixed the issues and attached the updated patch.
>>>>>
>>>>> Thanks,
>>>>> Khushboo
>>>>>
>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Hi there,
>>>>>>
>>>>>> We've been noticing some issues with the tests on both our CI and
>>>>>> local Mac workstations.
>>>>>>
>>>>>>    1. When the following code blocks are invoked - we get plenty of
>>>>>>    app.context() issues. It must not be valid when running tests.
>>>>>>
>>>>>> ​
>>>>>>
>>>>>> from pgadmin.utils.driver import get_driver
>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>
>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>
>>>>>> 2. When we finally enable
>>>>>>
>>>>>> "default_binary_paths": {
>>>>>>
>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>
>>>>>> ======================================================================
>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>> When restore object with option - Miscellaneous
>>>>>> ----------------------------------------------------------------------
>>>>>> Traceback (most recent call last):
>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>     return func(*args, **keywargs)
>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>> AssertionError: 410 != 200
>>>>>>
>>>>>> And
>>>>>>
>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>> Traceback (most recent call last):
>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>     manager.export_password_env(p.id)
>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>     os.environ[str(env)] = password
>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>     self.putenv(key, value)
>>>>>> ValueError: illegal environment variable name
>>>>>> FAIL
>>>>>>
>>>>>> ​
>>>>>>
>>>>>> Sincerely,
>>>>>>
>>>>>> Victoria && Anthony
>>>>>>
>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Khushboo
>>>>>>>
>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi
>>>>>>>>>
>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>
>>>>>>>>>> 1. Unit test cases
>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks. I've yet to be able to run the feature tests successfully.
>>>>>>>>> Here's what I've found so far:
>>>>>>>>>
>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the JSON
>>>>>>>>> config file.
>>>>>>>>>
>>>>>>>>> Will do.
>>>>>>>>
>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>
>>>>>>>>> ============================================================
>>>>>>>>> ==========
>>>>>>>>>
>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>
>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>
>>>>>>>>> ------------------------------------------------------------
>>>>>>>>> ----------
>>>>>>>>>
>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>> 56, in runTest
>>>>>>>>>
>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>> 75, in _open_maintenance_dialogue
>>>>>>>>>
>>>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>> line 80, in click
>>>>>>>>>
>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>> line 628, in _execute
>>>>>>>>>
>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>> line 312, in execute
>>>>>>>>>
>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>> line 242, in check_response
>>>>>>>>>
>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>
>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>
>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>
>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X
>>>>>>>>> 10.12.6 x86_64)
>>>>>>>>>
>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>
>>>>>>>>> ============================================================
>>>>>>>>> ==========
>>>>>>>>>
>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>
>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>
>>>>>>>>> ------------------------------------------------------------
>>>>>>>>> ----------
>>>>>>>>>
>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py", line
>>>>>>>>> 93, in runTest
>>>>>>>>>
>>>>>>>>>     self.page.fill_input_by_field_name("file", "test_backup_file")
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>> fill_input_by_field_name
>>>>>>>>>
>>>>>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>> wait_for_input_field_content
>>>>>>>>>
>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>> input_field_has_content
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in _wait_for
>>>>>>>>>
>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>
>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>> line 80, in until
>>>>>>>>>
>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>
>>>>>>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>>>>>>> 'test_backup_file'
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> (with screenshot attached)
>>>>>>>>>
>>>>>>>>> Thanks.
>>>>>>>>>
>>>>>>>>> I have ran the feature tests with multiple servers many times but
>>>>>>>> didn't get a single failure.
>>>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Khushboo
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>
>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>
>>>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>>>> passing, but the linter fails:
>>>>>>>>>>>
>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>> 38
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Codewise:
>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>> - Looks like there is a bug report in this area of the code and
>>>>>>>>>>> we do not have coverage for it: https://redmine.postgresql
>>>>>>>>>>> .org/issues/3232
>>>>>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>> coverage.
>>>>>>>>>>>
>>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think
>>>>>>>>>>> that this configuration should live near the server configuration, maybe?
>>>>>>>>>>> Also to maintain coherency on the naming maybe we should make it all lower
>>>>>>>>>>> case.
>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as well in
>>>>>>>>>>> you patch.
>>>>>>>>>>>
>>>>>>>>>>> Thanks
>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>
>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi,
>>>>>>>>>>>>
>>>>>>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>>>>>>> backup module (RM #3206).
>>>>>>>>>>>>
>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Dave Page
>>>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>>>> Twitter: @pgsnake
>>>>>>>>>
>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Dave Page
>>>> Blog: http://pgsnake.blogspot.com
>>>> Twitter: @pgsnake
>>>>
>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>> The Enterprise PostgreSQL Company
>>>>
>>>
>>>
>


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
@ 2018-06-05 08:37                         ` Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-05 08:37 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Joao De Almeida Pereira <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers

On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:

> Hi
>
> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>>
>>
>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>> [email protected]> wrote:
>>
>>> Hi Khushboo,
>>>
>>> Some tests are failing in greenplum:
>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>> /pgadmin-patch/jobs/run-tests/builds/108
>>> The piece of code responsible for the error is:
>>>
>>> if server['default_binary_paths'] is not None:
>>>     test_utils.set_preference(server['default_binary_paths'])
>>>
>>>     config.DEFAULT_BINARY_PATHS = {
>>>         "pg": str(server['default_binary_paths']['pg']),
>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>         "gpdb": ""
>>>     }
>>>
>>>
>>> Can you send me the test_config.json file?  The above code sets the
>> paths to the SQLite database and through the logs couldn't figure out the
>> exact failure.
>>
>
> It seems clear from the code shown that it's not setting the binary paths
> for gpdb database servers. Shouldn't it be something like:
>
>     config.DEFAULT_BINARY_PATHS = {
>         "pg": str(server['default_binary_paths']['pg']),
>         "ppas": str(server['default_binary_paths']['ppas']),
>         "gpdb": str(server['default_binary_paths']['gpdb'])
>     }
>
> Without this code, the test cases should work as I already set  paths
through below code.

    test_utils.set_preference(server['default_binary_paths'])


>
>> test_backup_utils.py file name is misleading, these are not tests, are
>>> helpers.
>>> ​
>>>
>>>
>>> Thanks
>>> Victoria & Joao
>>>
>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> This looks good, except that it's leaving the test_restore_database
>>>>> behind. Can we clean that up please?
>>>>>
>>>>> PFA updated patch.
>>>>
>>>>> Thanks.
>>>>>
>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Victoria,
>>>>>>
>>>>>> Thanks for reviewing the patch.
>>>>>> The tests were failing due to the latest commit
>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>
>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>
>>>>>> Thanks,
>>>>>> Khushboo
>>>>>>
>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi there,
>>>>>>>
>>>>>>> We've been noticing some issues with the tests on both our CI and
>>>>>>> local Mac workstations.
>>>>>>>
>>>>>>>    1. When the following code blocks are invoked - we get plenty of
>>>>>>>    app.context() issues. It must not be valid when running tests.
>>>>>>>
>>>>>>> ​
>>>>>>>
>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>
>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>
>>>>>>> 2. When we finally enable
>>>>>>>
>>>>>>> "default_binary_paths": {
>>>>>>>
>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>
>>>>>>> ======================================================================
>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>> When restore object with option - Miscellaneous
>>>>>>> ----------------------------------------------------------------------
>>>>>>> Traceback (most recent call last):
>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>     return func(*args, **keywargs)
>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>> AssertionError: 410 != 200
>>>>>>>
>>>>>>> And
>>>>>>>
>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>> Traceback (most recent call last):
>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>     manager.export_password_env(p.id)
>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>     os.environ[str(env)] = password
>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>     self.putenv(key, value)
>>>>>>> ValueError: illegal environment variable name
>>>>>>> FAIL
>>>>>>>
>>>>>>> ​
>>>>>>>
>>>>>>> Sincerely,
>>>>>>>
>>>>>>> Victoria && Anthony
>>>>>>>
>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Khushboo
>>>>>>>>
>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Hi
>>>>>>>>>>
>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>
>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>
>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the
>>>>>>>>>> JSON config file.
>>>>>>>>>>
>>>>>>>>>> Will do.
>>>>>>>>>
>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>
>>>>>>>>>> ============================================================
>>>>>>>>>> ==========
>>>>>>>>>>
>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>
>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>
>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>> ----------
>>>>>>>>>>
>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>>> 56, in runTest
>>>>>>>>>>
>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>>> 75, in _open_maintenance_dialogue
>>>>>>>>>>
>>>>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>> line 80, in click
>>>>>>>>>>
>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>> line 628, in _execute
>>>>>>>>>>
>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>>> line 312, in execute
>>>>>>>>>>
>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>>> line 242, in check_response
>>>>>>>>>>
>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>
>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>
>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>
>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X
>>>>>>>>>> 10.12.6 x86_64)
>>>>>>>>>>
>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>
>>>>>>>>>> ============================================================
>>>>>>>>>> ==========
>>>>>>>>>>
>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>
>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>
>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>> ----------
>>>>>>>>>>
>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>> line 93, in runTest
>>>>>>>>>>
>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>> "test_backup_file")
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>
>>>>>>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>
>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>> input_field_has_content
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>> _wait_for
>>>>>>>>>>
>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>
>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>>> line 80, in until
>>>>>>>>>>
>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>
>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to contain
>>>>>>>>>> 'test_backup_file'
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>
>>>>>>>>>> Thanks.
>>>>>>>>>>
>>>>>>>>>> I have ran the feature tests with multiple servers many times but
>>>>>>>>> didn't get a single failure.
>>>>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Khushboo
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>
>>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>>
>>>>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>>>>> passing, but the linter fails:
>>>>>>>>>>>>
>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>> 38
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Codewise:
>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>> - Looks like there is a bug report in this area of the code and
>>>>>>>>>>>> we do not have coverage for it: https://redmine.postgresql
>>>>>>>>>>>> .org/issues/3232
>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>> coverage.
>>>>>>>>>>>>
>>>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think
>>>>>>>>>>>> that this configuration should live near the server configuration, maybe?
>>>>>>>>>>>> Also to maintain coherency on the naming maybe we should make it all lower
>>>>>>>>>>>> case.
>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as well in
>>>>>>>>>>>> you patch.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks
>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>
>>>>>>>>>>>>> Please find the attached patch which covers test cases for the
>>>>>>>>>>>>> backup module (RM #3206).
>>>>>>>>>>>>>
>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Dave Page
>>>>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>>>>> Twitter: @pgsnake
>>>>>>>>>>
>>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Dave Page
>>>>> Blog: http://pgsnake.blogspot.com
>>>>> Twitter: @pgsnake
>>>>>
>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>> The Enterprise PostgreSQL Company
>>>>>
>>>>
>>>>
>>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-05 08:39                           ` Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Dave Page @ 2018-06-05 08:39 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Joao De Almeida Pereira <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers

On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
[email protected]> wrote:

>
>
> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:
>
>> Hi
>>
>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>> [email protected]> wrote:
>>>
>>>> Hi Khushboo,
>>>>
>>>> Some tests are failing in greenplum:
>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>> /pgadmin-patch/jobs/run-tests/builds/108
>>>> The piece of code responsible for the error is:
>>>>
>>>> if server['default_binary_paths'] is not None:
>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>
>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>         "gpdb": ""
>>>>     }
>>>>
>>>>
>>>> Can you send me the test_config.json file?  The above code sets the
>>> paths to the SQLite database and through the logs couldn't figure out the
>>> exact failure.
>>>
>>
>> It seems clear from the code shown that it's not setting the binary paths
>> for gpdb database servers. Shouldn't it be something like:
>>
>>     config.DEFAULT_BINARY_PATHS = {
>>         "pg": str(server['default_binary_paths']['pg']),
>>         "ppas": str(server['default_binary_paths']['ppas']),
>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>     }
>>
>> Without this code, the test cases should work as I already set  paths
> through below code.
>
>     test_utils.set_preference(server['default_binary_paths'])
>
>
In that case, why is the code above required at all?



>
>>
>>> test_backup_utils.py file name is misleading, these are not tests, are
>>>> helpers.
>>>> ​
>>>>
>>>>
>>>> Thanks
>>>> Victoria & Joao
>>>>
>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> This looks good, except that it's leaving the test_restore_database
>>>>>> behind. Can we clean that up please?
>>>>>>
>>>>>> PFA updated patch.
>>>>>
>>>>>> Thanks.
>>>>>>
>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Victoria,
>>>>>>>
>>>>>>> Thanks for reviewing the patch.
>>>>>>> The tests were failing due to the latest commit
>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>
>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Khushboo
>>>>>>>
>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi there,
>>>>>>>>
>>>>>>>> We've been noticing some issues with the tests on both our CI and
>>>>>>>> local Mac workstations.
>>>>>>>>
>>>>>>>>    1. When the following code blocks are invoked - we get plenty
>>>>>>>>    of app.context() issues. It must not be valid when running
>>>>>>>>    tests.
>>>>>>>>
>>>>>>>> ​
>>>>>>>>
>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>
>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>
>>>>>>>> 2. When we finally enable
>>>>>>>>
>>>>>>>> "default_binary_paths": {
>>>>>>>>
>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>
>>>>>>>> ======================================================================
>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>> ----------------------------------------------------------------------
>>>>>>>> Traceback (most recent call last):
>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>> AssertionError: 410 != 200
>>>>>>>>
>>>>>>>> And
>>>>>>>>
>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>> Traceback (most recent call last):
>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>     self.putenv(key, value)
>>>>>>>> ValueError: illegal environment variable name
>>>>>>>> FAIL
>>>>>>>>
>>>>>>>> ​
>>>>>>>>
>>>>>>>> Sincerely,
>>>>>>>>
>>>>>>>> Victoria && Anthony
>>>>>>>>
>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Khushboo
>>>>>>>>>
>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi
>>>>>>>>>>>
>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi,
>>>>>>>>>>>>
>>>>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>
>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>
>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the
>>>>>>>>>>> JSON config file.
>>>>>>>>>>>
>>>>>>>>>>> Will do.
>>>>>>>>>>
>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>
>>>>>>>>>>> ============================================================
>>>>>>>>>>> ==========
>>>>>>>>>>>
>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>
>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>
>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>> ----------
>>>>>>>>>>>
>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>>>> 56, in runTest
>>>>>>>>>>>
>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>>>> 75, in _open_maintenance_dialogue
>>>>>>>>>>>
>>>>>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>> line 80, in click
>>>>>>>>>>>
>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>> line 628, in _execute
>>>>>>>>>>>
>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>>>> line 312, in execute
>>>>>>>>>>>
>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>>>> line 242, in check_response
>>>>>>>>>>>
>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>
>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>
>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>
>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X
>>>>>>>>>>> 10.12.6 x86_64)
>>>>>>>>>>>
>>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>>
>>>>>>>>>>> ============================================================
>>>>>>>>>>> ==========
>>>>>>>>>>>
>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>
>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>
>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>> ----------
>>>>>>>>>>>
>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>
>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>>
>>>>>>>>>>>     self.wait_for_input_field_content(field_name, field_content)
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>>
>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>>> _wait_for
>>>>>>>>>>>
>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>
>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>>>> line 80, in until
>>>>>>>>>>>
>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>
>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>
>>>>>>>>>>> Thanks.
>>>>>>>>>>>
>>>>>>>>>>> I have ran the feature tests with multiple servers many times
>>>>>>>>>> but didn't get a single failure.
>>>>>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>
>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>>>
>>>>>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>>>>>> passing, but the linter fails:
>>>>>>>>>>>>>
>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>> 38
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>> - Looks like there is a bug report in this area of the code
>>>>>>>>>>>>> and we do not have coverage for it: https://redmine.postgresql
>>>>>>>>>>>>> .org/issues/3232
>>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy path
>>>>>>>>>>>>> tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>>> coverage.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us
>>>>>>>>>>>>> think that this configuration should live near the server configuration,
>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as well
>>>>>>>>>>>>> in you patch.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Please find the attached patch which covers test cases for
>>>>>>>>>>>>>> the backup module (RM #3206).
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Dave Page
>>>>>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>>>>>> Twitter: @pgsnake
>>>>>>>>>>>
>>>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Dave Page
>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>> Twitter: @pgsnake
>>>>>>
>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>> The Enterprise PostgreSQL Company
>>>>>>
>>>>>
>>>>>
>>>
>>
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>
>


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
@ 2018-06-05 08:50                             ` Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-05 08:50 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Joao De Almeida Pereira <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers

On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:

>
>
> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>>
>>
>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:
>>
>>> Hi
>>>
>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Khushboo,
>>>>>
>>>>> Some tests are failing in greenplum:
>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>> /pgadmin-patch/jobs/run-tests/builds/108
>>>>> The piece of code responsible for the error is:
>>>>>
>>>>> if server['default_binary_paths'] is not None:
>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>
>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>         "gpdb": ""
>>>>>     }
>>>>>
>>>>>
>>>>> Can you send me the test_config.json file?  The above code sets the
>>>> paths to the SQLite database and through the logs couldn't figure out the
>>>> exact failure.
>>>>
>>>
>>> It seems clear from the code shown that it's not setting the binary
>>> paths for gpdb database servers. Shouldn't it be something like:
>>>
>>>     config.DEFAULT_BINARY_PATHS = {
>>>         "pg": str(server['default_binary_paths']['pg']),
>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>     }
>>>
>>> Without this code, the test cases should work as I already set  paths
>> through below code.
>>
>>     test_utils.set_preference(server['default_binary_paths'])
>>
>>
> In that case, why is the code above required at all?
>
> My bad. Removed this code and also updated set_preference function for
greenplum database.
Please find the attached updated patch.

>
>
>>
>>>
>>>> test_backup_utils.py file name is misleading, these are not tests, are
>>>>> helpers.
>>>>> ​
>>>>>
>>>>>
>>>>> Thanks
>>>>> Victoria & Joao
>>>>>
>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>>>>>>
>>>>>>> Hi
>>>>>>>
>>>>>>> This looks good, except that it's leaving the test_restore_database
>>>>>>> behind. Can we clean that up please?
>>>>>>>
>>>>>>> PFA updated patch.
>>>>>>
>>>>>>> Thanks.
>>>>>>>
>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Victoria,
>>>>>>>>
>>>>>>>> Thanks for reviewing the patch.
>>>>>>>> The tests were failing due to the latest commit
>>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>
>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Khushboo
>>>>>>>>
>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <[email protected]
>>>>>>>> > wrote:
>>>>>>>>
>>>>>>>>> Hi there,
>>>>>>>>>
>>>>>>>>> We've been noticing some issues with the tests on both our CI and
>>>>>>>>> local Mac workstations.
>>>>>>>>>
>>>>>>>>>    1. When the following code blocks are invoked - we get plenty
>>>>>>>>>    of app.context() issues. It must not be valid when running
>>>>>>>>>    tests.
>>>>>>>>>
>>>>>>>>> ​
>>>>>>>>>
>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>
>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>
>>>>>>>>> 2. When we finally enable
>>>>>>>>>
>>>>>>>>> "default_binary_paths": {
>>>>>>>>>
>>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>>
>>>>>>>>> ======================================================================
>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>
>>>>>>>>> And
>>>>>>>>>
>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>     self.putenv(key, value)
>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>> FAIL
>>>>>>>>>
>>>>>>>>> ​
>>>>>>>>>
>>>>>>>>> Sincerely,
>>>>>>>>>
>>>>>>>>> Victoria && Anthony
>>>>>>>>>
>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Khushboo
>>>>>>>>>>
>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi
>>>>>>>>>>>>
>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>
>>>>>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>
>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>
>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the
>>>>>>>>>>>> JSON config file.
>>>>>>>>>>>>
>>>>>>>>>>>> Will do.
>>>>>>>>>>>
>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>
>>>>>>>>>>>> ============================================================
>>>>>>>>>>>> ==========
>>>>>>>>>>>>
>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>>
>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>
>>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>>> ----------
>>>>>>>>>>>>
>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>>>>> 56, in runTest
>>>>>>>>>>>>
>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py", line
>>>>>>>>>>>> 75, in _open_maintenance_dialogue
>>>>>>>>>>>>
>>>>>>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>> line 80, in click
>>>>>>>>>>>>
>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>> line 628, in _execute
>>>>>>>>>>>>
>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>>>>> line 312, in execute
>>>>>>>>>>>>
>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>>>>> line 242, in check_response
>>>>>>>>>>>>
>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>
>>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>
>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>
>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X
>>>>>>>>>>>> 10.12.6 x86_64)
>>>>>>>>>>>>
>>>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>>>
>>>>>>>>>>>> ============================================================
>>>>>>>>>>>> ==========
>>>>>>>>>>>>
>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>
>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>
>>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>>> ----------
>>>>>>>>>>>>
>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>
>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>>>
>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>> field_content)
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>>>
>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>>>> _wait_for
>>>>>>>>>>>>
>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>
>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>>>>> line 80, in until
>>>>>>>>>>>>
>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>
>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>
>>>>>>>>>>>> I have ran the feature tests with multiple servers many times
>>>>>>>>>>> but didn't get a single failure.
>>>>>>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>>>>>>> passing, but the linter fails:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the code
>>>>>>>>>>>>>> and we do not have coverage for it:
>>>>>>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy
>>>>>>>>>>>>>> path tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>>>> coverage.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us
>>>>>>>>>>>>>> think that this configuration should live near the server configuration,
>>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as well
>>>>>>>>>>>>>> in you patch.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Please find the attached patch which covers test cases for
>>>>>>>>>>>>>>> the backup module (RM #3206).
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Dave Page
>>>>>>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>>>>>>> Twitter: @pgsnake
>>>>>>>>>>>>
>>>>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Dave Page
>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>> Twitter: @pgsnake
>>>>>>>
>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>
>>>
>>> --
>>> Dave Page
>>> Blog: http://pgsnake.blogspot.com
>>> Twitter: @pgsnake
>>>
>>> EnterpriseDB UK: http://www.enterprisedb.com
>>> The Enterprise PostgreSQL Company
>>>
>>
>>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


Attachments:

  [application/octet-stream] RM_3206_ver4.patch (107.4K, 3-RM_3206_ver4.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..b4c1bb2
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..3c0c98c
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..d76a3c7
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,58 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_utils.run_backup_job(self.tester,
+                                    job_id,
+                                    self.expected_params,
+                                    self.assertIn,
+                                    self.assertNotIn
+                                    )
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..64d0d1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,199 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        print(batch_process_mock.call_args_list[0][1]['args'])
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..1a0c90b
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,194 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        backup_utils.run_backup_job(self.tester, job_id,
+                                    self.backup_options['expected_params'],
+                                    self.assertIn, self.assertNotIn)
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..26b25c7 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-05 23:43                               ` Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Victoria Henry @ 2018-06-05 23:43 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi Khushboo

The tests are still failing and seems flaky:
https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-tests/builds/113

Sincerely,

Victoria

On Tue, Jun 5, 2018 at 4:50 AM Khushboo Vashi <
[email protected]> wrote:

>
>
> On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:
>
>>
>>
>> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:
>>>
>>>> Hi
>>>>
>>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Khushboo,
>>>>>>
>>>>>> Some tests are failing in greenplum:
>>>>>>
>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-tests/builds/108
>>>>>> The piece of code responsible for the error is:
>>>>>>
>>>>>> if server['default_binary_paths'] is not None:
>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>
>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>         "gpdb": ""
>>>>>>     }
>>>>>>
>>>>>>
>>>>>> Can you send me the test_config.json file?  The above code sets the
>>>>> paths to the SQLite database and through the logs couldn't figure out the
>>>>> exact failure.
>>>>>
>>>>
>>>> It seems clear from the code shown that it's not setting the binary
>>>> paths for gpdb database servers. Shouldn't it be something like:
>>>>
>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>>     }
>>>>
>>>> Without this code, the test cases should work as I already set  paths
>>> through below code.
>>>
>>>     test_utils.set_preference(server['default_binary_paths'])
>>>
>>>
>> In that case, why is the code above required at all?
>>
>> My bad. Removed this code and also updated set_preference function for
> greenplum database.
> Please find the attached updated patch.
>
>>
>>
>>>
>>>>
>>>>> test_backup_utils.py file name is misleading, these are not tests,
>>>>>> are helpers.
>>>>>> ​
>>>>>>
>>>>>>
>>>>>> Thanks
>>>>>> Victoria & Joao
>>>>>>
>>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]> wrote:
>>>>>>>
>>>>>>>> Hi
>>>>>>>>
>>>>>>>> This looks good, except that it's leaving the test_restore_database
>>>>>>>> behind. Can we clean that up please?
>>>>>>>>
>>>>>>>> PFA updated patch.
>>>>>>>
>>>>>>>> Thanks.
>>>>>>>>
>>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Victoria,
>>>>>>>>>
>>>>>>>>> Thanks for reviewing the patch.
>>>>>>>>> The tests were failing due to the latest commit
>>>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>>
>>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Khushboo
>>>>>>>>>
>>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi there,
>>>>>>>>>>
>>>>>>>>>> We've been noticing some issues with the tests on both our CI and
>>>>>>>>>> local Mac workstations.
>>>>>>>>>>
>>>>>>>>>>    1. When the following code blocks are invoked - we get plenty
>>>>>>>>>>    of app.context() issues. It must not be valid when running
>>>>>>>>>>    tests.
>>>>>>>>>>
>>>>>>>>>> ​
>>>>>>>>>>
>>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>>
>>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>>
>>>>>>>>>> 2. When we finally enable
>>>>>>>>>>
>>>>>>>>>> "default_binary_paths": {
>>>>>>>>>>
>>>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>>>
>>>>>>>>>> ======================================================================
>>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>>
>>>>>>>>>> And
>>>>>>>>>>
>>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>>     self.putenv(key, value)
>>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>>> FAIL
>>>>>>>>>>
>>>>>>>>>> ​
>>>>>>>>>>
>>>>>>>>>> Sincerely,
>>>>>>>>>>
>>>>>>>>>> Victoria && Anthony
>>>>>>>>>>
>>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Khushboo
>>>>>>>>>>>
>>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>>>>>>> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>>
>>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the
>>>>>>>>>>>>> JSON config file.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Will do.
>>>>>>>>>>>>
>>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> ======================================================================
>>>>>>>>>>>>>
>>>>>>>>>>>>> ERROR: runTest
>>>>>>>>>>>>> (pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>>>
>>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>>>>
>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>> line 56, in runTest
>>>>>>>>>>>>>
>>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>>>>>>>
>>>>>>>>>>>>>     "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>>> line 80, in click
>>>>>>>>>>>>>
>>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>>> line 628, in _execute
>>>>>>>>>>>>>
>>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>>>>>> line 312, in execute
>>>>>>>>>>>>>
>>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>>>>>> line 242, in check_response
>>>>>>>>>>>>>
>>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>>
>>>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>>
>>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>>
>>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.12.6 x86_64)
>>>>>>>>>>>>>
>>>>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> ======================================================================
>>>>>>>>>>>>>
>>>>>>>>>>>>> ERROR: runTest
>>>>>>>>>>>>> (pgadmin.feature_tests.pg_utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>>
>>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>>>>
>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>>
>>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>>>>>>>> line 211, in fill_input_by_field_name
>>>>>>>>>>>>>
>>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>>> field_content)
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>>>>>>>> line 251, in wait_for_input_field_content
>>>>>>>>>>>>>
>>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>>>>>>>>> line 337, in _wait_for
>>>>>>>>>>>>>
>>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>>
>>>>>>>>>>>>>   File
>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>>>>>> line 80, in until
>>>>>>>>>>>>>
>>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>>
>>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I have ran the feature tests with multiple servers many times
>>>>>>>>>>>> but didn't get a single failure.
>>>>>>>>>>>> I have asked Akshay to run on his machine, let see what he gets.
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We passed the tests through our CI the feature tests are not
>>>>>>>>>>>>>>> passing, but the linter fails:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the code
>>>>>>>>>>>>>>> and we do not have coverage for it:
>>>>>>>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy
>>>>>>>>>>>>>>> path tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>>>>> coverage.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us think that this
>>>>>>>>>>>>>>> configuration should live near the server configuration, maybe? Also to
>>>>>>>>>>>>>>> maintain coherency on the naming maybe we should make it all lower case.
>>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as well
>>>>>>>>>>>>>>> in you patch.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Please find the attached patch which covers test cases for
>>>>>>>>>>>>>>>> the backup module (RM #3206).
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
@ 2018-06-06 04:07                                 ` Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-06 04:07 UTC (permalink / raw)
  To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi Victoria,

As per the logs, Restore job is failing only for GPDB. As I don't have
setup for the greenplum database, can you please check this functionality
works well in pgAdmin4 with GPDB?

Thanks,
Khushboo

On Wed, Jun 6, 2018 at 5:13 AM, Victoria Henry <[email protected]> wrote:

> Hi Khushboo
>
> The tests are still failing and seems flaky:
> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/
> pipelines/pgadmin-patch/jobs/run-tests/builds/113
>
> Sincerely,
>
> Victoria
>
> On Tue, Jun 5, 2018 at 4:50 AM Khushboo Vashi <
> [email protected]> wrote:
>
>>
>>
>> On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:
>>
>>>
>>>
>>> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Khushboo,
>>>>>>>
>>>>>>> Some tests are failing in greenplum:
>>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/
>>>>>>> pipelines/pgadmin-patch/jobs/run-tests/builds/108
>>>>>>> The piece of code responsible for the error is:
>>>>>>>
>>>>>>> if server['default_binary_paths'] is not None:
>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>
>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>         "gpdb": ""
>>>>>>>     }
>>>>>>>
>>>>>>>
>>>>>>> Can you send me the test_config.json file?  The above code sets the
>>>>>> paths to the SQLite database and through the logs couldn't figure out the
>>>>>> exact failure.
>>>>>>
>>>>>
>>>>> It seems clear from the code shown that it's not setting the binary
>>>>> paths for gpdb database servers. Shouldn't it be something like:
>>>>>
>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>>>     }
>>>>>
>>>>> Without this code, the test cases should work as I already set  paths
>>>> through below code.
>>>>
>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>
>>>>
>>> In that case, why is the code above required at all?
>>>
>>> My bad. Removed this code and also updated set_preference function for
>> greenplum database.
>> Please find the attached updated patch.
>>
>>>
>>>
>>>>
>>>>>
>>>>>> test_backup_utils.py file name is misleading, these are not tests,
>>>>>>> are helpers.
>>>>>>> ​
>>>>>>>
>>>>>>>
>>>>>>> Thanks
>>>>>>> Victoria & Joao
>>>>>>>
>>>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi
>>>>>>>>>
>>>>>>>>> This looks good, except that it's leaving the
>>>>>>>>> test_restore_database behind. Can we clean that up please?
>>>>>>>>>
>>>>>>>>> PFA updated patch.
>>>>>>>>
>>>>>>>>> Thanks.
>>>>>>>>>
>>>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Victoria,
>>>>>>>>>>
>>>>>>>>>> Thanks for reviewing the patch.
>>>>>>>>>> The tests were failing due to the latest commit #
>>>>>>>>>> 2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>>>
>>>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Khushboo
>>>>>>>>>>
>>>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi there,
>>>>>>>>>>>
>>>>>>>>>>> We've been noticing some issues with the tests on both our CI
>>>>>>>>>>> and local Mac workstations.
>>>>>>>>>>>
>>>>>>>>>>>    1. When the following code blocks are invoked - we get
>>>>>>>>>>>    plenty of app.context() issues. It must not be valid when
>>>>>>>>>>>    running tests.
>>>>>>>>>>>
>>>>>>>>>>> ​
>>>>>>>>>>>
>>>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>>>
>>>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>>>
>>>>>>>>>>> 2. When we finally enable
>>>>>>>>>>>
>>>>>>>>>>> "default_binary_paths": {
>>>>>>>>>>>
>>>>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>>>>
>>>>>>>>>>> ======================================================================
>>>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>>>
>>>>>>>>>>> And
>>>>>>>>>>>
>>>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>>>     self.putenv(key, value)
>>>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>>>> FAIL
>>>>>>>>>>>
>>>>>>>>>>> ​
>>>>>>>>>>>
>>>>>>>>>>> Sincerely,
>>>>>>>>>>>
>>>>>>>>>>> Victoria && Anthony
>>>>>>>>>>>
>>>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi,
>>>>>>>>>>>>
>>>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> please find the attached updated patch for the test cases of
>>>>>>>>>>>>>>> Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in the
>>>>>>>>>>>>>> JSON config file.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Will do.
>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ============================================================
>>>>>>>>>>>>>> ==========
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_
>>>>>>>>>>>>>> utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>>>>> ----------
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/
>>>>>>>>>>>>>> web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>> line 56, in runTest
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/
>>>>>>>>>>>>>> web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     "*[.='" + self.table_name +
>>>>>>>>>>>>>> "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/
>>>>>>>>>>>>>> pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>>>> line 80, in click
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/
>>>>>>>>>>>>>> pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>>>> line 628, in _execute
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/
>>>>>>>>>>>>>> pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>>>>>>> line 312, in execute
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/
>>>>>>>>>>>>>> pgadmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>>>>>>> line 242, in check_response
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518 (
>>>>>>>>>>>>>> 183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X
>>>>>>>>>>>>>> 10.12.6 x86_64)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ============================================================
>>>>>>>>>>>>>> ==========
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_
>>>>>>>>>>>>>> utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>>>>> ----------
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/
>>>>>>>>>>>>>> web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/
>>>>>>>>>>>>>> web/regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>>>> field_content)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/
>>>>>>>>>>>>>> web/regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/
>>>>>>>>>>>>>> web/regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>>>>>> _wait_for
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/
>>>>>>>>>>>>>> pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>>>>>>> line 80, in until
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I have ran the feature tests with multiple servers many times
>>>>>>>>>>>>> but didn't get a single failure.
>>>>>>>>>>>>> I have asked Akshay to run on his machine, let see what he
>>>>>>>>>>>>> gets.
>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We passed the tests through our CI the feature tests are
>>>>>>>>>>>>>>>> not passing, but the linter fails:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the code
>>>>>>>>>>>>>>>> and we do not have coverage for it: https://redmine.
>>>>>>>>>>>>>>>> postgresql.org/issues/3232
>>>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy
>>>>>>>>>>>>>>>> path tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>>>>>> coverage.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The configuration change, maybe need to be updated. When we
>>>>>>>>>>>>>>>> install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us
>>>>>>>>>>>>>>>> think that this configuration should live near the server configuration,
>>>>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as
>>>>>>>>>>>>>>>> well in you patch.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Please find the attached patch which covers test cases for
>>>>>>>>>>>>>>>>> the backup module (RM #3206).
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-06 05:12                                   ` Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-06 05:12 UTC (permalink / raw)
  To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi Dave,

As per our discussion I have added the code to clean up the generated files.
Please find the attached updated patch.

Thanks,
Khushboo

On Wed, Jun 6, 2018 at 9:37 AM, Khushboo Vashi <
[email protected]> wrote:

> Hi Victoria,
>
> As per the logs, Restore job is failing only for GPDB. As I don't have
> setup for the greenplum database, can you please check this functionality
> works well in pgAdmin4 with GPDB?
>
> Thanks,
> Khushboo
>
> On Wed, Jun 6, 2018 at 5:13 AM, Victoria Henry <[email protected]> wrote:
>
>> Hi Khushboo
>>
>> The tests are still failing and seems flaky:
>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>> /pgadmin-patch/jobs/run-tests/builds/113
>>
>> Sincerely,
>>
>> Victoria
>>
>> On Tue, Jun 5, 2018 at 4:50 AM Khushboo Vashi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Khushboo,
>>>>>>>>
>>>>>>>> Some tests are failing in greenplum:
>>>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>>>>> /pgadmin-patch/jobs/run-tests/builds/108
>>>>>>>> The piece of code responsible for the error is:
>>>>>>>>
>>>>>>>> if server['default_binary_paths'] is not None:
>>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>>
>>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>>         "gpdb": ""
>>>>>>>>     }
>>>>>>>>
>>>>>>>>
>>>>>>>> Can you send me the test_config.json file?  The above code sets the
>>>>>>> paths to the SQLite database and through the logs couldn't figure out the
>>>>>>> exact failure.
>>>>>>>
>>>>>>
>>>>>> It seems clear from the code shown that it's not setting the binary
>>>>>> paths for gpdb database servers. Shouldn't it be something like:
>>>>>>
>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>>>>     }
>>>>>>
>>>>>> Without this code, the test cases should work as I already set  paths
>>>>> through below code.
>>>>>
>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>
>>>>>
>>>> In that case, why is the code above required at all?
>>>>
>>>> My bad. Removed this code and also updated set_preference function for
>>> greenplum database.
>>> Please find the attached updated patch.
>>>
>>>>
>>>>
>>>>>
>>>>>>
>>>>>>> test_backup_utils.py file name is misleading, these are not tests,
>>>>>>>> are helpers.
>>>>>>>> ​
>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Victoria & Joao
>>>>>>>>
>>>>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Hi
>>>>>>>>>>
>>>>>>>>>> This looks good, except that it's leaving the
>>>>>>>>>> test_restore_database behind. Can we clean that up please?
>>>>>>>>>>
>>>>>>>>>> PFA updated patch.
>>>>>>>>>
>>>>>>>>>> Thanks.
>>>>>>>>>>
>>>>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Victoria,
>>>>>>>>>>>
>>>>>>>>>>> Thanks for reviewing the patch.
>>>>>>>>>>> The tests were failing due to the latest commit
>>>>>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>>>>
>>>>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Khushboo
>>>>>>>>>>>
>>>>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi there,
>>>>>>>>>>>>
>>>>>>>>>>>> We've been noticing some issues with the tests on both our CI
>>>>>>>>>>>> and local Mac workstations.
>>>>>>>>>>>>
>>>>>>>>>>>>    1. When the following code blocks are invoked - we get
>>>>>>>>>>>>    plenty of app.context() issues. It must not be valid when
>>>>>>>>>>>>    running tests.
>>>>>>>>>>>>
>>>>>>>>>>>> ​
>>>>>>>>>>>>
>>>>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>>>>
>>>>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>>>>
>>>>>>>>>>>> 2. When we finally enable
>>>>>>>>>>>>
>>>>>>>>>>>> "default_binary_paths": {
>>>>>>>>>>>>
>>>>>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>>>>>
>>>>>>>>>>>> ======================================================================
>>>>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>>>>
>>>>>>>>>>>> And
>>>>>>>>>>>>
>>>>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>>>>     self.putenv(key, value)
>>>>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>>>>> FAIL
>>>>>>>>>>>>
>>>>>>>>>>>> ​
>>>>>>>>>>>>
>>>>>>>>>>>> Sincerely,
>>>>>>>>>>>>
>>>>>>>>>>>> Victoria && Anthony
>>>>>>>>>>>>
>>>>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>
>>>>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <[email protected]
>>>>>>>>>>>>>> > wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> please find the attached updated patch for the test cases
>>>>>>>>>>>>>>>> of Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in
>>>>>>>>>>>>>>> the JSON config file.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Will do.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ============================================================
>>>>>>>>>>>>>>> ==========
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>>>>>> ----------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>> line 56, in runTest
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     "*[.='" + self.table_name +
>>>>>>>>>>>>>>> "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>>>>> line 80, in click
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",
>>>>>>>>>>>>>>> line 628, in _execute
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",
>>>>>>>>>>>>>>> line 312, in execute
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py",
>>>>>>>>>>>>>>> line 242, in check_response
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS
>>>>>>>>>>>>>>> X 10.12.6 x86_64)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ============================================================
>>>>>>>>>>>>>>> ==========
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ------------------------------------------------------------
>>>>>>>>>>>>>>> ----------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>>>>> field_content)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>>>>>>> _wait_for
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
>>>>>>>>>>>>>>> line 80, in until
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I have ran the feature tests with multiple servers many
>>>>>>>>>>>>>> times but didn't get a single failure.
>>>>>>>>>>>>>> I have asked Akshay to run on his machine, let see what he
>>>>>>>>>>>>>> gets.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some more
>>>>>>>>>>>>>>>>> coverage in this area. Good job :D
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We passed the tests through our CI the feature tests are
>>>>>>>>>>>>>>>>> not passing, but the linter fails:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the
>>>>>>>>>>>>>>>>> code and we do not have coverage for it:
>>>>>>>>>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy
>>>>>>>>>>>>>>>>> path tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>>>>>>> coverage.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> The configuration change, maybe need to be updated. When
>>>>>>>>>>>>>>>>> we install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us
>>>>>>>>>>>>>>>>> think that this configuration should live near the server configuration,
>>>>>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as
>>>>>>>>>>>>>>>>> well in you patch.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Please find the attached patch which covers test cases
>>>>>>>>>>>>>>>>>> for the backup module (RM #3206).
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>


Attachments:

  [application/octet-stream] RM_3206_ver5.patch (108.2K, 3-RM_3206_ver5.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..65b5708
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,151 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import os
+
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        backup_file = None
+        if command:
+            backup_file = command[int(command.find('--file')) + 8:
+            int(command.find('--host')) - 2]
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..c4432b6
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    backup_file = None
+    if 'details' in process_list[0]:
+        backup_det = process_list[0]['details']
+        backup_file = backup_det[int(backup_det.find('--file')) + 8:
+        int(backup_det.find('--host')) - 2]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+    return backup_file
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..ed48c58
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,62 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_file = backup_utils.run_backup_job(self.tester,
+                                    job_id,
+                                    self.expected_params,
+                                    self.assertIn,
+                                    self.assertNotIn
+                                    )
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..58aef5c
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,198 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..ff81bf6
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,199 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import os
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        self.backup_file = backup_utils.run_backup_job(self.tester, job_id,
+                                    self.backup_options['expected_params'],
+                                    self.assertIn, self.assertNotIn)
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+        if self.backup_file is not None:
+            if os.path.isfile(self.backup_file):
+                os.remove(self.backup_file)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..26b25c7 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-06 06:57                                     ` Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-06 06:57 UTC (permalink / raw)
  To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Please find the atatched patch with the PEP8 fixes.

On Wed, Jun 6, 2018 at 10:42 AM, Khushboo Vashi <
[email protected]> wrote:

> Hi Dave,
>
> As per our discussion I have added the code to clean up the generated
> files.
> Please find the attached updated patch.
>
> Thanks,
> Khushboo
>
> On Wed, Jun 6, 2018 at 9:37 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi Victoria,
>>
>> As per the logs, Restore job is failing only for GPDB. As I don't have
>> setup for the greenplum database, can you please check this functionality
>> works well in pgAdmin4 with GPDB?
>>
>> Thanks,
>> Khushboo
>>
>> On Wed, Jun 6, 2018 at 5:13 AM, Victoria Henry <[email protected]> wrote:
>>
>>> Hi Khushboo
>>>
>>> The tests are still failing and seems flaky:
>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>> /pgadmin-patch/jobs/run-tests/builds/113
>>>
>>> Sincerely,
>>>
>>> Victoria
>>>
>>> On Tue, Jun 5, 2018 at 4:50 AM Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]> wrote:
>>>>>>
>>>>>>> Hi
>>>>>>>
>>>>>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Khushboo,
>>>>>>>>>
>>>>>>>>> Some tests are failing in greenplum:
>>>>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>>>>>> /pgadmin-patch/jobs/run-tests/builds/108
>>>>>>>>> The piece of code responsible for the error is:
>>>>>>>>>
>>>>>>>>> if server['default_binary_paths'] is not None:
>>>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>>>
>>>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>>>         "gpdb": ""
>>>>>>>>>     }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Can you send me the test_config.json file?  The above code sets
>>>>>>>> the paths to the SQLite database and through the logs couldn't figure out
>>>>>>>> the exact failure.
>>>>>>>>
>>>>>>>
>>>>>>> It seems clear from the code shown that it's not setting the binary
>>>>>>> paths for gpdb database servers. Shouldn't it be something like:
>>>>>>>
>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>>>>>     }
>>>>>>>
>>>>>>> Without this code, the test cases should work as I already set
>>>>>> paths through below code.
>>>>>>
>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>
>>>>>>
>>>>> In that case, why is the code above required at all?
>>>>>
>>>>> My bad. Removed this code and also updated set_preference function for
>>>> greenplum database.
>>>> Please find the attached updated patch.
>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>>> test_backup_utils.py file name is misleading, these are not tests,
>>>>>>>>> are helpers.
>>>>>>>>> ​
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks
>>>>>>>>> Victoria & Joao
>>>>>>>>>
>>>>>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]>
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi
>>>>>>>>>>>
>>>>>>>>>>> This looks good, except that it's leaving the
>>>>>>>>>>> test_restore_database behind. Can we clean that up please?
>>>>>>>>>>>
>>>>>>>>>>> PFA updated patch.
>>>>>>>>>>
>>>>>>>>>>> Thanks.
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi Victoria,
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks for reviewing the patch.
>>>>>>>>>>>> The tests were failing due to the latest commit
>>>>>>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>>>>>
>>>>>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>
>>>>>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi there,
>>>>>>>>>>>>>
>>>>>>>>>>>>> We've been noticing some issues with the tests on both our CI
>>>>>>>>>>>>> and local Mac workstations.
>>>>>>>>>>>>>
>>>>>>>>>>>>>    1. When the following code blocks are invoked - we get
>>>>>>>>>>>>>    plenty of app.context() issues. It must not be valid when
>>>>>>>>>>>>>    running tests.
>>>>>>>>>>>>>
>>>>>>>>>>>>> ​
>>>>>>>>>>>>>
>>>>>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>>>>>
>>>>>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2. When we finally enable
>>>>>>>>>>>>>
>>>>>>>>>>>>> "default_binary_paths": {
>>>>>>>>>>>>>
>>>>>>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>>>>>>
>>>>>>>>>>>>> ======================================================================
>>>>>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>>>>>
>>>>>>>>>>>>> And
>>>>>>>>>>>>>
>>>>>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>>>>>     self.putenv(key, value)
>>>>>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>>>>>> FAIL
>>>>>>>>>>>>>
>>>>>>>>>>>>> ​
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sincerely,
>>>>>>>>>>>>>
>>>>>>>>>>>>> Victoria && Anthony
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> please find the attached updated patch for the test cases
>>>>>>>>>>>>>>>>> of Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in
>>>>>>>>>>>>>>>> the JSON config file.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Will do.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================
>>>>>>>>>>>>>>>> ========================================
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>>>> ----------------------------------------
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>>> line 56, in runTest
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     "*[.='" + self.table_name +
>>>>>>>>>>>>>>>> "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webelement.py", line 80, in
>>>>>>>>>>>>>>>> click
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webelement.py", line 628, in
>>>>>>>>>>>>>>>> _execute
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webdriver.py", line 312, in
>>>>>>>>>>>>>>>> execute
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/errorhandler.py", line 242,
>>>>>>>>>>>>>>>> in check_response
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS
>>>>>>>>>>>>>>>> X 10.12.6 x86_64)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 3) One time the test did start, but then I saw this failure:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ==============================
>>>>>>>>>>>>>>>> ========================================
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>>>> ----------------------------------------
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>>>>>> field_content)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>>>>>>>> _wait_for
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I have ran the feature tests with multiple servers many
>>>>>>>>>>>>>>> times but didn't get a single failure.
>>>>>>>>>>>>>>> I have asked Akshay to run on his machine, let see what he
>>>>>>>>>>>>>>> gets.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira <
>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some
>>>>>>>>>>>>>>>>>> more coverage in this area. Good job :D
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> We passed the tests through our CI the feature tests are
>>>>>>>>>>>>>>>>>> not passing, but the linter fails:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the
>>>>>>>>>>>>>>>>>> code and we do not have coverage for it:
>>>>>>>>>>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have happy
>>>>>>>>>>>>>>>>>> path tests, maybe we should see if there are any sad paths that also need
>>>>>>>>>>>>>>>>>> coverage.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> The configuration change, maybe need to be updated. When
>>>>>>>>>>>>>>>>>> we install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes us
>>>>>>>>>>>>>>>>>> think that this configuration should live near the server configuration,
>>>>>>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as
>>>>>>>>>>>>>>>>>> well in you patch.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Please find the attached patch which covers test cases
>>>>>>>>>>>>>>>>>>> for the backup module (RM #3206).
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>
>


Attachments:

  [application/octet-stream] RM_3206_ver6.patch (108.3K, 3-RM_3206_ver6.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..6bc60a6
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,151 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import os
+
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        backup_file = None
+        if command:
+            backup_file = command[int(command.find('--file')) +
+                                  8:int(command.find('--host')) - 2]
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..9313ee9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    backup_file = None
+    if 'details' in process_list[0]:
+        backup_det = process_list[0]['details']
+        backup_file = backup_det[int(backup_det.find('--file')) +
+                                 8:int(backup_det.find('--host')) - 2]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+    return backup_file
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..3e3fe92
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,63 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_file = backup_utils.run_backup_job(self.tester,
+                                                  job_id,
+                                                  self.expected_params,
+                                                  self.assertIn,
+                                                  self.assertNotIn
+                                                  )
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..58aef5c
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,198 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..ca1ab2c
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,203 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import os
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        self.backup_file = backup_utils.run_backup_job(
+            self.tester,
+            job_id,
+            self.backup_options['expected_params'],
+            self.assertIn,
+            self.assertNotIn
+        )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+        if self.backup_file is not None:
+            if os.path.isfile(self.backup_file):
+                os.remove(self.backup_file)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..26b25c7 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-06 10:24                                       ` Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-06 10:24 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

On Wed, Jun 6, 2018 at 2:30 PM, Dave Page <[email protected]> wrote:

> Hi
>
> I'm seeing various failures with this patch. Many of them appear to be
> being caused by the notification popups obscuring elements. Perhaps they
> need to be explicitly closed? Errors below, screenshots attached.
>
Notifications should be taken care by test cases. On my MAC and Linux these
are working fine.
I will check with someone else's machine.

> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.pg_utilities_backup_restore_test.
> PGUtilitiesBackupFeatureTest)
> Test for PG utilities - Backup and Restore
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_backup_restore_test.py", line 97, in runTest
>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>     lambda driver: driver.find_element_by_xpath(xpath)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>     return self._wait_for("element to exist", element_if_it_exists)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>     "Timed out waiting for " + waiting_for_message
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/support/wait.py", line 80, in until
>     raise TimeoutException(message, screen, stacktrace)
> TimeoutException: Message: Timed out waiting for element to exist
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_file_manager_test.
> CheckFileManagerFeatureTest)
> Tests to check if File manager is vulnerable to XSS
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
> line 66, in tearDown
>     self.after()
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_file_manager_test.py",
> line 46, in after
>     self.page.close_query_tool('sql', False)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 104, in close_query_tool
>     "//li[contains(@class, 'context-menu-item')]/span[contains(text(),"
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>     lambda driver: driver.find_element_by_xpath(xpath)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>     return self._wait_for("element to exist", element_if_it_exists)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>     "Timed out waiting for " + waiting_for_message
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/support/wait.py", line 80, in until
>     raise TimeoutException(message, screen, stacktrace)
> TimeoutException: Message: Timed out waiting for element to exist
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_panels_and_query_tool_
> test.CheckForXssFeatureTest)
> Test XSS check for panels and query tool
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_
> checks_panels_and_query_tool_test.py", line 57, in runTest
>     self.page.add_server(self.server)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 65, in add_server
>     self.find_by_xpath("//button[contains(.,'Save')]").click()
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 80, in click
>     self._execute(Command.CLICK_ELEMENT)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
>     return self._parent.execute(command, params)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
>     self.error_handler.check_response(response)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/errorhandler.py", line 242, in
> check_response
>     raise exception_class(message, screen, stacktrace)
> WebDriverException: Message: unknown error: Element <button type="save"
> class="btn btn-primary" title="Save this object.">...</button> is not
> clickable at point (661, 761). Other element would receive the click: <div
> class="pg-bg-etime">...</div>
>   (Session info: chrome=66.0.3359.181)
>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
> OS X 10.12.6 x86_64)
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_panels_and_query_tool_
> test.CheckForXssFeatureTest)
> Test XSS check for panels and query tool
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
> line 66, in tearDown
>     self.after()
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_
> checks_panels_and_query_tool_test.py", line 69, in after
>     self.page.remove_server(self.server)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 124, in remove_server
>     "' and @class='aciTreeItem']")
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>     lambda driver: driver.find_element_by_xpath(xpath)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>     return self._wait_for("element to exist", element_if_it_exists)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>     "Timed out waiting for " + waiting_for_message
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/support/wait.py", line 80, in until
>     raise TimeoutException(message, screen, stacktrace)
> TimeoutException: Message: Timed out waiting for element to exist
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_pgadmin_debugger_test.
> CheckDebuggerForXssFeatureTest)
> Tests to check if Debugger is vulnerable to XSS
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_
> checks_pgadmin_debugger_test.py", line 41, in runTest
>     self.page.add_server(self.server)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 65, in add_server
>     self.find_by_xpath("//button[contains(.,'Save')]").click()
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 80, in click
>     self._execute(Command.CLICK_ELEMENT)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
>     return self._parent.execute(command, params)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
>     self.error_handler.check_response(response)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/errorhandler.py", line 242, in
> check_response
>     raise exception_class(message, screen, stacktrace)
> WebDriverException: Message: unknown error: Element <button type="save"
> class="btn btn-primary" title="Save this object.">...</button> is not
> clickable at point (661, 761). Other element would receive the click: <div
> class="pg-bg-etime">...</div>
>   (Session info: chrome=66.0.3359.181)
>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
> OS X 10.12.6 x86_64)
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_pgadmin_debugger_test.
> CheckDebuggerForXssFeatureTest)
> Tests to check if Debugger is vulnerable to XSS
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
> line 66, in tearDown
>     self.after()
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_
> checks_pgadmin_debugger_test.py", line 46, in after
>     self.page.remove_server(self.server)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 124, in remove_server
>     "' and @class='aciTreeItem']")
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>     lambda driver: driver.find_element_by_xpath(xpath)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>     return self._wait_for("element to exist", element_if_it_exists)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>     "Timed out waiting for " + waiting_for_message
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/support/wait.py", line 80, in until
>     raise TimeoutException(message, screen, stacktrace)
> TimeoutException: Message: Timed out waiting for element to exist
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_roles_control_test.
> CheckRoleMembershipControlFeatureTest)
> Tests to check if Role membership control is vulnerable to XSS
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_roles_control_test.py",
> line 37, in runTest
>     self.page.add_server(self.server)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 65, in add_server
>     self.find_by_xpath("//button[contains(.,'Save')]").click()
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 80, in click
>     self._execute(Command.CLICK_ELEMENT)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
>     return self._parent.execute(command, params)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
>     self.error_handler.check_response(response)
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/remote/errorhandler.py", line 242, in
> check_response
>     raise exception_class(message, screen, stacktrace)
> WebDriverException: Message: unknown error: Element <button type="save"
> class="btn btn-primary" title="Save this object.">...</button> is not
> clickable at point (661, 761). Other element would receive the click: <div
> class="pg-bg-etime">...</div>
>   (Session info: chrome=66.0.3359.181)
>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
> OS X 10.12.6 x86_64)
>
>
> ======================================================================
> ERROR: runTest (pgadmin.feature_tests.xss_checks_roles_control_test.
> CheckRoleMembershipControlFeatureTest)
> Tests to check if Role membership control is vulnerable to XSS
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
> line 66, in tearDown
>     self.after()
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_roles_control_test.py",
> line 42, in after
>     self.page.remove_server(self.server)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 124, in remove_server
>     "' and @class='aciTreeItem']")
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>     lambda driver: driver.find_element_by_xpath(xpath)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>     return self._wait_for("element to exist", element_if_it_exists)
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>     "Timed out waiting for " + waiting_for_message
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
> packages/selenium/webdriver/support/wait.py", line 80, in until
>     raise TimeoutException(message, screen, stacktrace)
> TimeoutException: Message: Timed out waiting for element to exist
>
>
> ======================================================================
> FAIL: runTest (pgadmin.feature_tests.pg_utilities_maintenance_test.
> PGUtilitiesMaintenanceFeatureTest)
> Test for PG maintenance: database pg_maintenance
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_maintenance_test.py", line 63, in runTest
>     self._verify_command()
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_maintenance_test.py", line 90, in _verify_command
>     self.assertEquals(command, "VACUUM "
> AssertionError: u'Backing up an object on the server \'Regression - PG 9.4
> Feature Tests (localhost:5432)\' from database \'pg_utility_test_db\'...\nRunning
> command:\n/Library/PostgreSQL/9.4/bin/pg_dump --file
> "/Users/dpage/test_backup" --host "localhost" --port "5432" --username
> "postgres" --no-password --verbose --format=c --blobs "pg_utility_test_db"'
> != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE;'
>
> ======================================================================
> FAIL: runTest (pgadmin.feature_tests.pg_utilities_maintenance_test.
> PGUtilitiesMaintenanceFeatureTest)
> Test for PG maintenance: database
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_maintenance_test.py", line 63, in runTest
>     self._verify_command()
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
> utilities_maintenance_test.py", line 97, in _verify_command
>     " public." + self.table_name + ";")
> AssertionError: u'Backing up an object on the server \'Regression - PG 9.4
> Feature Tests (localhost:5432)\' from database \'pg_utility_test_db\'...\nRunning
> command:\n/Library/PostgreSQL/9.4/bin/pg_dump --file
> "/Users/dpage/test_backup" --host "localhost" --port "5432" --username
> "postgres" --no-password --verbose --format=c --blobs "pg_utility_test_db"'
> != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE
> public.pg_maintenance_table;'
>
> ======================================================================
> FAIL: runTest (pgadmin.tools.maintenance.tests.test_create_maintenance_
> job.MaintenanceJobTest)
> When maintenance the object with the default options
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/
> tests/test_create_maintenance_job.py", line 85, in runTest
>     self.assertIn(self.expected_cmd, process_list[0]['details'])
> AssertionError: 'VACUUM VERBOSE' not found in u'<div class="h5">Backing up
> an object on the server \'Regression - PG 9.4 Feature Tests
> (localhost:5432)\' from database \'pg_utility_test_db\'...</div><div
> class="h5">Running command:</b><br><span class="pg-bg-cmd
> enable-selection">/Library/PostgreSQL/9.4/bin/pg_dump --file
> "/Users/dpage/test_backup" --host "localhost" --port "5432" --username
> "postgres" --no-password --verbose --format=c --blobs
> "pg_utility_test_db"</span></div>'
>
> ----------------------------------------------------------------------
> Ran 369 tests in 493.707s
>
> FAILED (failures=3, errors=8, skipped=21)
>
>
>
> On Wed, Jun 6, 2018 at 7:57 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>> Please find the atatched patch with the PEP8 fixes.
>>
>> On Wed, Jun 6, 2018 at 10:42 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi Dave,
>>>
>>> As per our discussion I have added the code to clean up the generated
>>> files.
>>> Please find the attached updated patch.
>>>
>>> Thanks,
>>> Khushboo
>>>
>>> On Wed, Jun 6, 2018 at 9:37 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi Victoria,
>>>>
>>>> As per the logs, Restore job is failing only for GPDB. As I don't have
>>>> setup for the greenplum database, can you please check this functionality
>>>> works well in pgAdmin4 with GPDB?
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>> On Wed, Jun 6, 2018 at 5:13 AM, Victoria Henry <[email protected]>
>>>> wrote:
>>>>
>>>>> Hi Khushboo
>>>>>
>>>>> The tests are still failing and seems flaky:
>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>> /pgadmin-patch/jobs/run-tests/builds/113
>>>>>
>>>>> Sincerely,
>>>>>
>>>>> Victoria
>>>>>
>>>>> On Tue, Jun 5, 2018 at 4:50 AM Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi
>>>>>>>>>
>>>>>>>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>
>>>>>>>>>>> Some tests are failing in greenplum:
>>>>>>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>>>>>>>> /pgadmin-patch/jobs/run-tests/builds/108
>>>>>>>>>>> The piece of code responsible for the error is:
>>>>>>>>>>>
>>>>>>>>>>> if server['default_binary_paths'] is not None:
>>>>>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>>>>>
>>>>>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>>>>>         "gpdb": ""
>>>>>>>>>>>     }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Can you send me the test_config.json file?  The above code sets
>>>>>>>>>> the paths to the SQLite database and through the logs couldn't figure out
>>>>>>>>>> the exact failure.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> It seems clear from the code shown that it's not setting the
>>>>>>>>> binary paths for gpdb database servers. Shouldn't it be something like:
>>>>>>>>>
>>>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>>>>>>>     }
>>>>>>>>>
>>>>>>>>> Without this code, the test cases should work as I already set
>>>>>>>> paths through below code.
>>>>>>>>
>>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>>
>>>>>>>>
>>>>>>> In that case, why is the code above required at all?
>>>>>>>
>>>>>>> My bad. Removed this code and also updated set_preference function
>>>>>> for greenplum database.
>>>>>> Please find the attached updated patch.
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>>> test_backup_utils.py file name is misleading, these are not
>>>>>>>>>>> tests, are helpers.
>>>>>>>>>>> ​
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thanks
>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]>
>>>>>>>>>>>> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>
>>>>>>>>>>>>> This looks good, except that it's leaving the
>>>>>>>>>>>>> test_restore_database behind. Can we clean that up please?
>>>>>>>>>>>>>
>>>>>>>>>>>>> PFA updated patch.
>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi Victoria,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks for reviewing the patch.
>>>>>>>>>>>>>> The tests were failing due to the latest commit
>>>>>>>>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi there,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We've been noticing some issues with the tests on both our
>>>>>>>>>>>>>>> CI and local Mac workstations.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>    1. When the following code blocks are invoked - we get
>>>>>>>>>>>>>>>    plenty of app.context() issues. It must not be valid
>>>>>>>>>>>>>>>    when running tests.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ​
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2. When we finally enable
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> "default_binary_paths": {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> in our test_config, we get more failing tests that look like:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ======================================================================
>>>>>>>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>>>>>>>     self.putenv(key, value)
>>>>>>>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>>>>>>>> FAIL
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ​
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sincerely,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Victoria && Anthony
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <
>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> please find the attached updated patch for the test
>>>>>>>>>>>>>>>>>>> cases of Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths in
>>>>>>>>>>>>>>>>>> the JSON config file.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Will do.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================
>>>>>>>>>>>>>>>>>> ========================================
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>>>>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>>>>>> ----------------------------------------
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>>>>> line 56, in runTest
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     "*[.='" + self.table_name +
>>>>>>>>>>>>>>>>>> "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webelement.py", line 80,
>>>>>>>>>>>>>>>>>> in click
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webelement.py", line 628,
>>>>>>>>>>>>>>>>>> in _execute
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webdriver.py", line 312,
>>>>>>>>>>>>>>>>>> in execute
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/errorhandler.py", line
>>>>>>>>>>>>>>>>>> 242, in check_response
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> WebDriverException: Message: unknown error: Element <span
>>>>>>>>>>>>>>>>>> class="aciTreeItem">...</span> is not clickable at point (223, 604). Other
>>>>>>>>>>>>>>>>>> element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
>>>>>>>>>>>>>>>>>> OS X 10.12.6 x86_64)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 3) One time the test did start, but then I saw this
>>>>>>>>>>>>>>>>>> failure:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ==============================
>>>>>>>>>>>>>>>>>> ========================================
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>>>>>> ----------------------------------------
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211, in
>>>>>>>>>>>>>>>>>> fill_input_by_field_name
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>>>>>>>> field_content)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251, in
>>>>>>>>>>>>>>>>>> wait_for_input_field_content
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337, in
>>>>>>>>>>>>>>>>>> _wait_for
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/support/wait.py", line 80, in
>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field to
>>>>>>>>>>>>>>>>>> contain 'test_backup_file'
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I have ran the feature tests with multiple servers many
>>>>>>>>>>>>>>>>> times but didn't get a single failure.
>>>>>>>>>>>>>>>>> I have asked Akshay to run on his machine, let see what he
>>>>>>>>>>>>>>>>> gets.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida Pereira
>>>>>>>>>>>>>>>>>>> <[email protected]> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some
>>>>>>>>>>>>>>>>>>>> more coverage in this area. Good job :D
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> We passed the tests through our CI the feature tests
>>>>>>>>>>>>>>>>>>>> are not passing, but the linter fails:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> For the feature tests, we realized we had to update the
>>>>>>>>>>>>>>>>>>>> configuration, and we did that, but we get the following error attached. We
>>>>>>>>>>>>>>>>>>>> spent some time trying to understand the problem but we were not successful.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>>>>>>>> - We just found some One Letter Variables in the code...
>>>>>>>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the
>>>>>>>>>>>>>>>>>>>> code and we do not have coverage for it:
>>>>>>>>>>>>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have
>>>>>>>>>>>>>>>>>>>> happy path tests, maybe we should see if there are any sad paths that also
>>>>>>>>>>>>>>>>>>>> need coverage.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> The configuration change, maybe need to be updated.
>>>>>>>>>>>>>>>>>>>> When we install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes
>>>>>>>>>>>>>>>>>>>> us think that this configuration should live near the server configuration,
>>>>>>>>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration as
>>>>>>>>>>>>>>>>>>>> well in you patch.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Please find the attached patch which covers test cases
>>>>>>>>>>>>>>>>>>>>> for the backup module (RM #3206).
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>
>>>
>>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-08 05:33                                         ` Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-08 05:33 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi Dave,

As per our discussion I have changed the window size to 1280X800, before it
was 1280X900.
Please find the attached updated patch.


Thanks,
Khushboo

On Wed, Jun 6, 2018 at 3:54 PM, Khushboo Vashi <
[email protected]> wrote:

>
>
> On Wed, Jun 6, 2018 at 2:30 PM, Dave Page <[email protected]> wrote:
>
>> Hi
>>
>> I'm seeing various failures with this patch. Many of them appear to be
>> being caused by the notification popups obscuring elements. Perhaps they
>> need to be explicitly closed? Errors below, screenshots attached.
>>
> Notifications should be taken care by test cases. On my MAC and Linux
> these are working fine.
> I will check with someone else's machine.
>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.pg_util
>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>> Test for PG utilities - Backup and Restore
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>> line 97, in runTest
>>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>     return self._wait_for("element to exist", element_if_it_exists)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>     "Timed out waiting for " + waiting_for_message
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>     raise TimeoutException(message, screen, stacktrace)
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_file_manager_test.CheckFileManagerFeatureTest)
>> Tests to check if File manager is vulnerable to XSS
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
>> line 66, in tearDown
>>     self.after()
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_file_manager_test.py",
>> line 46, in after
>>     self.page.close_query_tool('sql', False)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 104, in close_query_tool
>>     "//li[contains(@class, 'context-menu-item')]/span[contains(text(),"
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>     return self._wait_for("element to exist", element_if_it_exists)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>     "Timed out waiting for " + waiting_for_message
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>     raise TimeoutException(message, screen, stacktrace)
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_panels_and_query_tool_test.CheckForXssFeatureTest)
>> Test XSS check for panels and query tool
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_che
>> cks_panels_and_query_tool_test.py", line 57, in runTest
>>     self.page.add_server(self.server)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 65, in add_server
>>     self.find_by_xpath("//button[contains(.,'Save')]").click()
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 80, in click
>>     self._execute(Command.CLICK_ELEMENT)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 628, in _execute
>>     return self._parent.execute(command, params)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>     self.error_handler.check_response(response)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/errorhandler.py", line 242, in
>> check_response
>>     raise exception_class(message, screen, stacktrace)
>> WebDriverException: Message: unknown error: Element <button type="save"
>> class="btn btn-primary" title="Save this object.">...</button> is not
>> clickable at point (661, 761). Other element would receive the click: <div
>> class="pg-bg-etime">...</div>
>>   (Session info: chrome=66.0.3359.181)
>>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
>> OS X 10.12.6 x86_64)
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_panels_and_query_tool_test.CheckForXssFeatureTest)
>> Test XSS check for panels and query tool
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
>> line 66, in tearDown
>>     self.after()
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_che
>> cks_panels_and_query_tool_test.py", line 69, in after
>>     self.page.remove_server(self.server)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 124, in remove_server
>>     "' and @class='aciTreeItem']")
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>     return self._wait_for("element to exist", element_if_it_exists)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>     "Timed out waiting for " + waiting_for_message
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>     raise TimeoutException(message, screen, stacktrace)
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)
>> Tests to check if Debugger is vulnerable to XSS
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>> line 41, in runTest
>>     self.page.add_server(self.server)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 65, in add_server
>>     self.find_by_xpath("//button[contains(.,'Save')]").click()
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 80, in click
>>     self._execute(Command.CLICK_ELEMENT)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 628, in _execute
>>     return self._parent.execute(command, params)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>     self.error_handler.check_response(response)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/errorhandler.py", line 242, in
>> check_response
>>     raise exception_class(message, screen, stacktrace)
>> WebDriverException: Message: unknown error: Element <button type="save"
>> class="btn btn-primary" title="Save this object.">...</button> is not
>> clickable at point (661, 761). Other element would receive the click: <div
>> class="pg-bg-etime">...</div>
>>   (Session info: chrome=66.0.3359.181)
>>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
>> OS X 10.12.6 x86_64)
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)
>> Tests to check if Debugger is vulnerable to XSS
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
>> line 66, in tearDown
>>     self.after()
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>> line 46, in after
>>     self.page.remove_server(self.server)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 124, in remove_server
>>     "' and @class='aciTreeItem']")
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>     return self._wait_for("element to exist", element_if_it_exists)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>     "Timed out waiting for " + waiting_for_message
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>     raise TimeoutException(message, screen, stacktrace)
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_roles_control_test.CheckRoleMembershipControlFeatureTest)
>> Tests to check if Role membership control is vulnerable to XSS
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_roles_control_test.py",
>> line 37, in runTest
>>     self.page.add_server(self.server)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 65, in add_server
>>     self.find_by_xpath("//button[contains(.,'Save')]").click()
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 80, in click
>>     self._execute(Command.CLICK_ELEMENT)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webelement.py", line 628, in _execute
>>     return self._parent.execute(command, params)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/webdriver.py", line 312, in execute
>>     self.error_handler.check_response(response)
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/remote/errorhandler.py", line 242, in
>> check_response
>>     raise exception_class(message, screen, stacktrace)
>> WebDriverException: Message: unknown error: Element <button type="save"
>> class="btn btn-primary" title="Save this object.">...</button> is not
>> clickable at point (661, 761). Other element would receive the click: <div
>> class="pg-bg-etime">...</div>
>>   (Session info: chrome=66.0.3359.181)
>>   (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
>> OS X 10.12.6 x86_64)
>>
>>
>> ======================================================================
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_roles_control_test.CheckRoleMembershipControlFeatureTest)
>> Tests to check if Role membership control is vulnerable to XSS
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/base_feature_test.py",
>> line 66, in tearDown
>>     self.after()
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_roles_control_test.py",
>> line 42, in after
>>     self.page.remove_server(self.server)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 124, in remove_server
>>     "' and @class='aciTreeItem']")
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>     return self._wait_for("element to exist", element_if_it_exists)
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>     "Timed out waiting for " + waiting_for_message
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>     raise TimeoutException(message, screen, stacktrace)
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>> ======================================================================
>> FAIL: runTest (pgadmin.feature_tests.pg_util
>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>> Test for PG maintenance: database pg_maintenance
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 63, in runTest
>>     self._verify_command()
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 90, in _verify_command
>>     self.assertEquals(command, "VACUUM "
>> AssertionError: u'Backing up an object on the server \'Regression - PG
>> 9.4 Feature Tests (localhost:5432)\' from database
>> \'pg_utility_test_db\'...\nRunning command:\n/Library/PostgreSQL/9.4/bin/pg_dump
>> --file "/Users/dpage/test_backup" --host "localhost" --port "5432"
>> --username "postgres" --no-password --verbose --format=c --blobs
>> "pg_utility_test_db"' != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE;'
>>
>> ======================================================================
>> FAIL: runTest (pgadmin.feature_tests.pg_util
>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>> Test for PG maintenance: database
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 63, in runTest
>>     self._verify_command()
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 97, in _verify_command
>>     " public." + self.table_name + ";")
>> AssertionError: u'Backing up an object on the server \'Regression - PG
>> 9.4 Feature Tests (localhost:5432)\' from database
>> \'pg_utility_test_db\'...\nRunning command:\n/Library/PostgreSQL/9.4/bin/pg_dump
>> --file "/Users/dpage/test_backup" --host "localhost" --port "5432"
>> --username "postgres" --no-password --verbose --format=c --blobs
>> "pg_utility_test_db"' != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE
>> public.pg_maintenance_table;'
>>
>> ======================================================================
>> FAIL: runTest (pgadmin.tools.maintenance.tes
>> ts.test_create_maintenance_job.MaintenanceJobTest)
>> When maintenance the object with the default options
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/tes
>> ts/test_create_maintenance_job.py", line 85, in runTest
>>     self.assertIn(self.expected_cmd, process_list[0]['details'])
>> AssertionError: 'VACUUM VERBOSE' not found in u'<div class="h5">Backing
>> up an object on the server \'Regression - PG 9.4 Feature Tests
>> (localhost:5432)\' from database \'pg_utility_test_db\'...</div><div
>> class="h5">Running command:</b><br><span class="pg-bg-cmd
>> enable-selection">/Library/PostgreSQL/9.4/bin/pg_dump --file
>> "/Users/dpage/test_backup" --host "localhost" --port "5432" --username
>> "postgres" --no-password --verbose --format=c --blobs
>> "pg_utility_test_db"</span></div>'
>>
>> ----------------------------------------------------------------------
>> Ran 369 tests in 493.707s
>>
>> FAILED (failures=3, errors=8, skipped=21)
>>
>>
>>
>> On Wed, Jun 6, 2018 at 7:57 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Please find the atatched patch with the PEP8 fixes.
>>>
>>> On Wed, Jun 6, 2018 at 10:42 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi Dave,
>>>>
>>>> As per our discussion I have added the code to clean up the generated
>>>> files.
>>>> Please find the attached updated patch.
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>> On Wed, Jun 6, 2018 at 9:37 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Victoria,
>>>>>
>>>>> As per the logs, Restore job is failing only for GPDB. As I don't have
>>>>> setup for the greenplum database, can you please check this functionality
>>>>> works well in pgAdmin4 with GPDB?
>>>>>
>>>>> Thanks,
>>>>> Khushboo
>>>>>
>>>>> On Wed, Jun 6, 2018 at 5:13 AM, Victoria Henry <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Hi Khushboo
>>>>>>
>>>>>> The tests are still failing and seems flaky:
>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>>> /pgadmin-patch/jobs/run-tests/builds/113
>>>>>>
>>>>>> Sincerely,
>>>>>>
>>>>>> Victoria
>>>>>>
>>>>>> On Tue, Jun 5, 2018 at 4:50 AM Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Jun 5, 2018 at 2:09 PM, Dave Page <[email protected]> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Jun 5, 2018 at 9:37 AM, Khushboo Vashi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Tue, Jun 5, 2018 at 1:36 PM, Dave Page <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Hi
>>>>>>>>>>
>>>>>>>>>> On Tue, Jun 5, 2018 at 4:39 AM, Khushboo Vashi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Jun 4, 2018 at 8:41 PM, Joao De Almeida Pereira <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>
>>>>>>>>>>>> Some tests are failing in greenplum:
>>>>>>>>>>>> https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines
>>>>>>>>>>>> /pgadmin-patch/jobs/run-tests/builds/108
>>>>>>>>>>>> The piece of code responsible for the error is:
>>>>>>>>>>>>
>>>>>>>>>>>> if server['default_binary_paths'] is not None:
>>>>>>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>>>>>>
>>>>>>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>>>>>>         "gpdb": ""
>>>>>>>>>>>>     }
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Can you send me the test_config.json file?  The above code sets
>>>>>>>>>>> the paths to the SQLite database and through the logs couldn't figure out
>>>>>>>>>>> the exact failure.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> It seems clear from the code shown that it's not setting the
>>>>>>>>>> binary paths for gpdb database servers. Shouldn't it be something like:
>>>>>>>>>>
>>>>>>>>>>     config.DEFAULT_BINARY_PATHS = {
>>>>>>>>>>         "pg": str(server['default_binary_paths']['pg']),
>>>>>>>>>>         "ppas": str(server['default_binary_paths']['ppas']),
>>>>>>>>>>         "gpdb": str(server['default_binary_paths']['gpdb'])
>>>>>>>>>>     }
>>>>>>>>>>
>>>>>>>>>> Without this code, the test cases should work as I already set
>>>>>>>>> paths through below code.
>>>>>>>>>
>>>>>>>>>     test_utils.set_preference(server['default_binary_paths'])
>>>>>>>>>
>>>>>>>>>
>>>>>>>> In that case, why is the code above required at all?
>>>>>>>>
>>>>>>>> My bad. Removed this code and also updated set_preference function
>>>>>>> for greenplum database.
>>>>>>> Please find the attached updated patch.
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> test_backup_utils.py file name is misleading, these are not
>>>>>>>>>>>> tests, are helpers.
>>>>>>>>>>>> ​
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks
>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>
>>>>>>>>>>>> On Mon, Jun 4, 2018 at 1:36 AM Khushboo Vashi <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Sat, Jun 2, 2018 at 3:01 AM, Dave Page <[email protected]>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> This looks good, except that it's leaving the
>>>>>>>>>>>>>> test_restore_database behind. Can we clean that up please?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> PFA updated patch.
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Fri, Jun 1, 2018 at 7:06 AM, Khushboo Vashi <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi Victoria,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks for reviewing the patch.
>>>>>>>>>>>>>>> The tests were failing due to the latest commit
>>>>>>>>>>>>>>> #2b4605a9d390cb44e5dfe9967c3adf2b28d04f1f  - Ensure
>>>>>>>>>>>>>>> backup/restore/maintenance work via SSH tunnels. Fixes #3355
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I have fixed the issues and attached the updated patch.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Thu, May 31, 2018 at 10:00 PM, Victoria Henry <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi there,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> We've been noticing some issues with the tests on both our
>>>>>>>>>>>>>>>> CI and local Mac workstations.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    1. When the following code blocks are invoked - we get
>>>>>>>>>>>>>>>>    plenty of app.context() issues. It must not be valid
>>>>>>>>>>>>>>>>    when running tests.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ​
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> from pgadmin.utils.driver import get_driver
>>>>>>>>>>>>>>>> driver = get_driver(PG_DEFAULT_DRIVER)
>>>>>>>>>>>>>>>> manager = driver.connection_manager(self.sid)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>>>>>>>>>>>>>>> port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2. When we finally enable
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> "default_binary_paths": {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> in our test_config, we get more failing tests that look
>>>>>>>>>>>>>>>> like:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ======================================================================
>>>>>>>>>>>>>>>> FAIL: runTest (pgadmin.tools.restore.tests.test_restore_create_job_unit_test.RestoreCreateJobTest)
>>>>>>>>>>>>>>>> When restore object with option - Miscellaneous
>>>>>>>>>>>>>>>> ----------------------------------------------------------------------
>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/unittest/mock.py", line 1179, in patched
>>>>>>>>>>>>>>>>     return func(*args, **keywargs)
>>>>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py", line 295, in runTest
>>>>>>>>>>>>>>>>     self.assertEquals(response.status_code, 200)
>>>>>>>>>>>>>>>> AssertionError: 410 != 200
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> When restore object with the sections options ... 2018-05-31 12:24:42,988: ERROR    pgadmin:    illegal environment variable name
>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/tools/restore/__init__.py", line 352, in create_restore_job
>>>>>>>>>>>>>>>>     manager.export_password_env(p.id)
>>>>>>>>>>>>>>>>   File "/Users/pivotal/workspace/pgadmin4/web/pgadmin/utils/driver/psycopg2/server_manager.py", line 365, in export_password_env
>>>>>>>>>>>>>>>>     os.environ[str(env)] = password
>>>>>>>>>>>>>>>>   File "/Users/pivotal/.pyenv/versions/3.6.5/lib/python3.6/os.py", line 675, in __setitem__
>>>>>>>>>>>>>>>>     self.putenv(key, value)
>>>>>>>>>>>>>>>> ValueError: illegal environment variable name
>>>>>>>>>>>>>>>> FAIL
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ​
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sincerely,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Victoria && Anthony
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Thu, May 31, 2018 at 1:16 AM Khushboo Vashi <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Please find the attached updated patch with the fixes.
>>>>>>>>>>>>>>>>> The test cases were only failing on MAC not on Linux.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, May 30, 2018 at 10:13 AM, Khushboo Vashi <
>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Wed, May 30, 2018 at 1:05 AM, Dave Page <
>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hi
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Mon, May 28, 2018 at 8:09 AM, Khushboo Vashi <
>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> please find the attached updated patch for the test
>>>>>>>>>>>>>>>>>>>> cases of Backup, Restore and Maintenance modules which includes:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Thanks. I've yet to be able to run the feature tests
>>>>>>>>>>>>>>>>>>> successfully. Here's what I've found so far:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 1) DEFAULT_BINARY_PATHS should be default_binary_paths
>>>>>>>>>>>>>>>>>>> in the JSON config file.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Will do.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2) I've hit screensize related issues:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================
>>>>>>>>>>>>>>>>>>> ========================================
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>>>>>> ities_maintenance_test.PGUtili
>>>>>>>>>>>>>>>>>>> tiesMaintenanceFeatureTest)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Test for PG maintenance: database
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>>>>>>> ----------------------------------------
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>>>>>> line 56, in runTest
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     self._open_maintenance_dialogue()
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>>>>>>>>>>>>>>>>>>> line 75, in _open_maintenance_dialogue
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     "*[.='" + self.table_name +
>>>>>>>>>>>>>>>>>>> "']/../*[@class='aciTreeItem'"
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webelement.py", line 80,
>>>>>>>>>>>>>>>>>>> in click
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     self._execute(Command.CLICK_ELEMENT)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webelement.py", line 628,
>>>>>>>>>>>>>>>>>>> in _execute
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     return self._parent.execute(command, params)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/webdriver.py", line 312,
>>>>>>>>>>>>>>>>>>> in execute
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     self.error_handler.check_response(response)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/remote/errorhandler.py", line
>>>>>>>>>>>>>>>>>>> 242, in check_response
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     raise exception_class(message, screen, stacktrace)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> WebDriverException: Message: unknown error: Element
>>>>>>>>>>>>>>>>>>> <span class="aciTreeItem">...</span> is not clickable at point (223, 604).
>>>>>>>>>>>>>>>>>>> Other element would receive the click: <div class="wcFrameCenter
>>>>>>>>>>>>>>>>>>> wcPanelBackground wcScrollableX wcScrollableY" style="left: 0px; right:
>>>>>>>>>>>>>>>>>>> 0px; bottom: 0px;">...</div>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   (Session info: chrome=66.0.3359.181)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   (Driver info: chromedriver=2.38.552518
>>>>>>>>>>>>>>>>>>> (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac
>>>>>>>>>>>>>>>>>>> OS X 10.12.6 x86_64)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 3) One time the test did start, but then I saw this
>>>>>>>>>>>>>>>>>>> failure:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ==============================
>>>>>>>>>>>>>>>>>>> ========================================
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>>>>>>>>>>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Test for PG utilities - Backup and Restore
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>>>>>>> ----------------------------------------
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Traceback (most recent call last):
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>>> /pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>>>>>>>>>>>>>>> line 93, in runTest
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     self.page.fill_input_by_field_name("file",
>>>>>>>>>>>>>>>>>>> "test_backup_file")
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 211,
>>>>>>>>>>>>>>>>>>> in fill_input_by_field_name
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     self.wait_for_input_field_content(field_name,
>>>>>>>>>>>>>>>>>>> field_content)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 251,
>>>>>>>>>>>>>>>>>>> in wait_for_input_field_content
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     "field to contain '" + str(content) + "'",
>>>>>>>>>>>>>>>>>>> input_field_has_content
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/git/pgadmin4/web
>>>>>>>>>>>>>>>>>>> /regression/feature_utils/pgadmin_page.py", line 337,
>>>>>>>>>>>>>>>>>>> in _wait_for
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   File "/Users/dpage/.virtualenvs/pga
>>>>>>>>>>>>>>>>>>> dmin4/lib/python2.7/site-packa
>>>>>>>>>>>>>>>>>>> ges/selenium/webdriver/support/wait.py", line 80, in
>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> TimeoutException: Message: Timed out waiting for field
>>>>>>>>>>>>>>>>>>> to contain 'test_backup_file'
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> (with screenshot attached)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I have ran the feature tests with multiple servers many
>>>>>>>>>>>>>>>>>> times but didn't get a single failure.
>>>>>>>>>>>>>>>>>> I have asked Akshay to run on his machine, let see what
>>>>>>>>>>>>>>>>>> he gets.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 9:40 PM, Joao De Almeida
>>>>>>>>>>>>>>>>>>>> Pereira <[email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Hi Khushboo,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> We reviewed the patch and it is very nice to see some
>>>>>>>>>>>>>>>>>>>>> more coverage in this area. Good job :D
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> We passed the tests through our CI the feature tests
>>>>>>>>>>>>>>>>>>>>> are not passing, but the linter fails:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:37: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:53: [E501] line too long (104 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:59: [E501] line too long (85 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:62: [E501] line too long (96 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:63: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/feature_tests/pg_utilities_backup_test.py:70: [E501] line too long (118 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:37: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:48: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:49: [E251] unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:51: [E501] line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:52: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:53: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:81: [E501] line too long (113 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:82: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:83: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:111: [E501] line too long (100 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:113: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:114: [E501] line too long (108 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_backup_message.py:147: [E501] line too long (93 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:40: [E121] continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:51: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:135: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:137: [E501] line too long (83 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:138: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:139: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:140: [E122] continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:191: [E501] line too long (81 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:203: [E501] line too long (80 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:204: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E128] continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:205: [E501] line too long (94 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_batch_process.py:216: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:296: [E501] line too long (97 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:317: [E303] too many blank lines (2)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:336: [E501] line too long (84 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/backup/tests/test_create_backup_job.py:371: [W391] blank line at end of file
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 2       E121 continuation line under-indented for hanging indent
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 5       E122 continuation line missing indentation or outdented
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 2       E128 continuation line under-indented for visual indent
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 2       E251 unexpected spaces around keyword / parameter equals
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 1       E303 too many blank lines (2)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 24      E501 line too long (91 > 79 characters)
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 2       W391 blank line at end of file
>>>>>>>>>>>>>>>>>>>>>  <https://gpdb-dev.bosh.pivotalci.info/teams/pgadmin/pipelines/pgadmin-patch/jobs/run-linter/builds/17...;
>>>>>>>>>>>>>>>>>>>>> 38
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> For the feature tests, we realized we had to update
>>>>>>>>>>>>>>>>>>>>> the configuration, and we did that, but we get the following error
>>>>>>>>>>>>>>>>>>>>> attached. We spent some time trying to understand the problem but we were
>>>>>>>>>>>>>>>>>>>>> not successful.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Codewise:
>>>>>>>>>>>>>>>>>>>>> - We just found some One Letter Variables in the
>>>>>>>>>>>>>>>>>>>>> code...
>>>>>>>>>>>>>>>>>>>>> - Looks like there is a bug report in this area of the
>>>>>>>>>>>>>>>>>>>>> code and we do not have coverage for it:
>>>>>>>>>>>>>>>>>>>>> https://redmine.postgresql.org/issues/3232
>>>>>>>>>>>>>>>>>>>>>   Looks like in some of the unit tests we only have
>>>>>>>>>>>>>>>>>>>>> happy path tests, maybe we should see if there are any sad paths that also
>>>>>>>>>>>>>>>>>>>>> need coverage.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> The configuration change, maybe need to be updated.
>>>>>>>>>>>>>>>>>>>>> When we install multiple versions of postgres the binaries live in
>>>>>>>>>>>>>>>>>>>>> `/usr/lib/postgresql/{{db_version}}/bin`, which makes
>>>>>>>>>>>>>>>>>>>>> us think that this configuration should live near the server configuration,
>>>>>>>>>>>>>>>>>>>>> maybe? Also to maintain coherency on the naming maybe we should make it all
>>>>>>>>>>>>>>>>>>>>> lower case.
>>>>>>>>>>>>>>>>>>>>> Just as an aside, you can add the gpdb configuration
>>>>>>>>>>>>>>>>>>>>> as well in you patch.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>>>>>>> Victoria & Joao
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Wed, Apr 25, 2018 at 5:20 AM Khushboo Vashi <
>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch which covers test
>>>>>>>>>>>>>>>>>>>>>> cases for the backup module (RM #3206).
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> 1. Unit test cases
>>>>>>>>>>>>>>>>>>>>>> 2. End to end regression test cases
>>>>>>>>>>>>>>>>>>>>>> 3. Feature test cases
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>>>> Khushboo
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>
>>>>
>>>
>>
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>
>


Attachments:

  [application/octet-stream] RM_3206_ver7.patch (108.8K, 3-RM_3206_ver7.patch)
  download | inline diff:
diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
new file mode 100644
index 0000000..6bc60a6
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -0,0 +1,151 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import os
+
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+import config
+
+
+class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities - Backup and Restore test scenarios """
+
+    scenarios = [
+        ("Test for PG utilities - Backup and Restore", dict())
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
+
+        test_utils.create_database(self.server, "pg_utility_test_db")
+        self.page.add_server(self.server)
+
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('pg_utility_test_db')
+        self.driver.find_element_by_link_text("Tools").click()
+
+        self.page.find_by_partial_link_text("Backup...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') "
+                                "and contains(.,'Backup')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(), "
+                                "'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class, "
+                                          "'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("from database 'pg_utility_test_db'", str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_dump", str(command))
+
+        backup_file = None
+        if command:
+            backup_file = command[int(command.find('--file')) +
+                                  8:int(command.find('--host')) - 2]
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
+                                "]//div[contains(@class,'fa-close')]").click()
+
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Restore...").click()
+
+        self.wait.until(EC.presence_of_element_located(
+            (
+                By.XPATH,
+                "//label[contains(string(), 'Filename')]"
+            )
+        ))
+
+        self.wait.until(EC.element_to_be_clickable(
+            (By.CSS_SELECTOR, ".browse_file_input"))).click()
+
+        self.page.fill_input_by_field_name("file", "test_backup")
+        self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
+                                " and contains(.,'Restore')]").click()
+
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+
+        self.assertIn(self.server['name'], str(command))
+        self.assertIn("test_backup", str(command))
+        self.assertIn("pg_restore", str(command))
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]"
+                                "//div[contains(@class,'fa-close')]").click()
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, "pg_utility_test_db")
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
new file mode 100644
index 0000000..7806268
--- /dev/null
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -0,0 +1,112 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+# _*_  coding: utf-8 _*_
+import time
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+from regression.python_test_utils import test_utils
+
+
+class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
+    """ This class test PG utilities test scenarios """
+
+    scenarios = [
+        ("Test for PG maintenance: database pg_maintenance", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='database'
+        )),
+        ("Test for PG maintenance: database", dict(
+            database_name='pg_maintenance',
+            table_name='pg_maintenance_table',
+            test_level='table'
+        )),
+    ]
+
+    def before(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.create_database(self.server, self.database_name)
+        test_utils.create_table(self.server, self.database_name,
+                                self.table_name)
+        self.page.add_server(self.server)
+        self.wait = WebDriverWait(self.page.driver, 20)
+
+    def runTest(self):
+        self._open_maintenance_dialogue()
+        # time.sleep
+        self.page.find_by_xpath("//button[contains(@class,'fa-save') and"
+                                " contains(.,'OK')]").click()
+        self.page.wait_for_element_to_disappear(
+            lambda driver: driver.find_element_by_css_selector(".ajs-modal")
+        )
+        self._verify_command()
+
+    def _open_maintenance_dialogue(self):
+        self.page.toggle_open_server(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item(self.database_name)
+        if self.test_level == 'table':
+            self.page.toggle_open_tree_item('Schemas')
+            self.page.toggle_open_tree_item('public')
+            self.page.toggle_open_tree_item('Tables')
+            self.page.find_by_xpath(
+                "//*[@id='tree']//"
+                "*[.='" + self.table_name + "']/../*[@class='aciTreeItem'"
+                                            "]").click()
+        self.driver.find_element_by_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Maintenance...").click()
+        time.sleep(0.5)
+
+    def _verify_command(self):
+        status = self.page.find_by_xpath("//div[contains(@class,"
+                                         "'bg-success')]").text
+        self.assertEquals(status, "Successfully completed.")
+        self.page.find_by_xpath("//span[contains(string(),"
+                                " 'Click here for details.')]").click()
+        command = self.page.find_by_xpath("//p[contains(@class,"
+                                          " 'bg-detailed-desc')]").text
+        if self.test_level == 'database':
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE;")
+        else:
+            self.assertEquals(command, "VACUUM "
+                                       "(VERBOSE)\nRunning Query:"
+                                       "\nVACUUM VERBOSE"
+                                       " public." + self.table_name + ";")
+
+        self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')]//"
+                                "div[contains(@class,'fa-close')]").click()
+
+    def after(self):
+        self.page.remove_server(self.server)
+        connection = test_utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        test_utils.drop_database(connection, self.database_name)
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..9313ee9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    backup_file = None
+    if 'details' in process_list[0]:
+        backup_det = process_list[0]['details']
+        backup_file = backup_det[int(backup_det.find('--file')) +
+                                 8:int(backup_det.find('--host')) - 2]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+    return backup_file
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..3e3fe92
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,63 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_file = backup_utils.run_backup_job(self.tester,
+                                                  job_id,
+                                                  self.expected_params,
+                                                  self.assertIn,
+                                                  self.assertNotIn
+                                                  )
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..58aef5c
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,198 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..ca1ab2c
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,203 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import os
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        self.backup_file = backup_utils.run_backup_job(
+            self.tester,
+            job_id,
+            self.backup_options['expected_params'],
+            self.assertIn,
+            self.assertNotIn
+        )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+        if self.backup_file is not None:
+            if os.path.isfile(self.backup_file):
+                os.remove(self.backup_file)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..247e3fb 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -213,7 +216,7 @@ def get_test_modules(arguments):
                 if 'headless_chrome' in test_setup.config_data:
                     if test_setup.config_data['headless_chrome']:
                         options.add_argument("--headless")
-            options.add_argument("--window-size=1280x1024")
+            options.add_argument("--window-size=1280x800")
             driver = webdriver.Chrome(chrome_options=options)
 
         app_starter = AppStarter(driver, config)
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-08 09:08                                           ` Dave Page <[email protected]>
  2018-06-12 10:24                                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Dave Page @ 2018-06-08 09:08 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi

On Fri, Jun 8, 2018 at 6:33 AM, Khushboo Vashi <
[email protected]> wrote:

> Hi Dave,
>
> As per our discussion I have changed the window size to 1280X800, before
> it was 1280X900.
> Please find the attached updated patch
>

I'm not sure that actually made any difference on my system. The window
continued to look taller than it is wide, so I wonder if the code to set
the size is being ignored, or is at the wrong place?

Anyway, I got 10 failures with this patch :-(

======================================================================

ERROR: runTest
(pgadmin.feature_tests.pg_utilities_backup_restore_test.PGUtilitiesBackupFeatureTest)

Test for PG utilities - Backup and Restore

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
line 97, in runTest

    self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 171, in find_by_xpath

    lambda driver: driver.find_element_by_xpath(xpath)

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 263, in wait_for_element

    return self._wait_for("element to exist", element_if_it_exists)

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 337, in _wait_for

    "Timed out waiting for " + waiting_for_message

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
line 80, in until

    raise TimeoutException(message, screen, stacktrace)

TimeoutException: Message: Timed out waiting for element to exist



======================================================================

ERROR: runTest
(pgadmin.feature_tests.xss_checks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)

Tests to check if Debugger is vulnerable to XSS

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
line 42, in runTest

    self._function_node_expandable()

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
line 57, in _function_node_expandable

    self.page.select_tree_item("a_test_function()")

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 135, in select_tree_item

    "' and @class='aciTreeItem']").click()

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 171, in find_by_xpath

    lambda driver: driver.find_element_by_xpath(xpath)

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 263, in wait_for_element

    return self._wait_for("element to exist", element_if_it_exists)

  File
"/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
line 337, in _wait_for

    "Timed out waiting for " + waiting_for_message

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/selenium/webdriver/support/wait.py",
line 80, in until

    raise TimeoutException(message, screen, stacktrace)

TimeoutException: Message: Timed out waiting for element to exist



======================================================================

ERROR: runTest
(pgadmin.tools.backup.tests.test_create_backup_job.BackupJobTest)

When backup the object with the default options

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_create_backup_job.py",
line 58, in runTest

    self.assertNotIn

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
line 33, in run_backup_job

    random.randint(1, 9999999)))

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 830, in get

    return self.open(*args, **kw)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
line 127, in open

    follow_redirects=follow_redirects)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 803, in open

    response = self.run_wsgi_app(environ, buffered=buffered)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 716, in run_wsgi_app

    rv = run_wsgi_app(self.application, environ, buffered=buffered)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 923, in run_wsgi_app

    app_rv = app(environ, start_response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1997, in __call__

    return self.wsgi_app(environ, start_response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1985, in wsgi_app

    response = self.handle_exception(e)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1540, in handle_exception

    reraise(exc_type, exc_value, tb)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1982, in wsgi_app

    response = self.full_dispatch_request()

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1614, in full_dispatch_request

    rv = self.handle_user_exception(e)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1517, in handle_user_exception

    reraise(exc_type, exc_value, tb)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1612, in full_dispatch_request

    rv = self.dispatch_request()

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1598, in dispatch_request

    return self.view_functions[rule.endpoint](**req.view_args)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
line 792, in decorated_view

    return func(*args, **kwargs)

  File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
line 62, in index

    return make_response(response=BatchProcess.list())

  File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
line 584, in list

    details = desc.details(p.command, args)

  File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
line 159, in details

    name, host, port = self.get_server_details()

  File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
line 122, in get_server_details

    host = manager.local_bind_host if manager.use_ssh_tunnel else s.host

AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'


======================================================================

ERROR: runTest
(pgadmin.tools.maintenance.tests.test_create_maintenance_job.MaintenanceJobTest)

When maintenance the object with the default options

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py",
line 71, in runTest

    random.randint(1, 9999999)))

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 830, in get

    return self.open(*args, **kw)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
line 127, in open

    follow_redirects=follow_redirects)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 803, in open

    response = self.run_wsgi_app(environ, buffered=buffered)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 716, in run_wsgi_app

    rv = run_wsgi_app(self.application, environ, buffered=buffered)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 923, in run_wsgi_app

    app_rv = app(environ, start_response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1997, in __call__

    return self.wsgi_app(environ, start_response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1985, in wsgi_app

    response = self.handle_exception(e)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1540, in handle_exception

    reraise(exc_type, exc_value, tb)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1982, in wsgi_app

    response = self.full_dispatch_request()

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1614, in full_dispatch_request

    rv = self.handle_user_exception(e)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1517, in handle_user_exception

    reraise(exc_type, exc_value, tb)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1612, in full_dispatch_request

    rv = self.dispatch_request()

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1598, in dispatch_request

    return self.view_functions[rule.endpoint](**req.view_args)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
line 792, in decorated_view

    return func(*args, **kwargs)

  File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
line 62, in index

    return make_response(response=BatchProcess.list())

  File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
line 584, in list

    details = desc.details(p.command, args)

  File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
line 159, in details

    name, host, port = self.get_server_details()

  File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
line 122, in get_server_details

    host = manager.local_bind_host if manager.use_ssh_tunnel else s.host

AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'


======================================================================

ERROR: runTest
(pgadmin.tools.restore.tests.test_create_restore_job.RestoreJobTest)

When restore the object with the default options

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
line 95, in runTest

    self.create_backup()

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
line 86, in create_backup

    self.assertNotIn

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
line 33, in run_backup_job

    random.randint(1, 9999999)))

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 830, in get

    return self.open(*args, **kw)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
line 127, in open

    follow_redirects=follow_redirects)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 803, in open

    response = self.run_wsgi_app(environ, buffered=buffered)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 716, in run_wsgi_app

    rv = run_wsgi_app(self.application, environ, buffered=buffered)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
line 923, in run_wsgi_app

    app_rv = app(environ, start_response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1997, in __call__

    return self.wsgi_app(environ, start_response)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1985, in wsgi_app

    response = self.handle_exception(e)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1540, in handle_exception

    reraise(exc_type, exc_value, tb)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1982, in wsgi_app

    response = self.full_dispatch_request()

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1614, in full_dispatch_request

    rv = self.handle_user_exception(e)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1517, in handle_user_exception

    reraise(exc_type, exc_value, tb)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1612, in full_dispatch_request

    rv = self.dispatch_request()

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1598, in dispatch_request

    return self.view_functions[rule.endpoint](**req.view_args)

  File
"/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
line 792, in decorated_view

    return func(*args, **kwargs)

  File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
line 62, in index

    return make_response(response=BatchProcess.list())

  File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
line 584, in list

    details = desc.details(p.command, args)

  File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
line 159, in details

    name, host, port = self.get_server_details()

  File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
line 122, in get_server_details

    host = manager.local_bind_host if manager.use_ssh_tunnel else s.host

AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'


======================================================================

FAIL: runTest
(pgadmin.browser.server_groups.servers.databases.schemas.functions.tests.test_trigger_func_add.TriggerFuncAddTestCase)

Fetch Trigger Function Node URL

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/test_trigger_func_add.py",
line 111, in runTest

    self.assertEquals(response.status_code, 200)

AssertionError: 500 != 200


======================================================================

FAIL: runTest
(pgadmin.browser.server_groups.servers.databases.schemas.functions.tests.test_trigger_func_delete.TriggerFuncDeleteTestCase)

Fetch Trigger Function Node URL

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/test_trigger_func_delete.py",
line 72, in runTest

    self.assertEquals(response.status_code, 200)

AssertionError: 500 != 200


======================================================================

FAIL: runTest
(pgadmin.browser.server_groups.servers.databases.schemas.functions.tests.test_trigger_func_get.TriggerFuncGetTestCase)

Fetch Trigger Function Node URL

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/test_trigger_func_get.py",
line 72, in runTest

    self.assertEquals(response.status_code, 200)

AssertionError: 500 != 200


======================================================================

FAIL: runTest
(pgadmin.browser.server_groups.servers.databases.schemas.functions.tests.test_trigger_func_put.TriggerFuncPutTestCase)

Fetch Trigger Function Node URL

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/test_trigger_func_put.py",
line 87, in runTest

    self.assertEquals(put_response.status_code, 200)

AssertionError: 500 != 200


======================================================================

FAIL: runTest
(pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)

Test for PG maintenance: database pg_maintenance

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
line 63, in runTest

    self._verify_command()

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
line 90, in _verify_command

    self.assertEquals(command, "VACUUM "

AssertionError: u'Backing up an object on the server \'Regression - PG 11
Feature Tests (localhost:5436)\' from database
\'pg_utility_test_db\'...\nRunning
command:\n/Library/PostgreSQL/11/bin/pg_dump --file
"/Users/dpage/test_backup" --host "localhost" --port "5436" --username
"postgres" --no-password --verbose --format=c --blobs "pg_utility_test_db"'
!= 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE;'


======================================================================

FAIL: runTest
(pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)

Test for PG maintenance: database

----------------------------------------------------------------------

Traceback (most recent call last):

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
line 63, in runTest

    self._verify_command()

  File
"/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
line 97, in _verify_command

    " public." + self.table_name + ";")

AssertionError: u'Backing up an object on the server \'Regression - PG 11
Feature Tests (localhost:5436)\' from database
\'pg_utility_test_db\'...\nRunning
command:\n/Library/PostgreSQL/11/bin/pg_dump --file
"/Users/dpage/test_backup" --host "localhost" --port "5436" --username
"postgres" --no-password --verbose --format=c --blobs "pg_utility_test_db"'
!= 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE
public.pg_maintenance_table;'


----------------------------------------------------------------------

Ran 369 tests in 417.660s


FAILED (failures=6, errors=5, skipped=13)


======================================================================

Test Result Summary

======================================================================


Regression - PG 11:


346 tests passed

10 tests failed:

TriggerFuncGetTestCase (Fetch Trigger Function Node URL)

MaintenanceJobTest (When maintenance the object with the default options)

TriggerFuncDeleteTestCase (Fetch Trigger Function Node URL)

TriggerFuncPutTestCase (Fetch Trigger Function Node URL)

RestoreJobTest (When restore the object with the default options)

CheckDebuggerForXssFeatureTest (Tests to check if Debugger is vulnerable to
XSS)

TriggerFuncAddTestCase (Fetch Trigger Function Node URL)

PGUtilitiesBackupFeatureTest (Test for PG utilities - Backup and Restore)

PGUtilitiesMaintenanceFeatureTest (Test for PG maintenance: database,

Test for PG maintenance: database pg_maintenance)

BackupJobTest (When backup the object with the default options)

13 tests skipped:

SynonymDeleteTestCase (Fetch synonym Node URL)

SynonymGetTestCase (Fetch synonym Node URL)

PackageDeleteTestCase (Fetch Package Node URL)

ResourceGroupsGetTestCase (Get resource groups)

TestSSLConnection (Test for SSL connection)

ResourceGroupsAddTestCase (Add resource groups)

PackagePutTestCase (Fetch Package Node URL)

SynonymPutTestCase (Fetch synonym Node URL)

ResourceGroupsPutTestCase (Put resource groups)

ResourceGroupsDeleteTestCase (Delete resource groups)

SynonymAddTestCase (Default Node URL)

PackageAddTestCase (Fetch Package Node URL)

PackageGetTestCase (Fetch Package Node URL)


======================================================================


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Attachments:

  [image/png] PGUtilitiesMaintenanceFeatureTest-2018.06.08_09.58.10-Python-2.7.10.png (207.1K, 3-PGUtilitiesMaintenanceFeatureTest-2018.06.08_09.58.10-Python-2.7.10.png)
  download | view image

  [image/png] CheckDebuggerForXssFeatureTest-2018.06.08_10.02.24-Python-2.7.10.png (207.3K, 4-CheckDebuggerForXssFeatureTest-2018.06.08_10.02.24-Python-2.7.10.png)
  download | view image

  [image/png] PGUtilitiesBackupFeatureTest-2018.06.08_09.57.51-Python-2.7.10.png (223.3K, 5-PGUtilitiesBackupFeatureTest-2018.06.08_09.57.51-Python-2.7.10.png)
  download | view image

  [image/png] PGUtilitiesMaintenanceFeatureTest-2018.06.08_09.58.00-Python-2.7.10.png (156.0K, 6-PGUtilitiesMaintenanceFeatureTest-2018.06.08_09.58.00-Python-2.7.10.png)
  download | view image

  [image/png] PGUtilitiesMaintenanceFeatureTest-2018.06.08_09.58.10-Python-2.7.10.png (207.1K, 7-PGUtilitiesMaintenanceFeatureTest-2018.06.08_09.58.10-Python-2.7.10.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
@ 2018-06-12 10:24                                             ` Khushboo Vashi <[email protected]>
  2018-06-12 10:44                                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-12 10:24 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi,

Please find the attached patch excluding feature test cases.
Python test cases are working fine, so we can commit this patch. I am
working on fixing the feature tests which are failing on the different
window sizes.

Thanks,
Khushboo

On Fri, Jun 8, 2018 at 2:38 PM, Dave Page <[email protected]> wrote:

> Hi
>
> On Fri, Jun 8, 2018 at 6:33 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi Dave,
>>
>> As per our discussion I have changed the window size to 1280X800, before
>> it was 1280X900.
>> Please find the attached updated patch
>>
>
> I'm not sure that actually made any difference on my system. The window
> continued to look taller than it is wide, so I wonder if the code to set
> the size is being ignored, or is at the wrong place?
>
> Anyway, I got 10 failures with this patch :-(
>
> ======================================================================
>
> ERROR: runTest (pgadmin.feature_tests.pg_util
> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>
> Test for PG utilities - Backup and Restore
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
> line 97, in runTest
>
>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>
>     lambda driver: driver.find_element_by_xpath(xpath)
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>
>     return self._wait_for("element to exist", element_if_it_exists)
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>
>     "Timed out waiting for " + waiting_for_message
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
> ges/selenium/webdriver/support/wait.py", line 80, in until
>
>     raise TimeoutException(message, screen, stacktrace)
>
> TimeoutException: Message: Timed out waiting for element to exist
>
>
>
> ======================================================================
>
> ERROR: runTest (pgadmin.feature_tests.xss_che
> cks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)
>
> Tests to check if Debugger is vulnerable to XSS
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
> line 42, in runTest
>
>     self._function_node_expandable()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
> line 57, in _function_node_expandable
>
>     self.page.select_tree_item("a_test_function()")
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 135, in select_tree_item
>
>     "' and @class='aciTreeItem']").click()
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 171, in find_by_xpath
>
>     lambda driver: driver.find_element_by_xpath(xpath)
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 263, in wait_for_element
>
>     return self._wait_for("element to exist", element_if_it_exists)
>
>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
> line 337, in _wait_for
>
>     "Timed out waiting for " + waiting_for_message
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
> ges/selenium/webdriver/support/wait.py", line 80, in until
>
>     raise TimeoutException(message, screen, stacktrace)
>
> TimeoutException: Message: Timed out waiting for element to exist
>
>
>
> ======================================================================
>
> ERROR: runTest (pgadmin.tools.backup.tests.te
> st_create_backup_job.BackupJobTest)
>
> When backup the object with the default options
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_create_backup_job.py",
> line 58, in runTest
>
>     self.assertNotIn
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
> line 33, in run_backup_job
>
>     random.randint(1, 9999999)))
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 830, in get
>
>     return self.open(*args, **kw)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
> line 127, in open
>
>     follow_redirects=follow_redirects)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 803, in open
>
>     response = self.run_wsgi_app(environ, buffered=buffered)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 716, in run_wsgi_app
>
>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 923, in run_wsgi_app
>
>     app_rv = app(environ, start_response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1997, in __call__
>
>     return self.wsgi_app(environ, start_response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1985, in wsgi_app
>
>     response = self.handle_exception(e)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1540, in handle_exception
>
>     reraise(exc_type, exc_value, tb)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1982, in wsgi_app
>
>     response = self.full_dispatch_request()
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1614, in full_dispatch_request
>
>     rv = self.handle_user_exception(e)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1517, in handle_user_exception
>
>     reraise(exc_type, exc_value, tb)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1612, in full_dispatch_request
>
>     rv = self.dispatch_request()
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1598, in dispatch_request
>
>     return self.view_functions[rule.endpoint](**req.view_args)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
> line 792, in decorated_view
>
>     return func(*args, **kwargs)
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
> line 62, in index
>
>     return make_response(response=BatchProcess.list())
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
> line 584, in list
>
>     details = desc.details(p.command, args)
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
> line 159, in details
>
>     name, host, port = self.get_server_details()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
> line 122, in get_server_details
>
>     host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>
> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>
>
> ======================================================================
>
> ERROR: runTest (pgadmin.tools.maintenance.tes
> ts.test_create_maintenance_job.MaintenanceJobTest)
>
> When maintenance the object with the default options
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/tes
> ts/test_create_maintenance_job.py", line 71, in runTest
>
>     random.randint(1, 9999999)))
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 830, in get
>
>     return self.open(*args, **kw)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
> line 127, in open
>
>     follow_redirects=follow_redirects)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 803, in open
>
>     response = self.run_wsgi_app(environ, buffered=buffered)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 716, in run_wsgi_app
>
>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 923, in run_wsgi_app
>
>     app_rv = app(environ, start_response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1997, in __call__
>
>     return self.wsgi_app(environ, start_response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1985, in wsgi_app
>
>     response = self.handle_exception(e)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1540, in handle_exception
>
>     reraise(exc_type, exc_value, tb)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1982, in wsgi_app
>
>     response = self.full_dispatch_request()
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1614, in full_dispatch_request
>
>     rv = self.handle_user_exception(e)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1517, in handle_user_exception
>
>     reraise(exc_type, exc_value, tb)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1612, in full_dispatch_request
>
>     rv = self.dispatch_request()
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1598, in dispatch_request
>
>     return self.view_functions[rule.endpoint](**req.view_args)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
> line 792, in decorated_view
>
>     return func(*args, **kwargs)
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
> line 62, in index
>
>     return make_response(response=BatchProcess.list())
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
> line 584, in list
>
>     details = desc.details(p.command, args)
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
> line 159, in details
>
>     name, host, port = self.get_server_details()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
> line 122, in get_server_details
>
>     host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>
> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>
>
> ======================================================================
>
> ERROR: runTest (pgadmin.tools.restore.tests.t
> est_create_restore_job.RestoreJobTest)
>
> When restore the object with the default options
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
> line 95, in runTest
>
>     self.create_backup()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
> line 86, in create_backup
>
>     self.assertNotIn
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
> line 33, in run_backup_job
>
>     random.randint(1, 9999999)))
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 830, in get
>
>     return self.open(*args, **kw)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
> line 127, in open
>
>     follow_redirects=follow_redirects)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 803, in open
>
>     response = self.run_wsgi_app(environ, buffered=buffered)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 716, in run_wsgi_app
>
>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
> line 923, in run_wsgi_app
>
>     app_rv = app(environ, start_response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1997, in __call__
>
>     return self.wsgi_app(environ, start_response)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1985, in wsgi_app
>
>     response = self.handle_exception(e)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1540, in handle_exception
>
>     reraise(exc_type, exc_value, tb)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1982, in wsgi_app
>
>     response = self.full_dispatch_request()
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1614, in full_dispatch_request
>
>     rv = self.handle_user_exception(e)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1517, in handle_user_exception
>
>     reraise(exc_type, exc_value, tb)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1612, in full_dispatch_request
>
>     rv = self.dispatch_request()
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1598, in dispatch_request
>
>     return self.view_functions[rule.endpoint](**req.view_args)
>
>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
> line 792, in decorated_view
>
>     return func(*args, **kwargs)
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
> line 62, in index
>
>     return make_response(response=BatchProcess.list())
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
> line 584, in list
>
>     details = desc.details(p.command, args)
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
> line 159, in details
>
>     name, host, port = self.get_server_details()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
> line 122, in get_server_details
>
>     host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>
> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>
>
> ======================================================================
>
> FAIL: runTest (pgadmin.browser.server_groups.servers.databases.schemas.
> functions.tests.test_trigger_func_add.TriggerFuncAddTestCase)
>
> Fetch Trigger Function Node URL
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
> /servers/databases/schemas/functions/tests/test_trigger_func_add.py",
> line 111, in runTest
>
>     self.assertEquals(response.status_code, 200)
>
> AssertionError: 500 != 200
>
>
> ======================================================================
>
> FAIL: runTest (pgadmin.browser.server_groups.servers.databases.schemas.
> functions.tests.test_trigger_func_delete.TriggerFuncDeleteTestCase)
>
> Fetch Trigger Function Node URL
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
> /servers/databases/schemas/functions/tests/test_trigger_func_delete.py",
> line 72, in runTest
>
>     self.assertEquals(response.status_code, 200)
>
> AssertionError: 500 != 200
>
>
> ======================================================================
>
> FAIL: runTest (pgadmin.browser.server_groups.servers.databases.schemas.
> functions.tests.test_trigger_func_get.TriggerFuncGetTestCase)
>
> Fetch Trigger Function Node URL
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
> /servers/databases/schemas/functions/tests/test_trigger_func_get.py",
> line 72, in runTest
>
>     self.assertEquals(response.status_code, 200)
>
> AssertionError: 500 != 200
>
>
> ======================================================================
>
> FAIL: runTest (pgadmin.browser.server_groups.servers.databases.schemas.
> functions.tests.test_trigger_func_put.TriggerFuncPutTestCase)
>
> Fetch Trigger Function Node URL
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
> /servers/databases/schemas/functions/tests/test_trigger_func_put.py",
> line 87, in runTest
>
>     self.assertEquals(put_response.status_code, 200)
>
> AssertionError: 500 != 200
>
>
> ======================================================================
>
> FAIL: runTest (pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtili
> tiesMaintenanceFeatureTest)
>
> Test for PG maintenance: database pg_maintenance
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
> line 63, in runTest
>
>     self._verify_command()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
> line 90, in _verify_command
>
>     self.assertEquals(command, "VACUUM "
>
> AssertionError: u'Backing up an object on the server \'Regression - PG 11
> Feature Tests (localhost:5436)\' from database
> \'pg_utility_test_db\'...\nRunning command:\n/Library/PostgreSQL/11/bin/pg_dump
> --file "/Users/dpage/test_backup" --host "localhost" --port "5436"
> --username "postgres" --no-password --verbose --format=c --blobs
> "pg_utility_test_db"' != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE;'
>
>
> ======================================================================
>
> FAIL: runTest (pgadmin.feature_tests.pg_utilities_maintenance_test.PGUtili
> tiesMaintenanceFeatureTest)
>
> Test for PG maintenance: database
>
> ----------------------------------------------------------------------
>
> Traceback (most recent call last):
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
> line 63, in runTest
>
>     self._verify_command()
>
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
> line 97, in _verify_command
>
>     " public." + self.table_name + ";")
>
> AssertionError: u'Backing up an object on the server \'Regression - PG 11
> Feature Tests (localhost:5436)\' from database
> \'pg_utility_test_db\'...\nRunning command:\n/Library/PostgreSQL/11/bin/pg_dump
> --file "/Users/dpage/test_backup" --host "localhost" --port "5436"
> --username "postgres" --no-password --verbose --format=c --blobs
> "pg_utility_test_db"' != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE
> public.pg_maintenance_table;'
>
>
> ----------------------------------------------------------------------
>
> Ran 369 tests in 417.660s
>
>
> FAILED (failures=6, errors=5, skipped=13)
>
>
> ======================================================================
>
> Test Result Summary
>
> ======================================================================
>
>
> Regression - PG 11:
>
>
> 346 tests passed
>
> 10 tests failed:
>
> TriggerFuncGetTestCase (Fetch Trigger Function Node URL)
>
> MaintenanceJobTest (When maintenance the object with the default options)
>
> TriggerFuncDeleteTestCase (Fetch Trigger Function Node URL)
>
> TriggerFuncPutTestCase (Fetch Trigger Function Node URL)
>
> RestoreJobTest (When restore the object with the default options)
>
> CheckDebuggerForXssFeatureTest (Tests to check if Debugger is vulnerable
> to XSS)
>
> TriggerFuncAddTestCase (Fetch Trigger Function Node URL)
>
> PGUtilitiesBackupFeatureTest (Test for PG utilities - Backup and Restore)
>
> PGUtilitiesMaintenanceFeatureTest (Test for PG maintenance: database,
>
> Test for PG maintenance: database pg_maintenance)
>
> BackupJobTest (When backup the object with the default options)
>
> 13 tests skipped:
>
> SynonymDeleteTestCase (Fetch synonym Node URL)
>
> SynonymGetTestCase (Fetch synonym Node URL)
>
> PackageDeleteTestCase (Fetch Package Node URL)
>
> ResourceGroupsGetTestCase (Get resource groups)
>
> TestSSLConnection (Test for SSL connection)
>
> ResourceGroupsAddTestCase (Add resource groups)
>
> PackagePutTestCase (Fetch Package Node URL)
>
> SynonymPutTestCase (Fetch synonym Node URL)
>
> ResourceGroupsPutTestCase (Put resource groups)
>
> ResourceGroupsDeleteTestCase (Delete resource groups)
>
> SynonymAddTestCase (Default Node URL)
>
> PackageAddTestCase (Fetch Package Node URL)
>
> PackageGetTestCase (Fetch Package Node URL)
>
>
> ======================================================================
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


Attachments:

  [application/octet-stream] RM_3206_exclude_feature_tests.patch (98.3K, 3-RM_3206_exclude_feature_tests.patch)
  download | inline diff:
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..9313ee9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    backup_file = None
+    if 'details' in process_list[0]:
+        backup_det = process_list[0]['details']
+        backup_file = backup_det[int(backup_det.find('--file')) +
+                                 8:int(backup_det.find('--host')) - 2]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+    return backup_file
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..3e3fe92
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,63 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_file = backup_utils.run_backup_job(self.tester,
+                                                  job_id,
+                                                  self.expected_params,
+                                                  self.assertIn,
+                                                  self.assertNotIn
+                                                  )
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..58aef5c
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,198 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..ca1ab2c
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,203 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import os
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        self.backup_file = backup_utils.run_backup_job(
+            self.tester,
+            job_id,
+            self.backup_options['expected_params'],
+            self.assertIn,
+            self.assertNotIn
+        )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+        if self.backup_file is not None:
+            if os.path.isfile(self.backup_file):
+                os.remove(self.backup_file)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..69e9f4d 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -213,8 +216,19 @@ def get_test_modules(arguments):
                 if 'headless_chrome' in test_setup.config_data:
                     if test_setup.config_data['headless_chrome']:
                         options.add_argument("--headless")
-            options.add_argument("--window-size=1280x1024")
             driver = webdriver.Chrome(chrome_options=options)
+            try:
+                if sys.version_info[0] < 3:
+                    import Tkinter as tkinter
+                else:
+                    import tkinter as tkinter
+
+                root = tkinter.Tk()
+                width = root.winfo_screenwidth()
+                height = root.winfo_screenheight()
+                driver.set_window_size(width, height)
+            except:
+                driver.set_window_size(1280, 800)
 
         app_starter = AppStarter(driver, config)
         app_starter.start_app()
@@ -234,7 +248,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +406,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-12 10:24                                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-12 10:44                                               ` Khushboo Vashi <[email protected]>
  2018-06-12 15:36                                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-12 10:44 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Please find the attached updated patch with some code cleanup.

On Tue, Jun 12, 2018 at 3:54 PM, Khushboo Vashi <
[email protected]> wrote:

> Hi,
>
> Please find the attached patch excluding feature test cases.
> Python test cases are working fine, so we can commit this patch. I am
> working on fixing the feature tests which are failing on the different
> window sizes.
>
> Thanks,
> Khushboo
>
> On Fri, Jun 8, 2018 at 2:38 PM, Dave Page <[email protected]> wrote:
>
>> Hi
>>
>> On Fri, Jun 8, 2018 at 6:33 AM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi Dave,
>>>
>>> As per our discussion I have changed the window size to 1280X800, before
>>> it was 1280X900.
>>> Please find the attached updated patch
>>>
>>
>> I'm not sure that actually made any difference on my system. The window
>> continued to look taller than it is wide, so I wonder if the code to set
>> the size is being ignored, or is at the wrong place?
>>
>> Anyway, I got 10 failures with this patch :-(
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.feature_tests.pg_util
>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>
>> Test for PG utilities - Backup and Restore
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>> line 97, in runTest
>>
>>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>
>>     return self._wait_for("element to exist", element_if_it_exists)
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>
>>     "Timed out waiting for " + waiting_for_message
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>
>>     raise TimeoutException(message, screen, stacktrace)
>>
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.feature_tests.xss_che
>> cks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)
>>
>> Tests to check if Debugger is vulnerable to XSS
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>> line 42, in runTest
>>
>>     self._function_node_expandable()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>> line 57, in _function_node_expandable
>>
>>     self.page.select_tree_item("a_test_function()")
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 135, in select_tree_item
>>
>>     "' and @class='aciTreeItem']").click()
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 171, in find_by_xpath
>>
>>     lambda driver: driver.find_element_by_xpath(xpath)
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 263, in wait_for_element
>>
>>     return self._wait_for("element to exist", element_if_it_exists)
>>
>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>> line 337, in _wait_for
>>
>>     "Timed out waiting for " + waiting_for_message
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>
>>     raise TimeoutException(message, screen, stacktrace)
>>
>> TimeoutException: Message: Timed out waiting for element to exist
>>
>>
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.tools.backup.tests.te
>> st_create_backup_job.BackupJobTest)
>>
>> When backup the object with the default options
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_create_backup_job.py",
>> line 58, in runTest
>>
>>     self.assertNotIn
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>> line 33, in run_backup_job
>>
>>     random.randint(1, 9999999)))
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 830, in get
>>
>>     return self.open(*args, **kw)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>> line 127, in open
>>
>>     follow_redirects=follow_redirects)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 803, in open
>>
>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 716, in run_wsgi_app
>>
>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 923, in run_wsgi_app
>>
>>     app_rv = app(environ, start_response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1997, in __call__
>>
>>     return self.wsgi_app(environ, start_response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1985, in wsgi_app
>>
>>     response = self.handle_exception(e)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1540, in handle_exception
>>
>>     reraise(exc_type, exc_value, tb)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1982, in wsgi_app
>>
>>     response = self.full_dispatch_request()
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1614, in full_dispatch_request
>>
>>     rv = self.handle_user_exception(e)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1517, in handle_user_exception
>>
>>     reraise(exc_type, exc_value, tb)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1612, in full_dispatch_request
>>
>>     rv = self.dispatch_request()
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1598, in dispatch_request
>>
>>     return self.view_functions[rule.endpoint](**req.view_args)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>> line 792, in decorated_view
>>
>>     return func(*args, **kwargs)
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>> line 62, in index
>>
>>     return make_response(response=BatchProcess.list())
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>> line 584, in list
>>
>>     details = desc.details(p.command, args)
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>> line 159, in details
>>
>>     name, host, port = self.get_server_details()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>> line 122, in get_server_details
>>
>>     host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>
>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.tools.maintenance.tes
>> ts.test_create_maintenance_job.MaintenanceJobTest)
>>
>> When maintenance the object with the default options
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/tes
>> ts/test_create_maintenance_job.py", line 71, in runTest
>>
>>     random.randint(1, 9999999)))
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 830, in get
>>
>>     return self.open(*args, **kw)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>> line 127, in open
>>
>>     follow_redirects=follow_redirects)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 803, in open
>>
>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 716, in run_wsgi_app
>>
>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 923, in run_wsgi_app
>>
>>     app_rv = app(environ, start_response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1997, in __call__
>>
>>     return self.wsgi_app(environ, start_response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1985, in wsgi_app
>>
>>     response = self.handle_exception(e)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1540, in handle_exception
>>
>>     reraise(exc_type, exc_value, tb)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1982, in wsgi_app
>>
>>     response = self.full_dispatch_request()
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1614, in full_dispatch_request
>>
>>     rv = self.handle_user_exception(e)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1517, in handle_user_exception
>>
>>     reraise(exc_type, exc_value, tb)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1612, in full_dispatch_request
>>
>>     rv = self.dispatch_request()
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1598, in dispatch_request
>>
>>     return self.view_functions[rule.endpoint](**req.view_args)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>> line 792, in decorated_view
>>
>>     return func(*args, **kwargs)
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>> line 62, in index
>>
>>     return make_response(response=BatchProcess.list())
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>> line 584, in list
>>
>>     details = desc.details(p.command, args)
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>> line 159, in details
>>
>>     name, host, port = self.get_server_details()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>> line 122, in get_server_details
>>
>>     host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>
>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>
>>
>> ======================================================================
>>
>> ERROR: runTest (pgadmin.tools.restore.tests.t
>> est_create_restore_job.RestoreJobTest)
>>
>> When restore the object with the default options
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
>> line 95, in runTest
>>
>>     self.create_backup()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
>> line 86, in create_backup
>>
>>     self.assertNotIn
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>> line 33, in run_backup_job
>>
>>     random.randint(1, 9999999)))
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 830, in get
>>
>>     return self.open(*args, **kw)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>> line 127, in open
>>
>>     follow_redirects=follow_redirects)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 803, in open
>>
>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 716, in run_wsgi_app
>>
>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>> line 923, in run_wsgi_app
>>
>>     app_rv = app(environ, start_response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1997, in __call__
>>
>>     return self.wsgi_app(environ, start_response)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1985, in wsgi_app
>>
>>     response = self.handle_exception(e)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1540, in handle_exception
>>
>>     reraise(exc_type, exc_value, tb)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1982, in wsgi_app
>>
>>     response = self.full_dispatch_request()
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1614, in full_dispatch_request
>>
>>     rv = self.handle_user_exception(e)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1517, in handle_user_exception
>>
>>     reraise(exc_type, exc_value, tb)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1612, in full_dispatch_request
>>
>>     rv = self.dispatch_request()
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>> line 1598, in dispatch_request
>>
>>     return self.view_functions[rule.endpoint](**req.view_args)
>>
>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>> line 792, in decorated_view
>>
>>     return func(*args, **kwargs)
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>> line 62, in index
>>
>>     return make_response(response=BatchProcess.list())
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>> line 584, in list
>>
>>     details = desc.details(p.command, args)
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>> line 159, in details
>>
>>     name, host, port = self.get_server_details()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>> line 122, in get_server_details
>>
>>     host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
>>
>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>
>>
>> ======================================================================
>>
>> FAIL: runTest (pgadmin.browser.server_groups
>> .servers.databases.schemas.functions.tests.test_trigger_func
>> _add.TriggerFuncAddTestCase)
>>
>> Fetch Trigger Function Node URL
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
>> /servers/databases/schemas/functions/tests/test_trigger_func_add.py",
>> line 111, in runTest
>>
>>     self.assertEquals(response.status_code, 200)
>>
>> AssertionError: 500 != 200
>>
>>
>> ======================================================================
>>
>> FAIL: runTest (pgadmin.browser.server_groups
>> .servers.databases.schemas.functions.tests.test_trigger_func
>> _delete.TriggerFuncDeleteTestCase)
>>
>> Fetch Trigger Function Node URL
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
>> /servers/databases/schemas/functions/tests/test_trigger_func_delete.py",
>> line 72, in runTest
>>
>>     self.assertEquals(response.status_code, 200)
>>
>> AssertionError: 500 != 200
>>
>>
>> ======================================================================
>>
>> FAIL: runTest (pgadmin.browser.server_groups
>> .servers.databases.schemas.functions.tests.test_trigger_func
>> _get.TriggerFuncGetTestCase)
>>
>> Fetch Trigger Function Node URL
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
>> /servers/databases/schemas/functions/tests/test_trigger_func_get.py",
>> line 72, in runTest
>>
>>     self.assertEquals(response.status_code, 200)
>>
>> AssertionError: 500 != 200
>>
>>
>> ======================================================================
>>
>> FAIL: runTest (pgadmin.browser.server_groups
>> .servers.databases.schemas.functions.tests.test_trigger_func
>> _put.TriggerFuncPutTestCase)
>>
>> Fetch Trigger Function Node URL
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups
>> /servers/databases/schemas/functions/tests/test_trigger_func_put.py",
>> line 87, in runTest
>>
>>     self.assertEquals(put_response.status_code, 200)
>>
>> AssertionError: 500 != 200
>>
>>
>> ======================================================================
>>
>> FAIL: runTest (pgadmin.feature_tests.pg_util
>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>
>> Test for PG maintenance: database pg_maintenance
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 63, in runTest
>>
>>     self._verify_command()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 90, in _verify_command
>>
>>     self.assertEquals(command, "VACUUM "
>>
>> AssertionError: u'Backing up an object on the server \'Regression - PG 11
>> Feature Tests (localhost:5436)\' from database
>> \'pg_utility_test_db\'...\nRunning command:\n/Library/PostgreSQL/11/bin/pg_dump
>> --file "/Users/dpage/test_backup" --host "localhost" --port "5436"
>> --username "postgres" --no-password --verbose --format=c --blobs
>> "pg_utility_test_db"' != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE;'
>>
>>
>> ======================================================================
>>
>> FAIL: runTest (pgadmin.feature_tests.pg_util
>> ities_maintenance_test.PGUtilitiesMaintenanceFeatureTest)
>>
>> Test for PG maintenance: database
>>
>> ----------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 63, in runTest
>>
>>     self._verify_command()
>>
>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py",
>> line 97, in _verify_command
>>
>>     " public." + self.table_name + ";")
>>
>> AssertionError: u'Backing up an object on the server \'Regression - PG 11
>> Feature Tests (localhost:5436)\' from database
>> \'pg_utility_test_db\'...\nRunning command:\n/Library/PostgreSQL/11/bin/pg_dump
>> --file "/Users/dpage/test_backup" --host "localhost" --port "5436"
>> --username "postgres" --no-password --verbose --format=c --blobs
>> "pg_utility_test_db"' != 'VACUUM (VERBOSE)\nRunning Query:\nVACUUM VERBOSE
>> public.pg_maintenance_table;'
>>
>>
>> ----------------------------------------------------------------------
>>
>> Ran 369 tests in 417.660s
>>
>>
>> FAILED (failures=6, errors=5, skipped=13)
>>
>>
>> ======================================================================
>>
>> Test Result Summary
>>
>> ======================================================================
>>
>>
>> Regression - PG 11:
>>
>>
>> 346 tests passed
>>
>> 10 tests failed:
>>
>> TriggerFuncGetTestCase (Fetch Trigger Function Node URL)
>>
>> MaintenanceJobTest (When maintenance the object with the default options)
>>
>> TriggerFuncDeleteTestCase (Fetch Trigger Function Node URL)
>>
>> TriggerFuncPutTestCase (Fetch Trigger Function Node URL)
>>
>> RestoreJobTest (When restore the object with the default options)
>>
>> CheckDebuggerForXssFeatureTest (Tests to check if Debugger is vulnerable
>> to XSS)
>>
>> TriggerFuncAddTestCase (Fetch Trigger Function Node URL)
>>
>> PGUtilitiesBackupFeatureTest (Test for PG utilities - Backup and Restore)
>>
>> PGUtilitiesMaintenanceFeatureTest (Test for PG maintenance: database,
>>
>> Test for PG maintenance: database pg_maintenance)
>>
>> BackupJobTest (When backup the object with the default options)
>>
>> 13 tests skipped:
>>
>> SynonymDeleteTestCase (Fetch synonym Node URL)
>>
>> SynonymGetTestCase (Fetch synonym Node URL)
>>
>> PackageDeleteTestCase (Fetch Package Node URL)
>>
>> ResourceGroupsGetTestCase (Get resource groups)
>>
>> TestSSLConnection (Test for SSL connection)
>>
>> ResourceGroupsAddTestCase (Add resource groups)
>>
>> PackagePutTestCase (Fetch Package Node URL)
>>
>> SynonymPutTestCase (Fetch synonym Node URL)
>>
>> ResourceGroupsPutTestCase (Put resource groups)
>>
>> ResourceGroupsDeleteTestCase (Delete resource groups)
>>
>> SynonymAddTestCase (Default Node URL)
>>
>> PackageAddTestCase (Fetch Package Node URL)
>>
>> PackageGetTestCase (Fetch Package Node URL)
>>
>>
>> ======================================================================
>>
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>
>


Attachments:

  [application/octet-stream] RM_3206_exclude_feature_tests.patch (97.4K, 3-RM_3206_exclude_feature_tests.patch)
  download | inline diff:
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..a376a3b
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,463 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert backup_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..34eacc9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        assert backup_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..9313ee9
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert response.status_code == 200
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assertIn, assertNotIn):
+    cnt = 0
+    while 1:
+        if cnt > 1:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert response1.status_code == 200
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert 'execution_time' in process_list[0]
+    assert 'stime' in process_list[0]
+    assert 'exit_code' in process_list[0]
+    assert process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ]
+
+    backup_file = None
+    if 'details' in process_list[0]:
+        backup_det = process_list[0]['details']
+        backup_file = backup_det[int(backup_det.find('--file')) +
+                                 8:int(backup_det.find('--host')) - 2]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assertIn(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assertNotIn(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert p_details.status_code == 200
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 10:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert p_details.status_code == 200
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert backup_ack.status_code == 200
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert backup_ack_res['success'] == 1
+
+    return backup_file
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..c074ca5
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,212 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.database, self.class_params['database'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "backup_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..3e3fe92
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,63 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params)
+        backup_file = backup_utils.run_backup_job(self.tester,
+                                                  job_id,
+                                                  self.expected_params,
+                                                  self.assertIn,
+                                                  self.assertNotIn
+                                                  )
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..55c3db8
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,153 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            self.assertEquals(cmd_obj.query, self.class_params['cmd'])
+            self.assertEquals(cmd_obj.message, self.expected_msg)
+            self.assertEquals(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..1e01f1d
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,140 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEquals(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..58aef5c
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,198 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..4cb89ed
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        assert maintenance_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..28d692a
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            assert isinstance(cmd_obj, IProcessDesc)
+            print(cmd_obj)
+            self.assertEquals(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEquals(cmd_obj.cmd,
+                              ' --file "restore_file" '
+                              '--host "{0}" '
+                              '--port "{1}" '
+                              '--username "{2}" '
+                              '--no-password '
+                              '--database "{3}"'.format(
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                              ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        assert db_mock.session.add.called
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert cmd_test in cmd
+                assert 'env' in kwargs
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        assert popen_mock.called
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        assert 'details' in ret_value[0]
+        assert 'desc' in ret_value[0]
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..ca1ab2c
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,203 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import os
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'])
+        self.backup_file = backup_utils.run_backup_job(
+            self.tester,
+            job_id,
+            self.backup_options['expected_params'],
+            self.assertIn,
+            self.assertNotIn
+        )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt > 1:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEquals(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        assert 'execution_time' in process_list[0]
+        assert 'stime' in process_list[0]
+        assert 'exit_code' in process_list[0]
+        assert process_list[0]['exit_code'] in self.expected_exit_code
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEquals(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 10:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEquals(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEquals(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEquals(restore_ack_res['success'], 1)
+
+        if self.backup_file is not None:
+            if os.path.isfile(self.backup_file):
+                os.remove(self.backup_file)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..2829cd8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        assert restore_message_mock.called
+        assert batch_process_mock.called
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..bb45286
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        assert restore_obj.message == self.extected_msg
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..26b25c7 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-12 10:24                                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 10:44                                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-12 15:36                                                 ` Victoria Henry <[email protected]>
  2018-06-13 12:12                                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Victoria Henry @ 2018-06-12 15:36 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

--000000000000641b04056e73a2db
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Khushboo
can you explain a little bit more this while loop?


cnt =3D 0
while 1:
    if cnt > 1:
        break
    # Check the process list
    response1 =3D self.tester.get('/misc/bgprocess/?_=3D'.format(
        random.randint(1, 9999999)))
    self.assertEquals(response1.status_code, 200)
    process_list =3D json.loads(response1.data.decode('utf-8'))

    if len(process_list) > 0 and 'execution_time' in process_list[0]:
        break
    time.sleep(0.5)
    cnt +=3D 1



^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-12 10:24                                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 10:44                                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 15:36                                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
@ 2018-06-13 12:12                                                   ` Khushboo Vashi <[email protected]>
  2018-06-15 07:13                                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-13 12:12 UTC (permalink / raw)
  To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi Victoria,


On Tue, Jun 12, 2018 at 9:06 PM, Victoria Henry <[email protected]> wrote:

> Hi Khushboo
> can you explain a little bit more this while loop?
>
>
> cnt = 0
> while 1:
>     if cnt > 1:
>         break
>     # Check the process list
>     response1 = self.tester.get('/misc/bgprocess/?_='.format(
>         random.randint(1, 9999999)))
>     self.assertEquals(response1.status_code, 200)
>     process_list = json.loads(response1.data.decode('utf-8'))
>
>     if len(process_list) > 0 and 'execution_time' in process_list[0]:
>         break
>     time.sleep(0.5)
>     cnt += 1
>
> From what it looks like this will only run twice, maybe a for would be a
> better solution because we know it will only run twice. Also are we sure we
> only want it to run twice?
>
> The code waits till the background process completes. So, while I
originally developed, not intended to run only twice.
But after that I put a kind of break point and that remains there. So, I
will remove that if condition which is not required.

> We are using PyCharm to do our developments and we notice there are a big
> group of unused variables throughout. We should remove them if they are not
> needed. Not sure if your editor also shows that information or not.
>
Do you know if there is a configuration in pycodestyle to enable the check
> for unused variables? That would help a lot.
>
> Thanks for sharing the information.

> The code
>
> assert 'execution_time' in process_list[0]
> assert 'stime' in process_list[0]
> assert 'exit_code' in process_list[0]
> assert process_list[0]['exit_code'] in self.expected_exit_code
>
> in test_Create_restore_job should use self.assertEqual or similar from
> unittest instead of plain assert. Because when something fails we do not
> have a way to understand what was wrong.
>
Will do.

> The tests on the restore are still failing GreenPlum.
>
It is failing because, Restore is not working with GreenPlum. Can you
please look into the Restore functionality for GPDB?


Thanks,
Khushboo

> ​
>
>
>
> Thanks
> Victoria & Joao
>
> On Tue, Jun 12, 2018 at 6:44 AM Khushboo Vashi <
> [email protected]> wrote:
>
>> Please find the attached updated patch with some code cleanup.
>>
>> On Tue, Jun 12, 2018 at 3:54 PM, Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Hi,
>>>
>>> Please find the attached patch excluding feature test cases.
>>> Python test cases are working fine, so we can commit this patch. I am
>>> working on fixing the feature tests which are failing on the different
>>> window sizes.
>>>
>>> Thanks,
>>> Khushboo
>>>
>>> On Fri, Jun 8, 2018 at 2:38 PM, Dave Page <[email protected]> wrote:
>>>
>>>> Hi
>>>>
>>>> On Fri, Jun 8, 2018 at 6:33 AM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Dave,
>>>>>
>>>>> As per our discussion I have changed the window size to 1280X800,
>>>>> before it was 1280X900.
>>>>> Please find the attached updated patch
>>>>>
>>>>
>>>> I'm not sure that actually made any difference on my system. The window
>>>> continued to look taller than it is wide, so I wonder if the code to set
>>>> the size is being ignored, or is at the wrong place?
>>>>
>>>> Anyway, I got 10 failures with this patch :-(
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.feature_tests.pg_utilities_backup_restore_test.
>>>> PGUtilitiesBackupFeatureTest)
>>>>
>>>> Test for PG utilities - Backup and Restore
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_
>>>> utilities_backup_restore_test.py", line 97, in runTest
>>>>
>>>>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 171, in find_by_xpath
>>>>
>>>>     lambda driver: driver.find_element_by_xpath(xpath)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 263, in wait_for_element
>>>>
>>>>     return self._wait_for("element to exist", element_if_it_exists)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 337, in _wait_for
>>>>
>>>>     "Timed out waiting for " + waiting_for_message
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/support/wait.py", line 80, in until
>>>>
>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>
>>>> TimeoutException: Message: Timed out waiting for element to exist
>>>>
>>>>
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.feature_tests.xss_checks_pgadmin_debugger_test.
>>>> CheckDebuggerForXssFeatureTest)
>>>>
>>>> Tests to check if Debugger is vulnerable to XSS
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_
>>>> checks_pgadmin_debugger_test.py", line 42, in runTest
>>>>
>>>>     self._function_node_expandable()
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_
>>>> checks_pgadmin_debugger_test.py", line 57, in _function_node_expandable
>>>>
>>>>     self.page.select_tree_item("a_test_function()")
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 135, in select_tree_item
>>>>
>>>>     "' and @class='aciTreeItem']").click()
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 171, in find_by_xpath
>>>>
>>>>     lambda driver: driver.find_element_by_xpath(xpath)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 263, in wait_for_element
>>>>
>>>>     return self._wait_for("element to exist", element_if_it_exists)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>> line 337, in _wait_for
>>>>
>>>>     "Timed out waiting for " + waiting_for_message
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-
>>>> packages/selenium/webdriver/support/wait.py", line 80, in until
>>>>
>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>
>>>> TimeoutException: Message: Timed out waiting for element to exist
>>>>
>>>>
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.tools.backup.tests.test_create_backup_job.
>>>> BackupJobTest)
>>>>
>>>> When backup the object with the default options
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/
>>>> tests/test_create_backup_job.py", line 58, in runTest
>>>>
>>>>     self.assertNotIn
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>>>> line 33, in run_backup_job
>>>>
>>>>     random.randint(1, 9999999)))
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 830, in get
>>>>
>>>>     return self.open(*args, **kw)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>> line 127, in open
>>>>
>>>>     follow_redirects=follow_redirects)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 803, in open
>>>>
>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 716, in run_wsgi_app
>>>>
>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 923, in run_wsgi_app
>>>>
>>>>     app_rv = app(environ, start_response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1997, in __call__
>>>>
>>>>     return self.wsgi_app(environ, start_response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1985, in wsgi_app
>>>>
>>>>     response = self.handle_exception(e)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1540, in handle_exception
>>>>
>>>>     reraise(exc_type, exc_value, tb)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1982, in wsgi_app
>>>>
>>>>     response = self.full_dispatch_request()
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1614, in full_dispatch_request
>>>>
>>>>     rv = self.handle_user_exception(e)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1517, in handle_user_exception
>>>>
>>>>     reraise(exc_type, exc_value, tb)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1612, in full_dispatch_request
>>>>
>>>>     rv = self.dispatch_request()
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1598, in dispatch_request
>>>>
>>>>     return self.view_functions[rule.endpoint](**req.view_args)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>>> line 792, in decorated_view
>>>>
>>>>     return func(*args, **kwargs)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>>> line 62, in index
>>>>
>>>>     return make_response(response=BatchProcess.list())
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>>> line 584, in list
>>>>
>>>>     details = desc.details(p.command, args)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>> line 159, in details
>>>>
>>>>     name, host, port = self.get_server_details()
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>> line 122, in get_server_details
>>>>
>>>>     host = manager.local_bind_host if manager.use_ssh_tunnel else
>>>> s.host
>>>>
>>>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>>>
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.tools.maintenance.
>>>> tests.test_create_maintenance_job.MaintenanceJobTest)
>>>>
>>>> When maintenance the object with the default options
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/
>>>> tests/test_create_maintenance_job.py", line 71, in runTest
>>>>
>>>>     random.randint(1, 9999999)))
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 830, in get
>>>>
>>>>     return self.open(*args, **kw)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>> line 127, in open
>>>>
>>>>     follow_redirects=follow_redirects)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 803, in open
>>>>
>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 716, in run_wsgi_app
>>>>
>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 923, in run_wsgi_app
>>>>
>>>>     app_rv = app(environ, start_response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1997, in __call__
>>>>
>>>>     return self.wsgi_app(environ, start_response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1985, in wsgi_app
>>>>
>>>>     response = self.handle_exception(e)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1540, in handle_exception
>>>>
>>>>     reraise(exc_type, exc_value, tb)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1982, in wsgi_app
>>>>
>>>>     response = self.full_dispatch_request()
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1614, in full_dispatch_request
>>>>
>>>>     rv = self.handle_user_exception(e)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1517, in handle_user_exception
>>>>
>>>>     reraise(exc_type, exc_value, tb)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1612, in full_dispatch_request
>>>>
>>>>     rv = self.dispatch_request()
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1598, in dispatch_request
>>>>
>>>>     return self.view_functions[rule.endpoint](**req.view_args)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>>> line 792, in decorated_view
>>>>
>>>>     return func(*args, **kwargs)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>>> line 62, in index
>>>>
>>>>     return make_response(response=BatchProcess.list())
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>>> line 584, in list
>>>>
>>>>     details = desc.details(p.command, args)
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>> line 159, in details
>>>>
>>>>     name, host, port = self.get_server_details()
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>> line 122, in get_server_details
>>>>
>>>>     host = manager.local_bind_host if manager.use_ssh_tunnel else
>>>> s.host
>>>>
>>>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>>>
>>>>
>>>> ======================================================================
>>>>
>>>> ERROR: runTest (pgadmin.tools.restore.tests.test_create_restore_job.
>>>> RestoreJobTest)
>>>>
>>>> When restore the object with the default options
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Traceback (most recent call last):
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/
>>>> tests/test_create_restore_job.py", line 95, in runTest
>>>>
>>>>     self.create_backup()
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/
>>>> tests/test_create_restore_job.py", line 86, in create_backup
>>>>
>>>>     self.assertNotIn
>>>>
>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>>>> line 33, in run_backup_job
>>>>
>>>>     random.randint(1, 9999999)))
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 830, in get
>>>>
>>>>     return self.open(*args, **kw)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>> line 127, in open
>>>>
>>>>     follow_redirects=follow_redirects)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 803, in open
>>>>
>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 716, in run_wsgi_app
>>>>
>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>> line 923, in run_wsgi_app
>>>>
>>>>     app_rv = app(environ, start_response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1997, in __call__
>>>>
>>>>     return self.wsgi_app(environ, start_response)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1985, in wsgi_app
>>>>
>>>>     response = self.handle_exception(e)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1540, in handle_exception
>>>>
>>>>     reraise(exc_type, exc_value, tb)
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1982, in wsgi_app
>>>>
>>>>     response = self.full_dispatch_request()
>>>>
>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>> line 1614, in full_dispatch_request
>>>>
>>>>     rv = self.handle_user_exception(e)
>>>>
>>>>


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-12 10:24                                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 10:44                                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 15:36                                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-13 12:12                                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-15 07:13                                                     ` Khushboo Vashi <[email protected]>
  2018-06-15 10:37                                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  0 siblings, 1 reply; 29+ messages in thread

From: Khushboo Vashi @ 2018-06-15 07:13 UTC (permalink / raw)
  To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Hi,

Please find the attached updated patch.

On Wed, Jun 13, 2018 at 5:42 PM, Khushboo Vashi <
[email protected]> wrote:

> Hi Victoria,
>
>
> On Tue, Jun 12, 2018 at 9:06 PM, Victoria Henry <[email protected]> wrote:
>
>> Hi Khushboo
>> can you explain a little bit more this while loop?
>>
>>
>> cnt = 0
>> while 1:
>>     if cnt > 1:
>>         break
>>     # Check the process list
>>     response1 = self.tester.get('/misc/bgprocess/?_='.format(
>>         random.randint(1, 9999999)))
>>     self.assertEquals(response1.status_code, 200)
>>     process_list = json.loads(response1.data.decode('utf-8'))
>>
>>     if len(process_list) > 0 and 'execution_time' in process_list[0]:
>>         break
>>     time.sleep(0.5)
>>     cnt += 1
>>
>> From what it looks like this will only run twice, maybe a for would be a
>> better solution because we know it will only run twice. Also are we sure we
>> only want it to run twice?
>>
>> The code waits till the background process completes. So, while I
> originally developed, not intended to run only twice.
> But after that I put a kind of break point and that remains there. So, I
> will remove that if condition which is not required.
>
I have made maximum 5 attempts.

> We are using PyCharm to do our developments and we notice there are a big
>> group of unused variables throughout. We should remove them if they are not
>> needed. Not sure if your editor also shows that information or not.
>>
> Do you know if there is a configuration in pycodestyle to enable the check
>> for unused variables? That would help a lot.
>>
>> Removed unused local variables.

> Thanks for sharing the information.
>
>> The code
>>
>> assert 'execution_time' in process_list[0]
>> assert 'stime' in process_list[0]
>> assert 'exit_code' in process_list[0]
>> assert process_list[0]['exit_code'] in self.expected_exit_code
>>
>> in test_Create_restore_job should use self.assertEqual or similar from
>> unittest instead of plain assert. Because when something fails we do not
>> have a way to understand what was wrong.
>>
> Will do.
>
Done

> The tests on the restore are still failing GreenPlum.
>>
> It is failing because, Restore is not working with GreenPlum. Can you
> please look into the Restore functionality for GPDB?
>
>
> Thanks,
> Khushboo
>
>> ​
>>
>>
>> Thanks,
Khushboo

>
>> Thanks
>> Victoria & Joao
>>
>> On Tue, Jun 12, 2018 at 6:44 AM Khushboo Vashi <
>> [email protected]> wrote:
>>
>>> Please find the attached updated patch with some code cleanup.
>>>
>>> On Tue, Jun 12, 2018 at 3:54 PM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>>
>>>> Please find the attached patch excluding feature test cases.
>>>> Python test cases are working fine, so we can commit this patch. I am
>>>> working on fixing the feature tests which are failing on the different
>>>> window sizes.
>>>>
>>>> Thanks,
>>>> Khushboo
>>>>
>>>> On Fri, Jun 8, 2018 at 2:38 PM, Dave Page <[email protected]> wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> On Fri, Jun 8, 2018 at 6:33 AM, Khushboo Vashi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Dave,
>>>>>>
>>>>>> As per our discussion I have changed the window size to 1280X800,
>>>>>> before it was 1280X900.
>>>>>> Please find the attached updated patch
>>>>>>
>>>>>
>>>>> I'm not sure that actually made any difference on my system. The
>>>>> window continued to look taller than it is wide, so I wonder if the code to
>>>>> set the size is being ignored, or is at the wrong place?
>>>>>
>>>>> Anyway, I got 10 failures with this patch :-(
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>
>>>>> Test for PG utilities - Backup and Restore
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>> line 97, in runTest
>>>>>
>>>>>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 171, in find_by_xpath
>>>>>
>>>>>     lambda driver: driver.find_element_by_xpath(xpath)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 263, in wait_for_element
>>>>>
>>>>>     return self._wait_for("element to exist", element_if_it_exists)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 337, in _wait_for
>>>>>
>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>
>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>
>>>>> TimeoutException: Message: Timed out waiting for element to exist
>>>>>
>>>>>
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.feature_tests.xss_che
>>>>> cks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)
>>>>>
>>>>> Tests to check if Debugger is vulnerable to XSS
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>>>>> line 42, in runTest
>>>>>
>>>>>     self._function_node_expandable()
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>>>>> line 57, in _function_node_expandable
>>>>>
>>>>>     self.page.select_tree_item("a_test_function()")
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 135, in select_tree_item
>>>>>
>>>>>     "' and @class='aciTreeItem']").click()
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 171, in find_by_xpath
>>>>>
>>>>>     lambda driver: driver.find_element_by_xpath(xpath)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 263, in wait_for_element
>>>>>
>>>>>     return self._wait_for("element to exist", element_if_it_exists)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>> line 337, in _wait_for
>>>>>
>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>
>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>
>>>>> TimeoutException: Message: Timed out waiting for element to exist
>>>>>
>>>>>
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.tools.backup.tests.te
>>>>> st_create_backup_job.BackupJobTest)
>>>>>
>>>>> When backup the object with the default options
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_create_backup_job.py",
>>>>> line 58, in runTest
>>>>>
>>>>>     self.assertNotIn
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>>>>> line 33, in run_backup_job
>>>>>
>>>>>     random.randint(1, 9999999)))
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 830, in get
>>>>>
>>>>>     return self.open(*args, **kw)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>>> line 127, in open
>>>>>
>>>>>     follow_redirects=follow_redirects)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 803, in open
>>>>>
>>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 716, in run_wsgi_app
>>>>>
>>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 923, in run_wsgi_app
>>>>>
>>>>>     app_rv = app(environ, start_response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1997, in __call__
>>>>>
>>>>>     return self.wsgi_app(environ, start_response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1985, in wsgi_app
>>>>>
>>>>>     response = self.handle_exception(e)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1540, in handle_exception
>>>>>
>>>>>     reraise(exc_type, exc_value, tb)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1982, in wsgi_app
>>>>>
>>>>>     response = self.full_dispatch_request()
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1614, in full_dispatch_request
>>>>>
>>>>>     rv = self.handle_user_exception(e)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1517, in handle_user_exception
>>>>>
>>>>>     reraise(exc_type, exc_value, tb)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1612, in full_dispatch_request
>>>>>
>>>>>     rv = self.dispatch_request()
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1598, in dispatch_request
>>>>>
>>>>>     return self.view_functions[rule.endpoint](**req.view_args)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>>>> line 792, in decorated_view
>>>>>
>>>>>     return func(*args, **kwargs)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>>>> line 62, in index
>>>>>
>>>>>     return make_response(response=BatchProcess.list())
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>>>> line 584, in list
>>>>>
>>>>>     details = desc.details(p.command, args)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>> line 159, in details
>>>>>
>>>>>     name, host, port = self.get_server_details()
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>> line 122, in get_server_details
>>>>>
>>>>>     host = manager.local_bind_host if manager.use_ssh_tunnel else
>>>>> s.host
>>>>>
>>>>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>>>>
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.tools.maintenance.tes
>>>>> ts.test_create_maintenance_job.MaintenanceJobTest)
>>>>>
>>>>> When maintenance the object with the default options
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/tes
>>>>> ts/test_create_maintenance_job.py", line 71, in runTest
>>>>>
>>>>>     random.randint(1, 9999999)))
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 830, in get
>>>>>
>>>>>     return self.open(*args, **kw)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>>> line 127, in open
>>>>>
>>>>>     follow_redirects=follow_redirects)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 803, in open
>>>>>
>>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 716, in run_wsgi_app
>>>>>
>>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 923, in run_wsgi_app
>>>>>
>>>>>     app_rv = app(environ, start_response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1997, in __call__
>>>>>
>>>>>     return self.wsgi_app(environ, start_response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1985, in wsgi_app
>>>>>
>>>>>     response = self.handle_exception(e)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1540, in handle_exception
>>>>>
>>>>>     reraise(exc_type, exc_value, tb)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1982, in wsgi_app
>>>>>
>>>>>     response = self.full_dispatch_request()
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1614, in full_dispatch_request
>>>>>
>>>>>     rv = self.handle_user_exception(e)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1517, in handle_user_exception
>>>>>
>>>>>     reraise(exc_type, exc_value, tb)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1612, in full_dispatch_request
>>>>>
>>>>>     rv = self.dispatch_request()
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1598, in dispatch_request
>>>>>
>>>>>     return self.view_functions[rule.endpoint](**req.view_args)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>>>> line 792, in decorated_view
>>>>>
>>>>>     return func(*args, **kwargs)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>>>> line 62, in index
>>>>>
>>>>>     return make_response(response=BatchProcess.list())
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>>>> line 584, in list
>>>>>
>>>>>     details = desc.details(p.command, args)
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>> line 159, in details
>>>>>
>>>>>     name, host, port = self.get_server_details()
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>> line 122, in get_server_details
>>>>>
>>>>>     host = manager.local_bind_host if manager.use_ssh_tunnel else
>>>>> s.host
>>>>>
>>>>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>>>>
>>>>>
>>>>> ======================================================================
>>>>>
>>>>> ERROR: runTest (pgadmin.tools.restore.tests.t
>>>>> est_create_restore_job.RestoreJobTest)
>>>>>
>>>>> When restore the object with the default options
>>>>>
>>>>> ----------------------------------------------------------------------
>>>>>
>>>>> Traceback (most recent call last):
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
>>>>> line 95, in runTest
>>>>>
>>>>>     self.create_backup()
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
>>>>> line 86, in create_backup
>>>>>
>>>>>     self.assertNotIn
>>>>>
>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>>>>> line 33, in run_backup_job
>>>>>
>>>>>     random.randint(1, 9999999)))
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 830, in get
>>>>>
>>>>>     return self.open(*args, **kw)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>>> line 127, in open
>>>>>
>>>>>     follow_redirects=follow_redirects)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 803, in open
>>>>>
>>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 716, in run_wsgi_app
>>>>>
>>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>> line 923, in run_wsgi_app
>>>>>
>>>>>     app_rv = app(environ, start_response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1997, in __call__
>>>>>
>>>>>     return self.wsgi_app(environ, start_response)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1985, in wsgi_app
>>>>>
>>>>>     response = self.handle_exception(e)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1540, in handle_exception
>>>>>
>>>>>     reraise(exc_type, exc_value, tb)
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1982, in wsgi_app
>>>>>
>>>>>     response = self.full_dispatch_request()
>>>>>
>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>> line 1614, in full_dispatch_request
>>>>>
>>>>>     rv = self.handle_user_exception(e)
>>>>>
>>>>>
>


Attachments:

  [application/octet-stream] RM_3206_exclude_feature_tests_ver1.patch (97.7K, 3-RM_3206_exclude_feature_tests_ver1.patch)
  download | inline diff:
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 125db80..0513365 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -109,8 +109,7 @@ class BackupMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -123,13 +122,19 @@ class BackupMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         if self.backup_type == BACKUP.OBJECT:
             return _(
                 "Backing up an object on the server '{0}' "
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 ),
                 self.database
             )
@@ -137,13 +142,13 @@ class BackupMessage(IProcessDesc):
             return _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         elif self.backup_type == BACKUP.SERVER:
             return _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    s.name, host, port
+                    name, host, port
                 )
             )
         else:
@@ -151,17 +156,7 @@ class BackupMessage(IProcessDesc):
             return "Unknown Backup"
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
+        name, host, port = self.get_server_details()
 
         res = '<div class="h5">'
 
@@ -171,7 +166,7 @@ class BackupMessage(IProcessDesc):
                 "from database '{1}'..."
             ).format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port),
                 ),
@@ -181,7 +176,7 @@ class BackupMessage(IProcessDesc):
             res += _("Backing up the global objects on "
                      "the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
@@ -189,7 +184,7 @@ class BackupMessage(IProcessDesc):
         elif self.backup_type == BACKUP.SERVER:
             res += _("Backing up the server '{0}'...").format(
                 "{0} ({1}:{2})".format(
-                    html.safe_str(s.name),
+                    html.safe_str(name),
                     html.safe_str(host),
                     html.safe_str(port)
                 )
diff --git a/web/pgadmin/tools/backup/tests/__init__.py b/web/pgadmin/tools/backup/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
new file mode 100644
index 0000000..5b1d21f
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py
@@ -0,0 +1,457 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.backup import BackupMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When backup object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option sections to all data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=c',
+                                '--section=pre-data', '--section=data',
+                                '--section=post-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=False
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--data-only'],
+             not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option only_schema',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=False,
+                 only_schema=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--schema-only'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - format plain and dns_owner',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--format=p', '--no-owner'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - Do not save privilege,'
+         ' tablespace, unlogged table data',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_privilege=True,
+                 dns_unlogged_tbl_data=True,
+                 dns_tablespace=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--no-privileges',
+                                '--no-tablespaces',
+                                '--no-unlogged-table-data'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='plain',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--create', '--clean', '--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - all queries and format custom',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_column_inserts=True,
+                 include_create_database=True,
+                 use_insert_commands=True,
+                 include_drop_database=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--inserts',
+                                '--column-inserts'],
+             not_expected_cmd_opts=['--create', '--clean'],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with option - miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_quoting=True,
+                 use_set_session_auth=True,
+                 with_oids=True,
+                 dqoute=True
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose', '--quote-all-identifiers',
+                                '--disable-dollar-quoting', '--oids',
+                                '--use-set-session-authorization'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the object with format tar',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='tar',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 blobs=True,
+             ),
+             url='/backup/job/{0}/object',
+             expected_cmd_opts=['--verbose',
+                                '--blobs',
+                                '--format=t'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_server_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='server'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_global_file',
+                 dqoute=False,
+                 verbose=True,
+                 type='globals'
+             ),
+             url='/backup/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.backup.Server')
+    @patch('pgadmin.tools.backup.BackupMessage')
+    @patch('pgadmin.tools.backup.filename_with_file_manager_path')
+    @patch('pgadmin.tools.backup.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, backup_message_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username,
+                         maintenance_db):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+                self.maintenance_db = maintenance_db
+
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username'],
+                                  self.class_params['database']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEqual(response.status_code, 200)
+
+        self.assertTrue(backup_message_mock.called)
+        self.assertTrue(batch_process_mock.called)
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py
new file mode 100644
index 0000000..91305a6
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_message.py
@@ -0,0 +1,149 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class BackupMessageTest(BaseTestGenerator):
+    """Test the BackupMessage class"""
+    scenarios = [
+        ('When Backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the server"
+                          " 'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file '
+                                  '"backup_file" --host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When Backup global',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up the global objects on the server "
+                          "'test_backup_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     'backup_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_dump"
+             ),
+             extected_msg="Backing up an object on the server "
+                          "'test_backup_server (localhost:5444)'"
+                          " from database 'postgres'...",
+             expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
+                                  '--host "localhost" '
+                                  '--port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        # Check the expected message returned
+        self.assertEqual(backup_obj.message, self.extected_msg)
+
+        # Check the command
+        obj_details = backup_obj.details(self.class_params['cmd'],
+                                         self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/backup/tests/test_backup_utils.py b/web/pgadmin/tools/backup/tests/test_backup_utils.py
new file mode 100644
index 0000000..d078675
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_backup_utils.py
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import time
+import random
+import simplejson as json
+
+
+def create_backup_job(tester, url, params, assert_equal):
+    # Create the backup job
+    response = tester.post(url,
+                           data=json.dumps(params),
+                           content_type='html/json')
+    assert_equal(response.status_code, 200)
+    response_data = json.loads(response.data.decode('utf-8'))
+    job_id = response_data['data']['job_id']
+    return job_id
+
+
+def run_backup_job(tester, job_id, expected_params, assert_in, assert_not_in,
+                   assert_equal):
+    cnt = 0
+    while 1:
+        if cnt >= 5:
+            break
+        # Check the process list
+        response1 = tester.get('/misc/bgprocess/?_='.format(
+            random.randint(1, 9999999)))
+        assert_equal(response1.status_code, 200)
+        process_list = json.loads(response1.data.decode('utf-8'))
+
+        if len(process_list) > 0 and 'execution_time' in process_list[0]:
+            break
+        time.sleep(0.5)
+        cnt += 1
+
+    assert_equal('execution_time' in process_list[0], True)
+    assert_equal('stime' in process_list[0], True)
+    assert_equal('exit_code' in process_list[0], True)
+    assert_equal(process_list[0]['exit_code'] in expected_params[
+        'expected_exit_code'
+    ], True)
+
+    backup_file = None
+    if 'details' in process_list[0]:
+        backup_det = process_list[0]['details']
+        backup_file = backup_det[int(backup_det.find('--file')) +
+                                 8:int(backup_det.find('--host')) - 2]
+
+    if expected_params['expected_cmd_opts']:
+        for opt in expected_params['expected_cmd_opts']:
+            assert_in(opt, process_list[0]['details'])
+    if expected_params['not_expected_cmd_opts']:
+        for opt in expected_params['not_expected_cmd_opts']:
+            assert_not_in(opt, process_list[0]['details'])
+
+    # Check the process details
+    p_details = tester.get('/misc/bgprocess/{0}?_='.format(
+        job_id, random.randint(1, 9999999))
+    )
+    assert_equal(p_details.status_code, 200)
+
+    p_details = tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+        job_id, 0, 0, random.randint(1, 9999999))
+    )
+    assert_equal(p_details.status_code, 200)
+    p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+    cnt = 0
+    # Retrieve the backup job process logs
+    while 1:
+        out, err, status = get_params(p_details_data)
+        if status or cnt >= 5:
+            break
+
+        p_details = tester.get(
+            '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                job_id, out, err, random.randint(1, 9999999))
+        )
+        assert_equal(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        cnt += 1
+        time.sleep(1)
+
+    # Check the job is complete.
+    backup_ack = tester.put('/misc/bgprocess/{0}'.format(job_id))
+    assert_equal(backup_ack.status_code, 200)
+    backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+    assert_equal(backup_ack_res['success'], 1)
+
+    return backup_file
+
+
+def get_params(data):
+    out = 0
+    out_done = False
+    err = 0
+    err_done = False
+    if 'out' in data:
+        out = data['out'] and data['out']['pos']
+
+        if 'done' in data['out']:
+            out_done = data['out']['done']
+
+    if 'err' in data:
+        err = data['err'] and data['err']['pos']
+
+        if 'done' in data['err']:
+            err_done = data['err']['done']
+
+    return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py
new file mode 100644
index 0000000..ce8a666
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_batch_process.py
@@ -0,0 +1,213 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import simplejson as json
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.backup import BackupMessage, BACKUP
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When backup server',
+         dict(
+             class_params=dict(
+                 type=BACKUP.SERVER,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup_server'
+             )
+         )),
+        ('When backup globals',
+         dict(
+             class_params=dict(
+                 type=BACKUP.GLOBALS,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         )),
+        ('When backup object',
+         dict(
+             class_params=dict(
+                 type=BACKUP.OBJECT,
+                 sid=1,
+                 name='test_backup_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_backup',
+                 args=[
+                     '--file',
+                     "backup_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='backup'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.backup.BackupMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.backup.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            self.assertTrue(isinstance(cmd_obj, IProcessDesc))
+            self.assertEqual(cmd_obj.backup_type, self.class_params['type'])
+            self.assertEqual(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEqual(cmd_obj.database, self.class_params['database'])
+            self.assertEqual(cmd_obj.cmd,
+                             ' --file "backup_file" '
+                             '--host "{0}" '
+                             '--port "{1}" '
+                             '--username "{2}" '
+                             '--no-password '
+                             '--database "{3}"'.format(
+                                 self.class_params['host'],
+                                 self.class_params['port'],
+                                 self.class_params['username'],
+                                 self.class_params['database']
+                             ))
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        backup_obj = BackupMessage(
+            self.class_params['type'],
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args'],
+            **{'database': self.class_params['database']}
+        )
+
+        p = BatchProcess(
+            desc=backup_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        self.assertTrue(db_mock.session.add.called)
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, backup_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+        assert_true = self.assertTrue
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert_true(cmd_test in cmd)
+                assert_true('env' in kwargs)
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        self.assertTrue(popen_mock.called)
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, backup_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(backup_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        self.assertTrue('details' in ret_value[0])
+        self.assertTrue('desc' in ret_value[0])
diff --git a/web/pgadmin/tools/backup/tests/test_create_backup_job.py b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
new file mode 100644
index 0000000..b495672
--- /dev/null
+++ b/web/pgadmin/tools/backup/tests/test_create_backup_job.py
@@ -0,0 +1,65 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+class BackupJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When backup the object with the default options',
+         dict(
+             params=dict(
+                 file='test_backup',
+                 format='custom',
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/backup/job/{0}/object',
+             expected_params=dict(
+                 expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                 not_expected_cmd_opts=[],
+                 expected_exit_code=[0, None]
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        url = self.url.format(self.server_id)
+
+        # Create the backup job
+        job_id = backup_utils.create_backup_job(self.tester, url, self.params,
+                                                self.assertEqual)
+        backup_file = backup_utils.run_backup_job(self.tester,
+                                                  job_id,
+                                                  self.expected_params,
+                                                  self.assertIn,
+                                                  self.assertNotIn,
+                                                  self.assertEqual
+                                                  )
+
+        if backup_file is not None:
+            if os.path.isfile(backup_file):
+                os.remove(backup_file)
diff --git a/web/pgadmin/tools/maintenance/tests/__init__.py b/web/pgadmin/tools/maintenance/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
new file mode 100644
index 0000000..748a456
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When maintained server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 host='localhost',
+                 port=5444,
+                 username='postgres',
+                 args=[
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     '--dbname',
+                     "postgres",
+                     '--command',
+                     "VACUUM VERBOSE;\n"
+                 ],
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             expected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+         ))
+    ]
+
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, server_mock, db_mock,
+                current_app_mock, popen_mock):
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        class TestMockServer():
+            def __init__(self, name, host, port):
+                self.name = name
+                self.host = host
+                self.port = port
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            self.assertTrue(isinstance(cmd_obj, IProcessDesc))
+            self.assertEqual(cmd_obj.query, self.class_params['cmd'])
+            self.assertEqual(cmd_obj.message, self.expected_msg)
+            self.assertEqual(cmd_obj.data, self.class_params['data'])
+
+        mock_obj = TestMockServer(self.class_params['username'],
+                                  self.class_params['host'],
+                                  self.class_params['port'])
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        p = BatchProcess(
+            desc=maintenance_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        self.assertTrue(db_mock.session.add.called)
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, maintenance_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+        assert_true = self.assertTrue
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert_true(cmd_test in cmd)
+                assert_true('env' in kwargs)
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        self.assertTrue(popen_mock.called)
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, maintenance_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(maintenance_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        self.assertTrue('details' in ret_value[0])
+        self.assertTrue('desc' in ret_value[0])
diff --git a/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
new file mode 100644
index 0000000..c76f1d9
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_create_maintenance_job.py
@@ -0,0 +1,139 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import time
+import random
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+class MaintenanceJobTest(BaseTestGenerator):
+    """Maintenance api test cases"""
+    scenarios = [
+        ('When maintenance the object with the default options',
+         dict(
+             params=dict(
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd='VACUUM VERBOSE',
+             expected_exit_code=[0, None]
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def runTest(self):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params['data']),
+                                    content_type='html/json')
+        self.assertEqual(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt >= 10:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEqual(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        self.assertTrue('execution_time' in process_list[0])
+        self.assertTrue('stime' in process_list[0])
+        self.assertTrue('exit_code' in process_list[0])
+        self.assertTrue(process_list[0]['exit_code'] in
+                        self.expected_exit_code)
+
+        self.assertIn(self.expected_cmd, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEqual(p_details.status_code, 200)
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEqual(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the backup job process logs
+        while 1:
+            out, err, status = MaintenanceJobTest.get_params(p_details_data)
+            if status:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEqual(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            time.sleep(1)
+
+        # Check the job is complete.
+        backup_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEqual(backup_ack.status_code, 200)
+        backup_ack_res = json.loads(backup_ack.data.decode('utf-8'))
+
+        self.assertEqual(backup_ack_res['success'], 1)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
new file mode 100644
index 0000000..40c1b2c
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_create_job_unit_test.py
@@ -0,0 +1,196 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import simplejson as json
+
+
+from pgadmin.misc.bgprocess.processes import BatchProcess
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class MaintenanceCreateJobTest(BaseTestGenerator):
+    """Test the BackupCreateJob class"""
+    scenarios = [
+        ('When maintenance object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM VERBOSE;\n'],
+         )),
+        ('When maintenance object with VACUUM FULL',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='VACUUM',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=True,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
+         )),
+        ('When maintenance object with the ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='ANALYZE',
+                 vacuum_analyze=True,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=True
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['ANALYZE VERBOSE;\n'],
+         )),
+        ('When maintenance the object with the REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='REINDEX',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
+         )),
+        ('When maintenance the object with the CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_maintenance_server',
+                 port=5444,
+                 host='localhost',
+                 username='postgres'
+             ),
+             params=dict(
+                 database='postgres',
+                 op='CLUSTER',
+                 vacuum_analyze=False,
+                 vacuum_freeze=False,
+                 vacuum_full=False,
+                 verbose=False
+             ),
+             url='/maintenance/job/{0}/{1}',
+             expected_cmd_opts=['CLUSTER;\n'],
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.maintenance.Server')
+    @patch('pgadmin.tools.maintenance.Message')
+    @patch('pgadmin.tools.maintenance.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock,
+                batch_process_mock, message_mock, server_mock):
+        self.server_id = parent_node_dict["database"][-1]["server_id"]
+        self.db_id = parent_node_dict["database"][-1]["db_id"]
+        url = self.url.format(self.server_id, self.db_id)
+
+        class TestMockServer():
+            def __init__(self, host, port, id, username):
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        mock_obj = TestMockServer(self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        # Create the backup job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEqual(response.status_code, 200)
+
+        self.assertTrue(message_mock.called)
+        self.assertTrue(batch_process_mock.called)
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt,
+                              batch_process_mock.call_args_list[0][1]['args'])
diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
new file mode 100644
index 0000000..8b30752
--- /dev/null
+++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py
@@ -0,0 +1,124 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.maintenance import Message
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class MaintenanceMessageTest(BaseTestGenerator):
+    """Test the Maintenance Message class"""
+    scenarios = [
+        ('When maintained the server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="VACUUM VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM VERBOSE;'
+
+         )),
+        ('When maintained the server with FULL VERBOSE options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'VACUUM',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': True,
+                     'verbose': True
+                 },
+                 cmd="VACUUM FULL VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Vacuum)",
+             expetced_details_cmd='VACUUM FULL VERBOSE;'
+
+         )),
+        ('When maintained the server with ANALYZE',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'ANALYZE',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="ANALYZE VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Analyze)",
+             expetced_details_cmd='ANALYZE VERBOSE;'
+
+         )),
+        ('When maintained the server with REINDEX',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'REINDEX',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': False
+                 },
+                 cmd="REINDEX;\n"
+             ),
+             extected_msg="Maintenance (Reindex)",
+             expetced_details_cmd='REINDEX;'
+
+         )),
+        ('When maintained the server with CLUSTER',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 data={
+                     'database': 'postgres',
+                     'op': 'CLUSTER',
+                     'vacuum_analyze': False,
+                     'vacuum_freeze': False,
+                     'vacuum_full': False,
+                     'verbose': True
+                 },
+                 cmd="CLUSTER VERBOSE;\n"
+             ),
+             extected_msg="Maintenance (Cluster)",
+             expetced_details_cmd='CLUSTER VERBOSE;'
+
+         )),
+    ]
+
+    def runTest(self):
+        maintenance_obj = Message(
+            self.class_params['sid'],
+            self.class_params['data'],
+            self.class_params['cmd']
+        )
+
+        # Check the expected message returned
+        self.assertEqual(maintenance_obj.message, self.extected_msg)
+
+        # Check the command
+        obj_details = maintenance_obj.details(self.class_params['cmd'], None)
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 45d3816..58bc251 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -86,8 +86,7 @@ class RestoreMessage(IProcessDesc):
             else:
                 self.cmd += cmdArg(arg)
 
-    @property
-    def message(self):
+    def get_server_details(self):
         # Fetch the server details like hostname, port, roles etc
         s = Server.query.filter_by(
             id=self.sid, user_id=current_user.id
@@ -100,30 +99,25 @@ class RestoreMessage(IProcessDesc):
         host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
         port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
 
+        return s.name, host, port
+
+    @property
+    def message(self):
+        name, host, port = self.get_server_details()
+
         return _("Restoring backup on the server '{0}'...").format(
-            "{0} ({1}:{2})".format(s.name, host, port),
+            "{0} ({1}:{2})".format(name, host, port),
         )
 
     def details(self, cmd, args):
-        # Fetch the server details like hostname, port, roles etc
-        s = Server.query.filter_by(
-            id=self.sid, user_id=current_user.id
-        ).first()
-
-        from pgadmin.utils.driver import get_driver
-        driver = get_driver(PG_DEFAULT_DRIVER)
-        manager = driver.connection_manager(self.sid)
-
-        host = manager.local_bind_host if manager.use_ssh_tunnel else s.host
-        port = manager.local_bind_port if manager.use_ssh_tunnel else s.port
-
+        name, host, port = self.get_server_details()
         res = '<div class="h5">'
 
         res += html.safe_str(
             _(
                 "Restoring backup on the server '{0}'..."
             ).format(
-                "{0} ({1}:{2})".format(s.name, host, port)
+                "{0} ({1}:{2})".format(name, host, port)
             )
         )
 
@@ -206,6 +200,7 @@ def create_restore_job(sid):
 
     if _file is None:
         return make_json_response(
+            status=410,
             success=0,
             errormsg=_("File could not be found.")
         )
diff --git a/web/pgadmin/tools/restore/tests/__init__.py b/web/pgadmin/tools/restore/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py
new file mode 100644
index 0000000..1a5030c
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_batch_process.py
@@ -0,0 +1,154 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from pickle import dumps, loads
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class BatchProcessTest(BaseTestGenerator):
+    """Test the BatchProcess class"""
+    scenarios = [
+        ('When restore server',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 username='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     "restore_file",
+                     '--host',
+                     "localhost",
+                     '--port',
+                     "5444",
+                     '--username',
+                     "postgres",
+                     '--no-password',
+                     '--database',
+                     "postgres"
+                 ],
+                 cmd='restore_server'
+             )
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    @patch('pgadmin.misc.bgprocess.processes.Popen')
+    @patch('pgadmin.misc.bgprocess.processes.current_app')
+    @patch('pgadmin.misc.bgprocess.processes.db')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.misc.bgprocess.processes.current_user')
+    def runTest(self, current_user_mock, current_user, db_mock,
+                current_app_mock, popen_mock, get_server_details_mock):
+        current_user.id = 1
+        current_user_mock.id = 1
+        current_app_mock.PGADMIN_RUNTIME = False
+
+        def db_session_add_mock(j):
+            cmd_obj = loads(j.desc)
+            self.assertTrue(isinstance(cmd_obj, IProcessDesc))
+            self.assertEqual(cmd_obj.bfile, self.class_params['bfile'])
+            self.assertEqual(cmd_obj.cmd,
+                             ' --file "restore_file" '
+                             '--host "{0}" '
+                             '--port "{1}" '
+                             '--username "{2}" '
+                             '--no-password '
+                             '--database "{3}"'.format(
+                                 self.class_params['host'],
+                                 self.class_params['port'],
+                                 self.class_params['username'],
+                                 self.class_params['database']
+                             ))
+
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        db_mock.session.add.side_effect = db_session_add_mock
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        p = BatchProcess(
+            desc=restore_obj,
+            cmd=self.class_params['cmd'],
+            args=self.class_params['args']
+        )
+
+        # Check that _create_process has been called
+        self.assertTrue(db_mock.session.add.called)
+
+        # Check start method
+        self._check_start(popen_mock, p)
+
+        # Check list method
+        self._check_list(p, restore_obj)
+
+    def _check_start(self, popen_mock, p):
+        cmd_test = self.class_params['cmd']
+        assert_true = self.assertTrue
+
+        class popenMockSideEffect():
+            def __init__(self, cmd, **kwargs):
+                assert_true(cmd_test in cmd)
+                assert_true('env' in kwargs)
+
+            def poll(self):
+                pass
+
+        popen_mock.side_effect = popenMockSideEffect
+        p.start()
+
+        self.assertTrue(popen_mock.called)
+
+    @patch('pgadmin.misc.bgprocess.processes.Process')
+    @patch('pgadmin.misc.bgprocess.processes.BatchProcess.'
+           'update_process_info')
+    def _check_list(self, p, restore_obj, update_process_info_mock,
+                    process_mock):
+        class TestMockProcess():
+            def __init__(self, desc, args, cmd):
+                self.pid = 1
+                self.exit_code = 1
+                self.start_time = '2018-04-17 06:18:56.315445 +0000'
+                self.end_time = None
+                self.desc = dumps(desc)
+                self.arguments = " ".join(args)
+                self.command = cmd
+                self.acknowledge = None
+
+        process_mock.query.filter_by.return_value = [
+            TestMockProcess(restore_obj,
+                            self.class_params['args'],
+                            self.class_params['cmd'])
+        ]
+
+        update_process_info_mock.return_value = [True, True]
+
+        ret_value = p.list()
+        self.assertEqual(1, len(ret_value))
+        self.assertTrue('details' in ret_value[0])
+        self.assertTrue('desc' in ret_value[0])
diff --git a/web/pgadmin/tools/restore/tests/test_create_restore_job.py b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
new file mode 100644
index 0000000..a809ffc
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_create_restore_job.py
@@ -0,0 +1,206 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+import time
+import random
+import os
+
+import simplejson as json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+import pgadmin.tools.backup.tests.test_backup_utils as backup_utils
+
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreJobTest(BaseTestGenerator):
+    """Backup api test cases"""
+    scenarios = [
+        ('When restore the object with the default options',
+         dict(
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='test_restore_database'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None],
+             backup_options=dict(
+                 params=dict(
+                     file='test_restore_file',
+                     format='custom',
+                     verbose=True,
+                     blobs=True,
+                     schemas=[],
+                     tables=[],
+                     database='test_restore_database'
+                 ),
+                 url='/backup/job/{0}/object',
+                 expected_params=dict(
+                     expected_cmd_opts=['--verbose', '--format=c', '--blobs'],
+                     not_expected_cmd_opts=[],
+                     expected_exit_code=[0, None]
+                 )
+
+             )
+         ))
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    def create_backup(self):
+        url = self.backup_options['url'].format(self.server_id)
+        job_id = backup_utils.create_backup_job(self.tester, url,
+                                                self.backup_options['params'],
+                                                self.assertEqual)
+        self.backup_file = backup_utils.run_backup_job(
+            self.tester,
+            job_id,
+            self.backup_options['expected_params'],
+            self.assertIn,
+            self.assertNotIn,
+            self.assertEqual
+        )
+
+    def runTest(self):
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+        server_response = server_utils.connect_server(self, self.server_id)
+        db_id = utils.create_database(self.server, self.params['database'])
+
+        self.create_backup()
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEqual(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        cnt = 0
+        while 1:
+            if cnt >= 5:
+                break
+            # Check the process list
+            response1 = self.tester.get('/misc/bgprocess/?_='.format(
+                random.randint(1, 9999999)))
+            self.assertEqual(response1.status_code, 200)
+            process_list = json.loads(response1.data.decode('utf-8'))
+
+            if len(process_list) > 0 and 'execution_time' in process_list[0]:
+                break
+            time.sleep(0.5)
+            cnt += 1
+
+        self.assertTrue('execution_time' in process_list[0])
+        self.assertTrue('stime' in process_list[0])
+        self.assertTrue('exit_code' in process_list[0])
+        self.assertTrue(process_list[0]['exit_code'] in
+                        self.expected_exit_code)
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(opt, process_list[0]['details'])
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(opt, process_list[0]['details'])
+
+        # Check the process details
+        p_details = self.tester.get('/misc/bgprocess/{0}?_='.format(
+            job_id, random.randint(1, 9999999))
+        )
+        self.assertEqual(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        p_details = self.tester.get('/misc/bgprocess/{0}/{1}/{2}/?_='.format(
+            job_id, 0, 0, random.randint(1, 9999999))
+        )
+        self.assertEqual(p_details.status_code, 200)
+        p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+        # Retrieve the restore job process logs
+        cnt = 0
+        while 1:
+            out, err, status = RestoreJobTest.get_params(p_details_data)
+            if status or cnt >= 5:
+                break
+
+            p_details = self.tester.get(
+                '/misc/bgprocess/{0}/{1}/{2}/?_={3}'.format(
+                    job_id, out, err, random.randint(1, 9999999))
+            )
+            self.assertEqual(p_details.status_code, 200)
+            p_details_data = json.loads(p_details.data.decode('utf-8'))
+
+            cnt += 1
+            time.sleep(1)
+
+        # Check the job is complete.
+        restore_ack = self.tester.put('/misc/bgprocess/{0}'.format(job_id))
+        self.assertEqual(restore_ack.status_code, 200)
+        restore_ack_res = json.loads(restore_ack.data.decode('utf-8'))
+
+        self.assertEqual(restore_ack_res['success'], 1)
+
+        if self.backup_file is not None:
+            if os.path.isfile(self.backup_file):
+                os.remove(self.backup_file)
+
+    @staticmethod
+    def get_params(data):
+        out = 0
+        out_done = False
+        err = 0
+        err_done = False
+        if 'out' in data:
+            out = data['out'] and data['out']['pos']
+
+            if 'done' in data['out']:
+                out_done = data['out']['done']
+
+        if 'err' in data:
+            err = data['err'] and data['err']['pos']
+
+            if 'done' in data['err']:
+                err_done = data['err']['done']
+
+        return out, err, (out_done and err_done)
+
+    def tearDown(self):
+        connection = utils.get_db_connection(
+            self.server['db'],
+            self.server['username'],
+            self.server['db_password'],
+            self.server['host'],
+            self.server['port'],
+            self.server['sslmode']
+        )
+        utils.drop_database(connection, self.params['database'])
diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
new file mode 100644
index 0000000..b80541f
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py
@@ -0,0 +1,318 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import sys
+import simplejson as json
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from pgadmin.utils import server_utils as server_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class RestoreCreateJobTest(BaseTestGenerator):
+    """Test the RestoreCreateJob class"""
+    scenarios = [
+        ('When restore object with default options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 custom=False,
+                 verbose=True,
+                 blobs=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres'
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with the sections options',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 data=True,
+                 pre_data=True,
+                 post_data=True,
+                 only_data=True,
+                 only_schema=True
+             ),
+             url='/restore/job/{0}',
+             # Please include sections data here, right now this is a bug
+             expected_cmd_opts=['--verbose', '--jobs', '2'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--data-only', '--schema-only'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore the object with Type of objects',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 no_of_jobs='2',
+                 custom=False,
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 only_data=True,
+                 only_schema=True,
+                 dns_owner=True
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--verbose', '--data-only'],
+             not_expected_cmd_opts=[],
+             # Below options should be enabled once we fix the issue #3368
+             # not_expected_cmd_opts=['--schema-only', '--no-owner'],
+             expected_exit_code=[0, None],
+         )),
+        ('When restore object with option - Do not save',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_restore_file',
+                 format='custom',
+                 verbose=True,
+                 custom=False,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 dns_owner=True,
+                 dns_privilege=True,
+                 dns_tablespace=True,
+                 only_data=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-privileges' to the expected_cmd once #3363 fixed
+             expected_cmd_opts=['--no-owner',
+                                '--no-tablespaces'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Queries',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 clean=True,
+                 include_create_database=True,
+                 single_transaction=True,
+             ),
+             url='/restore/job/{0}',
+             expected_cmd_opts=['--create', '--clean',
+                                '--single-transaction'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Disbale',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 disable_trigger=True,
+                 no_data_fail_table=True,
+                 only_schema=False
+             ),
+             url='/restore/job/{0}',
+             # Add '--no-data-for-failed-tables' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--disable-triggers'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+        ('When restore object with option - Miscellaneous',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_file',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 username='postgres'
+             ),
+             params=dict(
+                 file='test_backup_file',
+                 format='custom',
+                 verbose=True,
+                 schemas=[],
+                 tables=[],
+                 database='postgres',
+                 use_set_session_auth=True,
+                 exit_on_error=True,
+             ),
+             url='/restore/job/{0}',
+             # Add '--use_set_session_auth' into
+             # expected_cmd_opts once #3363 fixed
+             expected_cmd_opts=['--exit-on-error'],
+             not_expected_cmd_opts=[],
+             expected_exit_code=[0, None]
+         )),
+    ]
+
+    def setUp(self):
+        if self.server['default_binary_paths'] is None:
+            self.skipTest(
+                "default_binary_paths is not set for the server {0}".format(
+                    self.server['name']
+                )
+            )
+
+    @patch('pgadmin.tools.restore.Server')
+    @patch('pgadmin.tools.restore.current_user')
+    @patch('pgadmin.tools.restore.RestoreMessage')
+    @patch('pgadmin.tools.restore.filename_with_file_manager_path')
+    @patch('pgadmin.tools.restore.BatchProcess')
+    @patch('pgadmin.utils.driver.psycopg2.server_manager.ServerManager.'
+           'export_password_env')
+    def runTest(self, export_password_env_mock, batch_process_mock,
+                filename_mock, restore_message_mock,
+                current_user_mock, server_mock):
+        class TestMockServer():
+            def __init__(self, name, host, port, id, username):
+                self.name = name
+                self.host = host
+                self.port = port
+                self.id = id
+                self.username = username
+
+        self.db_name = ''
+        self.server_id = parent_node_dict["server"][-1]["server_id"]
+
+        mock_obj = TestMockServer(self.class_params['name'],
+                                  self.class_params['host'],
+                                  self.class_params['port'],
+                                  self.server_id,
+                                  self.class_params['username']
+                                  )
+        mock_result = server_mock.query.filter_by.return_value
+        mock_result.first.return_value = mock_obj
+
+        filename_mock.return_value = self.params['file']
+
+        batch_process_mock.set_env_variables = MagicMock(
+            return_value=True
+        )
+        batch_process_mock.start = MagicMock(
+            return_value=True
+        )
+
+        export_password_env_mock.return_value = True
+
+        server_response = server_utils.connect_server(self, self.server_id)
+        if server_response["info"] == "Server connected.":
+            db_owner = server_response['data']['user']['name']
+            self.data = database_utils.get_db_data(db_owner)
+            self.db_name = self.data['name']
+
+        url = self.url.format(self.server_id)
+
+        # Create the restore job
+        response = self.tester.post(url,
+                                    data=json.dumps(self.params),
+                                    content_type='html/json')
+        self.assertEqual(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        job_id = response_data['data']['job_id']
+
+        self.assertTrue(restore_message_mock.called)
+        self.assertTrue(batch_process_mock.called)
+
+        if self.expected_cmd_opts:
+            for opt in self.expected_cmd_opts:
+                self.assertIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
+        if self.not_expected_cmd_opts:
+            for opt in self.not_expected_cmd_opts:
+                self.assertNotIn(
+                    opt,
+                    batch_process_mock.call_args_list[0][1]['args']
+                )
diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py
new file mode 100644
index 0000000..88017f8
--- /dev/null
+++ b/web/pgadmin/tools/restore/tests/test_restore_message.py
@@ -0,0 +1,76 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.tools.restore import RestoreMessage
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch
+else:
+    from unittest.mock import patch
+
+
+class RestoreMessageTest(BaseTestGenerator):
+    """Test the RestoreMessage class"""
+    scenarios = [
+        ('When restore object',
+         dict(
+             class_params=dict(
+                 sid=1,
+                 name='test_restore_server',
+                 port=5444,
+                 host='localhost',
+                 database='postgres',
+                 bfile='test_restore',
+                 args=[
+                     '--file',
+                     'restore_file',
+                     '--host',
+                     'localhost',
+                     '--port',
+                     '5444',
+                     '--username',
+                     'postgres',
+                     '--no-password',
+                     '--database',
+                     'postgres'
+                 ],
+                 cmd="/test_path/pg_restore"
+             ),
+             extected_msg="Restoring backup on the server "
+                          "'test_restore_server (localhost:5444)'...",
+             expetced_details_cmd='/test_path/pg_restore --file '
+                                  '"restore_file" --host "localhost"'
+                                  ' --port "5444" --username "postgres" '
+                                  '--no-password --database "postgres"'
+
+         ))
+    ]
+
+    @patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
+    def runTest(self, get_server_details_mock):
+        get_server_details_mock.return_value = \
+            self.class_params['name'],\
+            self.class_params['host'],\
+            self.class_params['port']
+
+        restore_obj = RestoreMessage(
+            self.class_params['sid'],
+            self.class_params['bfile'],
+            *self.class_params['args']
+        )
+
+        # Check the expected message returned
+        self.assertEqual(restore_obj.message, self.extected_msg)
+
+        # Check the command
+        obj_details = restore_obj.details(self.class_params['cmd'],
+                                          self.class_params['args'])
+        self.assertIn(self.expetced_details_cmd, obj_details)
diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py
index 3e517b6..6f57c67 100644
--- a/web/regression/python_test_utils/test_utils.py
+++ b/web/regression/python_test_utils/test_utils.py
@@ -21,6 +21,8 @@ import config
 import regression
 from regression import test_setup
 
+from pgadmin.utils.preferences import Preferences
+
 SERVER_GROUP = test_setup.config_data['server_group']
 file_name = os.path.realpath(__file__)
 
@@ -86,7 +88,8 @@ def get_config_data():
                 "db_password": srv['db_password'],
                 "role": "",
                 "sslmode": srv['sslmode'],
-                "tablespace_path": srv.get('tablespace_path', None)
+                "tablespace_path": srv.get('tablespace_path', None),
+                "default_binary_paths": srv.get('default_binary_paths', None)
             }
             if 'db_type' in srv:
                 data['db_type'] = srv['db_type']
@@ -445,6 +448,13 @@ def delete_server_with_api(tester, sid):
         url = '/browser/server/obj/' + str(SERVER_GROUP) + "/"
         # Call API to delete the server
         response = tester.delete(url + str(sid))
+
+        cnt = 0
+        for s in regression.parent_node_dict["server"]:
+            if s['server_id'] == int(sid):
+                del regression.parent_node_dict["server"][cnt]
+            cnt += 1
+
     except Exception:
         traceback.print_exc(file=sys.stderr)
 
@@ -596,6 +606,64 @@ def get_db_server(sid):
     return connection
 
 
+def set_preference(default_binary_path):
+    conn = sqlite3.connect(config.TEST_SQLITE_PATH)
+    cur = conn.cursor()
+
+    perf = Preferences.module('paths')
+    pg_path_pref = perf.preference('pg_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' % pg_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ?',
+                    (default_binary_path['pg'], pg_path_pref.pid))
+    else:
+        pg_pref_details = (pg_path_pref.pid, 1,
+                           default_binary_path['pg'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', pg_pref_details)
+
+    ppas_path_pref = perf.preference('ppas_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        ppas_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['ppas'], ppas_path_pref.pid))
+    else:
+        ppas_pref_details = (ppas_path_pref.pid, 1,
+                             default_binary_path['ppas'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', ppas_pref_details)
+
+    gpdb_path_pref = perf.preference('gpdb_bin_dir')
+
+    user_pref = cur.execute(
+        'SELECT pid, uid FROM user_preferences where pid=%s' %
+        gpdb_path_pref.pid
+    )
+    user_pref = user_pref.fetchone()
+
+    if user_pref:
+        cur.execute('UPDATE user_preferences SET value = ? WHERE pid = ? ',
+                    (default_binary_path['gpdb'], gpdb_path_pref.pid))
+    else:
+        gpdb_pref_details = (gpdb_path_pref.pid, 1,
+                             default_binary_path['gpdb'])
+        cur.execute('INSERT INTO user_preferences(pid, uid, value)'
+                    ' VALUES (?,?,?)', gpdb_pref_details)
+
+    conn.commit()
+
+
 def remove_db_file():
     """This function use to remove SQLite DB file"""
     if os.path.isfile(config.TEST_SQLITE_PATH):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index d786692..26b25c7 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -114,6 +114,9 @@ test_client = app.test_client()
 driver = None
 app_starter = None
 handle_cleanup = None
+app.PGADMIN_RUNTIME = True
+if config.SERVER_MODE is True:
+    app.PGADMIN_RUNTIME = False
 
 setattr(unit_test.result.TestResult, "passed", [])
 
@@ -234,7 +237,6 @@ def get_test_modules(arguments):
     # Sort module list so that test suite executes the test cases sequentially
     module_list = TestsGeneratorRegistry.registry.items()
     module_list = sorted(module_list, key=lambda module_tuple: module_tuple[0])
-
     return module_list
 
 
@@ -393,6 +395,9 @@ if __name__ == '__main__':
             # Create test server
             server_information = test_utils.create_parent_server_node(server)
 
+            if server['default_binary_paths'] is not None:
+                test_utils.set_preference(server['default_binary_paths'])
+
             suite = get_suite(test_module_list,
                               server,
                               test_client,
diff --git a/web/regression/test_config.json.in b/web/regression/test_config.json.in
index ebc1466..15b133a 100644
--- a/web/regression/test_config.json.in
+++ b/web/regression/test_config.json.in
@@ -23,7 +23,12 @@
       "maintenance_db": "postgres",
       "sslmode": "prefer",
       "tablespace_path": "",
-      "enabled": true
+      "enabled": true,
+      "default_binary_paths": {
+        "pg": "/opt/PostgreSQL/9.4/bin/",
+        "ppas": "/opt/edb/as10/bin/",
+        "gpdb": ""
+      }
     }
   ],
   "server_update_data": [


^ permalink  raw  reply  [nested|flat] 29+ messages in thread

* Re: [pgadmin4][Patch]: Test cases for the backup module
  2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-04-25 16:10 ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-05-28 12:09   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-29 19:35     ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-05-30 04:43       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 05:16         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-05-31 16:30           ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-01 11:06             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-01 21:31               ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-04 05:35                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-04 15:11                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Joao De Almeida Pereira <[email protected]>
  2018-06-05 03:39                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:06                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:37                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 08:39                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-05 08:50                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-05 23:43                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-06 04:07                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 05:12                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 06:57                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-06 10:24                                       ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 05:33                                         ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-08 09:08                                           ` Re: [pgadmin4][Patch]: Test cases for the backup module Dave Page <[email protected]>
  2018-06-12 10:24                                             ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 10:44                                               ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-12 15:36                                                 ` Re: [pgadmin4][Patch]: Test cases for the backup module Victoria Henry <[email protected]>
  2018-06-13 12:12                                                   ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
  2018-06-15 07:13                                                     ` Re: [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
@ 2018-06-15 10:37                                                       ` Dave Page <[email protected]>
  0 siblings, 0 replies; 29+ messages in thread

From: Dave Page @ 2018-06-15 10:37 UTC (permalink / raw)
  To: Khushboo Vashi <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao De Almeida Pereira <[email protected]>; pgadmin-hackers

Thanks, applied with a few tweaks to remove some unused imports and a
couple of variables.

On Fri, Jun 15, 2018 at 8:13 AM, Khushboo Vashi <
[email protected]> wrote:

> Hi,
>
> Please find the attached updated patch.
>
> On Wed, Jun 13, 2018 at 5:42 PM, Khushboo Vashi <
> [email protected]> wrote:
>
>> Hi Victoria,
>>
>>
>> On Tue, Jun 12, 2018 at 9:06 PM, Victoria Henry <[email protected]>
>> wrote:
>>
>>> Hi Khushboo
>>> can you explain a little bit more this while loop?
>>>
>>>
>>> cnt = 0
>>> while 1:
>>>     if cnt > 1:
>>>         break
>>>     # Check the process list
>>>     response1 = self.tester.get('/misc/bgprocess/?_='.format(
>>>         random.randint(1, 9999999)))
>>>     self.assertEquals(response1.status_code, 200)
>>>     process_list = json.loads(response1.data.decode('utf-8'))
>>>
>>>     if len(process_list) > 0 and 'execution_time' in process_list[0]:
>>>         break
>>>     time.sleep(0.5)
>>>     cnt += 1
>>>
>>> From what it looks like this will only run twice, maybe a for would be a
>>> better solution because we know it will only run twice. Also are we sure we
>>> only want it to run twice?
>>>
>>> The code waits till the background process completes. So, while I
>> originally developed, not intended to run only twice.
>> But after that I put a kind of break point and that remains there. So, I
>> will remove that if condition which is not required.
>>
> I have made maximum 5 attempts.
>
>> We are using PyCharm to do our developments and we notice there are a big
>>> group of unused variables throughout. We should remove them if they are not
>>> needed. Not sure if your editor also shows that information or not.
>>>
>> Do you know if there is a configuration in pycodestyle to enable the
>>> check for unused variables? That would help a lot.
>>>
>>> Removed unused local variables.
>
>> Thanks for sharing the information.
>>
>>> The code
>>>
>>> assert 'execution_time' in process_list[0]
>>> assert 'stime' in process_list[0]
>>> assert 'exit_code' in process_list[0]
>>> assert process_list[0]['exit_code'] in self.expected_exit_code
>>>
>>> in test_Create_restore_job should use self.assertEqual or similar from
>>> unittest instead of plain assert. Because when something fails we do
>>> not have a way to understand what was wrong.
>>>
>> Will do.
>>
> Done
>
>> The tests on the restore are still failing GreenPlum.
>>>
>> It is failing because, Restore is not working with GreenPlum. Can you
>> please look into the Restore functionality for GPDB?
>>
>>
>> Thanks,
>> Khushboo
>>
>>> ​
>>>
>>>
>>> Thanks,
> Khushboo
>
>>
>>> Thanks
>>> Victoria & Joao
>>>
>>> On Tue, Jun 12, 2018 at 6:44 AM Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Please find the attached updated patch with some code cleanup.
>>>>
>>>> On Tue, Jun 12, 2018 at 3:54 PM, Khushboo Vashi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> Please find the attached patch excluding feature test cases.
>>>>> Python test cases are working fine, so we can commit this patch. I am
>>>>> working on fixing the feature tests which are failing on the different
>>>>> window sizes.
>>>>>
>>>>> Thanks,
>>>>> Khushboo
>>>>>
>>>>> On Fri, Jun 8, 2018 at 2:38 PM, Dave Page <[email protected]> wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> On Fri, Jun 8, 2018 at 6:33 AM, Khushboo Vashi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Dave,
>>>>>>>
>>>>>>> As per our discussion I have changed the window size to 1280X800,
>>>>>>> before it was 1280X900.
>>>>>>> Please find the attached updated patch
>>>>>>>
>>>>>>
>>>>>> I'm not sure that actually made any difference on my system. The
>>>>>> window continued to look taller than it is wide, so I wonder if the code to
>>>>>> set the size is being ignored, or is at the wrong place?
>>>>>>
>>>>>> Anyway, I got 10 failures with this patch :-(
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.feature_tests.pg_util
>>>>>> ities_backup_restore_test.PGUtilitiesBackupFeatureTest)
>>>>>>
>>>>>> Test for PG utilities - Backup and Restore
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py",
>>>>>> line 97, in runTest
>>>>>>
>>>>>>     self.page.find_by_xpath("//div[contains(@class,'wcFloatingFo
>>>>>> cus')"
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 171, in find_by_xpath
>>>>>>
>>>>>>     lambda driver: driver.find_element_by_xpath(xpath)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 263, in wait_for_element
>>>>>>
>>>>>>     return self._wait_for("element to exist", element_if_it_exists)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 337, in _wait_for
>>>>>>
>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>>
>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>
>>>>>> TimeoutException: Message: Timed out waiting for element to exist
>>>>>>
>>>>>>
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.feature_tests.xss_che
>>>>>> cks_pgadmin_debugger_test.CheckDebuggerForXssFeatureTest)
>>>>>>
>>>>>> Tests to check if Debugger is vulnerable to XSS
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>>>>>> line 42, in runTest
>>>>>>
>>>>>>     self._function_node_expandable()
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/feature_tests/xss_checks_pgadmin_debugger_test.py",
>>>>>> line 57, in _function_node_expandable
>>>>>>
>>>>>>     self.page.select_tree_item("a_test_function()")
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 135, in select_tree_item
>>>>>>
>>>>>>     "' and @class='aciTreeItem']").click()
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 171, in find_by_xpath
>>>>>>
>>>>>>     lambda driver: driver.find_element_by_xpath(xpath)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 263, in wait_for_element
>>>>>>
>>>>>>     return self._wait_for("element to exist", element_if_it_exists)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/regression/feature_utils/pgadmin_page.py",
>>>>>> line 337, in _wait_for
>>>>>>
>>>>>>     "Timed out waiting for " + waiting_for_message
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packa
>>>>>> ges/selenium/webdriver/support/wait.py", line 80, in until
>>>>>>
>>>>>>     raise TimeoutException(message, screen, stacktrace)
>>>>>>
>>>>>> TimeoutException: Message: Timed out waiting for element to exist
>>>>>>
>>>>>>
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.tools.backup.tests.te
>>>>>> st_create_backup_job.BackupJobTest)
>>>>>>
>>>>>> When backup the object with the default options
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_create_backup_job.py",
>>>>>> line 58, in runTest
>>>>>>
>>>>>>     self.assertNotIn
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>>>>>> line 33, in run_backup_job
>>>>>>
>>>>>>     random.randint(1, 9999999)))
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 830, in get
>>>>>>
>>>>>>     return self.open(*args, **kw)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>>>> line 127, in open
>>>>>>
>>>>>>     follow_redirects=follow_redirects)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 803, in open
>>>>>>
>>>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 716, in run_wsgi_app
>>>>>>
>>>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 923, in run_wsgi_app
>>>>>>
>>>>>>     app_rv = app(environ, start_response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1997, in __call__
>>>>>>
>>>>>>     return self.wsgi_app(environ, start_response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1985, in wsgi_app
>>>>>>
>>>>>>     response = self.handle_exception(e)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1540, in handle_exception
>>>>>>
>>>>>>     reraise(exc_type, exc_value, tb)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1982, in wsgi_app
>>>>>>
>>>>>>     response = self.full_dispatch_request()
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1614, in full_dispatch_request
>>>>>>
>>>>>>     rv = self.handle_user_exception(e)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1517, in handle_user_exception
>>>>>>
>>>>>>     reraise(exc_type, exc_value, tb)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1612, in full_dispatch_request
>>>>>>
>>>>>>     rv = self.dispatch_request()
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1598, in dispatch_request
>>>>>>
>>>>>>     return self.view_functions[rule.endpoint](**req.view_args)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>>>>> line 792, in decorated_view
>>>>>>
>>>>>>     return func(*args, **kwargs)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>>>>> line 62, in index
>>>>>>
>>>>>>     return make_response(response=BatchProcess.list())
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>>>>> line 584, in list
>>>>>>
>>>>>>     details = desc.details(p.command, args)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>>> line 159, in details
>>>>>>
>>>>>>     name, host, port = self.get_server_details()
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>>> line 122, in get_server_details
>>>>>>
>>>>>>     host = manager.local_bind_host if manager.use_ssh_tunnel else
>>>>>> s.host
>>>>>>
>>>>>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>>>>>
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.tools.maintenance.tes
>>>>>> ts.test_create_maintenance_job.MaintenanceJobTest)
>>>>>>
>>>>>> When maintenance the object with the default options
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/maintenance/tes
>>>>>> ts/test_create_maintenance_job.py", line 71, in runTest
>>>>>>
>>>>>>     random.randint(1, 9999999)))
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 830, in get
>>>>>>
>>>>>>     return self.open(*args, **kw)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>>>> line 127, in open
>>>>>>
>>>>>>     follow_redirects=follow_redirects)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 803, in open
>>>>>>
>>>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 716, in run_wsgi_app
>>>>>>
>>>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 923, in run_wsgi_app
>>>>>>
>>>>>>     app_rv = app(environ, start_response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1997, in __call__
>>>>>>
>>>>>>     return self.wsgi_app(environ, start_response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1985, in wsgi_app
>>>>>>
>>>>>>     response = self.handle_exception(e)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1540, in handle_exception
>>>>>>
>>>>>>     reraise(exc_type, exc_value, tb)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1982, in wsgi_app
>>>>>>
>>>>>>     response = self.full_dispatch_request()
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1614, in full_dispatch_request
>>>>>>
>>>>>>     rv = self.handle_user_exception(e)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1517, in handle_user_exception
>>>>>>
>>>>>>     reraise(exc_type, exc_value, tb)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1612, in full_dispatch_request
>>>>>>
>>>>>>     rv = self.dispatch_request()
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1598, in dispatch_request
>>>>>>
>>>>>>     return self.view_functions[rule.endpoint](**req.view_args)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>>>>> line 792, in decorated_view
>>>>>>
>>>>>>     return func(*args, **kwargs)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>>>>> line 62, in index
>>>>>>
>>>>>>     return make_response(response=BatchProcess.list())
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>>>>> line 584, in list
>>>>>>
>>>>>>     details = desc.details(p.command, args)
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>>> line 159, in details
>>>>>>
>>>>>>     name, host, port = self.get_server_details()
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/__init__.py",
>>>>>> line 122, in get_server_details
>>>>>>
>>>>>>     host = manager.local_bind_host if manager.use_ssh_tunnel else
>>>>>> s.host
>>>>>>
>>>>>> AttributeError: 'NoneType' object has no attribute 'use_ssh_tunnel'
>>>>>>
>>>>>>
>>>>>> ============================================================
>>>>>> ==========
>>>>>>
>>>>>> ERROR: runTest (pgadmin.tools.restore.tests.t
>>>>>> est_create_restore_job.RestoreJobTest)
>>>>>>
>>>>>> When restore the object with the default options
>>>>>>
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>>
>>>>>> Traceback (most recent call last):
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
>>>>>> line 95, in runTest
>>>>>>
>>>>>>     self.create_backup()
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/restore/tests/test_create_restore_job.py",
>>>>>> line 86, in create_backup
>>>>>>
>>>>>>     self.assertNotIn
>>>>>>
>>>>>>   File "/Users/dpage/git/pgadmin4/web/pgadmin/tools/backup/tests/test_backup_utils.py",
>>>>>> line 33, in run_backup_job
>>>>>>
>>>>>>     random.randint(1, 9999999)))
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 830, in get
>>>>>>
>>>>>>     return self.open(*args, **kw)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/testing.py",
>>>>>> line 127, in open
>>>>>>
>>>>>>     follow_redirects=follow_redirects)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 803, in open
>>>>>>
>>>>>>     response = self.run_wsgi_app(environ, buffered=buffered)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 716, in run_wsgi_app
>>>>>>
>>>>>>     rv = run_wsgi_app(self.application, environ, buffered=buffered)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/test.py",
>>>>>> line 923, in run_wsgi_app
>>>>>>
>>>>>>     app_rv = app(environ, start_response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1997, in __call__
>>>>>>
>>>>>>     return self.wsgi_app(environ, start_response)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1985, in wsgi_app
>>>>>>
>>>>>>     response = self.handle_exception(e)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1540, in handle_exception
>>>>>>
>>>>>>     reraise(exc_type, exc_value, tb)
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1982, in wsgi_app
>>>>>>
>>>>>>     response = self.full_dispatch_request()
>>>>>>
>>>>>>   File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>>>>> line 1614, in full_dispatch_request
>>>>>>
>>>>>>     rv = self.handle_user_exception(e)
>>>>>>
>>>>>>
>>
>


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


^ permalink  raw  reply  [nested|flat] 29+ messages in thread


end of thread, other threads:[~2018-06-15 10:37 UTC | newest]

Thread overview: 29+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2018-04-25 09:20 [pgadmin4][Patch]: Test cases for the backup module Khushboo Vashi <[email protected]>
2018-04-25 16:10 ` Joao De Almeida Pereira <[email protected]>
2018-05-28 12:09   ` Khushboo Vashi <[email protected]>
2018-05-29 19:35     ` Dave Page <[email protected]>
2018-05-30 04:43       ` Khushboo Vashi <[email protected]>
2018-05-31 05:16         ` Khushboo Vashi <[email protected]>
2018-05-31 16:30           ` Victoria Henry <[email protected]>
2018-06-01 11:06             ` Khushboo Vashi <[email protected]>
2018-06-01 21:31               ` Dave Page <[email protected]>
2018-06-04 05:35                 ` Khushboo Vashi <[email protected]>
2018-06-04 15:11                   ` Joao De Almeida Pereira <[email protected]>
2018-06-05 03:39                     ` Khushboo Vashi <[email protected]>
2018-06-05 08:06                       ` Dave Page <[email protected]>
2018-06-05 08:37                         ` Khushboo Vashi <[email protected]>
2018-06-05 08:39                           ` Dave Page <[email protected]>
2018-06-05 08:50                             ` Khushboo Vashi <[email protected]>
2018-06-05 23:43                               ` Victoria Henry <[email protected]>
2018-06-06 04:07                                 ` Khushboo Vashi <[email protected]>
2018-06-06 05:12                                   ` Khushboo Vashi <[email protected]>
2018-06-06 06:57                                     ` Khushboo Vashi <[email protected]>
2018-06-06 10:24                                       ` Khushboo Vashi <[email protected]>
2018-06-08 05:33                                         ` Khushboo Vashi <[email protected]>
2018-06-08 09:08                                           ` Dave Page <[email protected]>
2018-06-12 10:24                                             ` Khushboo Vashi <[email protected]>
2018-06-12 10:44                                               ` Khushboo Vashi <[email protected]>
2018-06-12 15:36                                                 ` Victoria Henry <[email protected]>
2018-06-13 12:12                                                   ` Khushboo Vashi <[email protected]>
2018-06-15 07:13                                                     ` Khushboo Vashi <[email protected]>
2018-06-15 10:37                                                       ` Dave Page <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox