Пример #1
0
    def test_conn_err(self):
        parser = DBCParams.get_arg_parser()
        args = parser.parse_args([
            '--packet-name=' + self.packet_name,
            '--db-name=' + self.test_dbc_01
        ])

        dbc = MainRoutine(args, self.conf_file)
        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.test_dbc_01])
        ActionTracker.init_tbls(db_conn, dbc.sys_conf.schema_location)
        ActionTracker.set_packet_unlock(db_conn, dbc.sys_conf.schema_location,
                                        self.packet_name)
        db_conn.close()

        main = MainRoutine(args, self.conf_file)

        @threaded
        def emulate_conn_error():
            time.sleep(2)
            th_db_conn = postgresql.open(
                dbc.sys_conf.dbs_dict[self.test_dbc_01])
            main.terminate_conns(th_db_conn, self.test_dbc_01,
                                 main.sys_conf.application_name,
                                 self.packet_name)
            th_db_conn.close()

        main.append_thread(self.test_dbc_01 + '_ext', emulate_conn_error())

        res = main.run()

        self.assertTrue(
            res.packet_status[self.test_dbc_01] == PacketStatus.DONE)
        self.assertTrue(
            res.result_code[self.test_dbc_01] == ResultCode.SUCCESS)
Пример #2
0
    def test_lock(self, mocked_requests_post):
        parser = DBCParams.get_arg_parser()
        args = parser.parse_args([
            '--packet-name=' + self.packet_name,
            '--db-name=' + self.test_dbc_01
        ])
        dbc = MainRoutine(args, self.conf_file)

        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.test_dbc_01])
        ActionTracker.set_packet_lock(db_conn, dbc.sys_conf.schema_location,
                                      self.packet_name)

        res_1 = dbc.run()
        self.assertTrue(
            res_1.packet_status[self.test_dbc_01] == PacketStatus.STARTED)
        self.assertTrue(
            res_1.result_code[self.test_dbc_01] == ResultCode.LOCKED)

        ActionTracker.set_packet_unlock(db_conn, dbc.sys_conf.schema_location,
                                        self.packet_name)

        res_2 = MainRoutine(args, self.conf_file).run()
        self.assertTrue(
            res_2.packet_status[self.test_dbc_01] == PacketStatus.DONE)
        self.assertTrue(
            res_2.result_code[self.test_dbc_01] == ResultCode.SUCCESS)

        db_conn.close()
Пример #3
0
    def test_lock(self, mocked_requests_post):
        dbc = MainRoutine(self.wipe_params, self.conf_file)
        res_1 = dbc.run()
        self.assertTrue(
            res_1.packet_status[self.test_dbc_01] == PacketStatus.NEW)
        self.assertTrue(
            res_1.result_code[self.test_dbc_01] == ResultCode.NOTHING_TODO)

        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.test_dbc_01])
        ActionTracker.set_packet_lock(db_conn, dbc.sys_conf.schema_location,
                                      self.packet_name)

        res_2 = MainRoutine(self.run_params, self.conf_file).run()
        self.assertTrue(
            res_2.packet_status[self.test_dbc_01] == PacketStatus.STARTED)
        self.assertTrue(
            res_2.result_code[self.test_dbc_01] == ResultCode.LOCKED)

        ActionTracker.set_packet_unlock(db_conn, dbc.sys_conf.schema_location,
                                        self.packet_name)
        db_conn.close()

        res_3 = MainRoutine(self.run_params, self.conf_file).run()
        self.assertTrue(
            res_3.packet_status[self.test_dbc_01] == PacketStatus.DONE)
        self.assertTrue(
            res_3.result_code[self.test_dbc_01] == ResultCode.SUCCESS)
Пример #4
0
    def test_sigint(self, mocked_requests_post):
        parser = DBCParams.get_arg_parser()
        args = parser.parse_args([
            '--packet-name=' + self.packet_name,
            '--db-name=' + self.test_dbc_01
        ])

        dbc = MainRoutine(args, self.conf_file)
        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.test_dbc_01])
        ActionTracker.set_packet_unlock(db_conn, dbc.sys_conf.schema_location,
                                        self.packet_name)
        db_conn.close()

        main = MainRoutine(args, self.conf_file)

        @threaded
        def send_signal():
            time.sleep(5)
            pid = os.getpid()
            os.kill(pid, signal.SIGINT)

        @threaded
        def emulate_signal():  # for Windows
            time.sleep(5)
            main.external_interrupt = True
            time.sleep(3)
            th_db_conn = postgresql.open(
                dbc.sys_conf.dbs_dict[self.test_dbc_01])
            main.terminate_conns(th_db_conn, self.test_dbc_01,
                                 main.sys_conf.application_name,
                                 self.packet_name)
            th_db_conn.close()

        if os.name == 'nt':
            main.append_thread(self.test_dbc_01 + '_ext', emulate_signal())
        else:
            main.append_thread(self.test_dbc_01 + '_ext', send_signal())

        res = main.run()

        self.assertTrue(
            res.packet_status[self.test_dbc_01] == PacketStatus.STARTED)
        self.assertTrue(
            res.result_code[self.test_dbc_01] == ResultCode.TERMINATE)
Пример #5
0
    def test_packets(self, mocked_requests_post):
        parser = DBCParams.get_arg_parser()
        args = parser.parse_args(
            ['--packet-name=dba_get_version', '--db-name=' + self.test_dbc_01])
        dbc = MainRoutine(args, self.conf_file)
        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.test_dbc_01])
        ActionTracker.init_tbls(db_conn, dbc.sys_conf.schema_location)

        for args in self.runs:
            ActionTracker.set_packet_unlock(db_conn,
                                            dbc.sys_conf.schema_location,
                                            args.packet_name)
            res = MainRoutine(args, self.conf_file).run()
            self.assertTrue(
                res.result_code[args.db_name] == ResultCode.SUCCESS)
            self.assertTrue(
                res.packet_status[args.db_name] == PacketStatus.DONE)

        db_conn.close()
Пример #6
0
    def test_skip_action_cancel(self):
        parser = DBCParams.get_arg_parser()

        MainRoutine(
            parser.parse_args([
                '--packet-name=' + self.packet_name,
                '--db-name=' + self.test_dbc_01, '--wipe'
            ]), self.conf_file).run()

        args = parser.parse_args([
            '--packet-name=' + self.packet_name,
            '--db-name=' + self.test_dbc_01, '--skip-action-cancel'
        ])

        dbc = MainRoutine(args, self.conf_file)
        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.test_dbc_01])
        ActionTracker.set_packet_unlock(db_conn, dbc.sys_conf.schema_location,
                                        self.packet_name)
        db_conn.close()

        main = MainRoutine(args, self.conf_file)

        @threaded
        def emulate_conn_error():
            time.sleep(5)
            th_db_conn = postgresql.open(
                dbc.sys_conf.dbs_dict[self.test_dbc_01])
            main.terminate_conns(th_db_conn,
                                 self.test_dbc_01,
                                 main.sys_conf.application_name,
                                 self.packet_name,
                                 terminate=False)
            th_db_conn.close()

        main.append_thread(self.test_dbc_01 + '_ext', emulate_conn_error())

        res_2 = main.run()

        self.assertTrue(
            res_2.packet_status[self.test_dbc_01] == PacketStatus.EXCEPTION)
        self.assertTrue(res_2.result_code[self.test_dbc_01] == ResultCode.FAIL)
Пример #7
0
    def test_create_db(self):
        global call_TestDBCPrepareDBs
        if call_TestDBCPrepareDBs:
            return

        parser = DBCParams.get_arg_parser()

        args = parser.parse_args([
            '--packet-name=' + self.packet_name, '--db-name=' + self.pg_db,
            '--wipe'
        ])
        dbc = MainRoutine(args, self.conf_file)
        db_conn = postgresql.open(dbc.sys_conf.dbs_dict[self.pg_db])
        ActionTracker.cleanup(db_conn, dbc.sys_conf.schema_location)

        db_conn.execute("""
            SELECT pg_terminate_backend(pid)
            FROM pg_stat_activity
            WHERE pid <> pg_backend_pid()
                AND datname in ('test_dbc_01', 'test_dbc_02')
        """)

        db_conn.execute("""DROP DATABASE IF EXISTS test_dbc_01""")
        db_conn.execute("""DROP DATABASE IF EXISTS test_dbc_02""")
        db_conn.close()

        MainRoutine(args, self.conf_file).run()
        MainRoutine(
            parser.parse_args([
                '--packet-name=' + self.packet_name, '--db-name=' + self.pg_db,
                '--unlock'
            ]), self.conf_file).run()
        res_1 = MainRoutine(
            parser.parse_args([
                '--packet-name=' + self.packet_name, '--db-name=' + self.pg_db
            ]), self.conf_file).run()

        call_TestDBCPrepareDBs = True
Пример #8
0
 def fill_status(self, db_name, db_conn):
     self.db_packet_status = ActionTracker.get_packet_status(
         db_conn, self.sys_conf.schema_location, self.args.packet_name
     )
     if "status" in self.db_packet_status:
         if "exception_descr" in self.db_packet_status and self.db_packet_status["exception_descr"] is not None:
             self.packet_status[db_name] = PacketStatus.EXCEPTION
         elif "status" in self.db_packet_status and self.db_packet_status["status"] is not None:
             if self.db_packet_status["status"] == 'done':
                 self.packet_status[db_name] = PacketStatus.DONE
             if self.db_packet_status["status"] == 'started':
                 self.packet_status[db_name] = PacketStatus.STARTED
     else:
         self.packet_status[db_name] = PacketStatus.NEW
Пример #9
0
    def run(self) -> DBCResult:
        self.logger.log('=====> DBC %s started' % VERSION, "Info", do_print=True)

        self.logger.log("#--------------- Incoming parameters", "Info")
        for arg in vars(self.args):
            self.logger.log("#   %s = %s" % (arg, getattr(self.args, arg)), "Info")
        self.logger.log("#-----------------------------------", "Info")

        # ========================================================================
        # confirmation
        break_deployment = False
        if not self.args.list and not self.args.status and self.sys_conf.db_name_all_confirmation:
            if len(self.dbs) > 1 and not self.args.force:
                print("Deployment will be performed on these databases:\n")
                for db_name in self.dbs:
                    print("     " + db_name)
                cmd_question = input('\nDo you want to continue? Type YES to continue...\n')
                if cmd_question != "YES":
                    print('Stopping...')
                    break_deployment = True
                    self.result_code[db_name] = ResultCode.NOTHING_TODO
        # ========================================================================

        if self.args.list:
            print("List of targets:")
            for db_name in self.dbs:
                print("     " + db_name)
                break_deployment = True
                self.result_code[db_name] = ResultCode.NOTHING_TODO

        if not break_deployment:
            if len(self.dbs) == 0:
                self.logger.log('No target databases!', "Error", do_print=True)
                for db in self.args.db_name.split(','):
                    self.packet_status[db] = PacketStatus.UNKNOWN
                    self.result_code[db] = ResultCode.NOTHING_TODO
            for db_name in self.dbs:
                try:
                    self.run_on_db(db_name, self.sys_conf.dbs_dict[db_name])
                    if self.args.seq:
                        self.wait_threads()     # wait on pair (lock_observer, worker_db_func)
                except (
                        postgresql.exceptions.AuthenticationSpecificationError,
                        postgresql.exceptions.ClientCannotConnectError,
                        TimeoutError
                ) as e:
                    self.logger.log(
                        'Cannot connect to %s: \n%s' % (db_name, exception_helper(self.sys_conf.detailed_traceback)),
                        "Error",
                        do_print=True
                    )

        if not break_deployment:
            self.wait_threads()     # wait all threads

        for db, result in self.workers_result.items():
            if db in self.sys_conf.dbs_dict:
                db_conn = postgresql.open(self.sys_conf.dbs_dict[db])
                ActionTracker.set_packet_unlock(db_conn, self.sys_conf.schema_location, self.args.packet_name)
                db_conn.close()
                if result == WorkerResult.SUCCESS:
                    self.result_code[db] = ResultCode.SUCCESS
                    self.packet_status[db] = PacketStatus.DONE
                if result == WorkerResult.FAIL:
                    self.result_code[db] = ResultCode.FAIL
                    self.packet_status[db] = PacketStatus.EXCEPTION
                if result == WorkerResult.TERMINATE:
                    self.result_code[db] = ResultCode.TERMINATE
                    self.packet_status[db] = PacketStatus.STARTED

        self.logger.log('<===== DBC %s finished' % VERSION, "Info", do_print=True)
        self.logger.stop()

        result = DBCResult()
        result.command_type = self.command_type
        result.packet_type = self.packet_type
        result.result_code = self.result_code.copy()
        result.packet_status = self.packet_status.copy()
        result.result_data = self.result_data.copy()

        self.cleanup()
        return result
Пример #10
0
    def run_on_db(self, db_name, str_conn):
        db_conn = postgresql.open(str_conn)
        # ================================================================================================
        # Check 'dbc_packets', 'dbc_steps', 'dbc_actions', 'dbc_locks' tables
        ActionTracker.init_tbls(db_conn, self.sys_conf.schema_location)
        # ================================================================================================
        if self.packet_type == PacketType.DEFAULT or self.args.status:
            self.fill_status(db_name, db_conn)
        if self.packet_type in (
                PacketType.READ_ONLY,
                PacketType.MAINTENANCE,
                PacketType.NO_COMMIT,
                PacketType.EXPORT_DATA
        ) and not self.args.status:
            self.packet_status[db_name] = PacketStatus.NEW
        # ================================================================================================
        if self.args.stop:
            term_conn_res = self.terminate_conns(
                db_conn, db_name, self.sys_conf.application_name, self.args.packet_name
            )
            self.result_code[db_name] = ResultCode.SUCCESS if term_conn_res else ResultCode.NOTHING_TODO
        # ================================================================================================
        if self.args.wipe and self.packet_type not in (
                PacketType.READ_ONLY,
                PacketType.MAINTENANCE,
                PacketType.NO_COMMIT,
                PacketType.EXPORT_DATA
        ):
            wipe_res = ActionTracker.wipe_packet(db_conn, self.sys_conf.schema_location, self.args.packet_name)
            ActionTracker.set_packet_unlock(db_conn, self.sys_conf.schema_location, self.args.packet_name)
            if wipe_res:
                self.result_code[db_name] = ResultCode.SUCCESS
                print("=====> Database '%s', packet '%s' successfully wiped!" % (db_name, self.args.packet_name))
            else:
                self.result_code[db_name] = ResultCode.NOTHING_TODO
                print("=====> Database '%s', packet '%s' data not found!" % (db_name, self.args.packet_name))
            self.packet_status[db_name] = PacketStatus.NEW
        elif self.args.wipe:
            print("=====> Database '%s', packet '%s' nothing to wipe!" % (db_name, self.args.packet_name))
            self.result_code[db_name] = ResultCode.NOTHING_TODO
            self.packet_status[db_name] = PacketStatus.NEW
        # ================================================================================================
        if self.args.status:
            print(
                "=====> Database '%s', packet '%s' status: %s" %
                (
                    db_name,
                    self.args.packet_name,
                    "new" if db_name not in self.packet_status else self.packet_status[db_name]
                )
            )
            self.result_code[db_name] = ResultCode.SUCCESS

            if "exception_descr" in  self.db_packet_status and  self.db_packet_status["exception_descr"] is not None:
                print("       Action date time: %s" % str( self.db_packet_status["exception_dt"]))
                print("=".join(['=' * 100]))
                print(self.db_packet_status["exception_descr"])
                print("=".join(['=' * 100]))
        # ================================================================================================
        if not self.args.unlock and self.command_type == CommandType.RUN:
            if self.packet_status[db_name] != PacketStatus.DONE:
                # ===========================================
                if ActionTracker.is_packet_locked(db_conn, self.sys_conf.schema_location, self.args.packet_name):
                    self.logger.log(
                        '=====> Packet %s is locked in DB %s' % (self.args.packet_name, db_name),
                        "Error",
                        do_print=True
                    )
                    self.result_code[db_name] = ResultCode.LOCKED
                    self.packet_status[db_name] = PacketStatus.STARTED
                else:
                    ActionTracker.set_packet_lock(db_conn, self.sys_conf.schema_location, self.args.packet_name)
                    self.logger.log(
                        '=====> Hold lock for packet %s in DB %s' % (self.args.packet_name, db_name),
                        "Info",
                        do_print=True
                    )
                    self.append_thread(
                        db_name,
                        self.lock_observer("lock_observer_%s" % str(db_name), str_conn, db_name, self.args.packet_name)
                    )

                    self.append_thread(
                        db_name,
                        self.worker_db_func(
                            "manager_db_%s" % str(db_name),
                            str_conn,
                            db_name,
                            self.args.packet_name,
                            self.packet_type == PacketType.READ_ONLY
                        )
                    )

                    self.logger.log(
                        '--------> Packet \'%s\' started for \'%s\' database!' % \
                        (self.args.packet_name, db_name),
                        "Info",
                        do_print=True
                    )
                # ===========================================
            if self.packet_status[db_name] == PacketStatus.DONE:
                self.logger.log(
                    '<-------- Packet \'%s\' already deployed to \'%s\' database!' % \
                    (self.args.packet_name, db_name),
                    "Info",
                    do_print=True
                )
                self.packet_status[db_name] = PacketStatus.DONE
                self.result_code[db_name] = ResultCode.NOTHING_TODO

        if self.args.unlock:
            if ActionTracker.is_packet_locked(db_conn, self.sys_conf.schema_location, self.args.packet_name):
                ActionTracker.set_packet_unlock(db_conn, self.sys_conf.schema_location, self.args.packet_name)
                self.result_code[db_name] = ResultCode.SUCCESS
                self.logger.log(
                    '--------> Packet \'%s\' has been unlocked in \'%s\' database!' % \
                    (self.args.packet_name, db_name),
                    "Info",
                    do_print=True
                )
            else:
                self.result_code[db_name] = ResultCode.NOTHING_TODO
                self.logger.log(
                    '--------> Packet \'%s\' not locked in \'%s\' database!' % \
                    (self.args.packet_name, db_name),
                    "Info",
                    do_print=True
                )

        db_conn.close()