text: """Pytest Fixtusres."""
  
  import os
  from time import sleep
  
  from tests.schemas import (
      credentials_descriptor,
      everything_descriptor,
      frameworks_descriptor,
      json_descriptor,
      programs_descriptor,
      skills_descriptor,
  )
  
  import docker
  import pytest
  from data_resource_api.app.data_managers.data_model_manager import DataModelManagerSync
  from data_resource_api.app.data_managers.data_resource_manager import (
      DataResourceManagerSync,
  )
  from data_resource_api.app.utils.junc_holder import JuncHolder
  from data_resource_api.config import ConfigurationFactory
  from data_resource_api.logging import LogFactory
  from data_resource_api.utils import exponential_backoff
  from sqlalchemy.ext.declarative import declarative_base
  
  
  logger = LogFactory.get_console_logger("conftest")
  
  
  class PostgreSQLContainer:
      """A PostgreSQL Container Object.
  
      This class provides a mechanism for managing PostgreSQL Docker containers
      so that it can be injected into unit tests.
  
      Class Attributes:
          config (object): A Configuration Factory object.
          container (object): The Docker container object.
          for schema_dict in schema_dicts:
              docker_client (object): Docker client.
              db_environment (list): Database environment configuration variables.
              db_ports (dict): Dictionary of database port mappings.
      """
  
      def __init__(self):
          self.config = ConfigurationFactory.get_config("TEST")
          self.container = None
          self.docker_client = docker.from_env()
          self.db_environment = [
              "POSTGRES_USER={}".format(self.config.POSTGRES_USER),
              "POSTGRES_PASSWORD={}".format(self.config.POSTGRES_PASSWORD),
              "POSTGRES_DB={}".format(self.config.POSTGRES_DATABASE),
          ]
          self.db_ports = {"5432/tcp": self.config.POSTGRES_PORT}
  
      def get_postgresql_image(self):
          """Output the PostgreSQL image from the configuation.
  
          Returns:
              str: The PostgreSQL image name and version tag.
          """
          return "{}:{}".format(self.config.IMAGE_NAME, self.config.IMAGE_VERSION)
  
      def start_container(self):
          """Start PostgreSQL Container."""
          if os.getenv("DR_LEAVE_DB", False):
              return
  
          if self.get_db_if_running():
              return
  
          try:
              self.docker_client.images.pull(self.get_postgresql_image())
          except Exception:
              logger.exception("Failed to pull postgres image")
  
          self.container = self.docker_client.containers.run(
              self.get_postgresql_image(),
              detach=True,
              auto_remove=True,
              name=self.config.CONTAINER_NAME,
              environment=self.db_environment,
              ports=self.db_ports,
          )
  
      def stop_if_running(self):
          if os.getenv("DR_LEAVE_DB", False):
              return
  
          try:
              running = self.docker_client.containers.get(self.config.CONTAINER_NAME)
              logger.info(f"Killing running container '{self.config.CONTAINER_NAME}'")
              running.stop()
          except Exception as e:
              if "404 Client Error: Not Found" in str(e):
                  return
              raise e
  
      def get_db_if_running(self):
          """Returns None or the db."""
          if os.getenv("DR_LEAVE_DB", False):
              return
  
          try:
              return self.docker_client.containers.get(self.config.CONTAINER_NAME)
          except Exception as e:
              if "404 Client Error: Not Found" in str(e):
                  return
  
  
  @pytest.fixture(scope="session", autouse=True)
  def run_the_database(autouse=True):
      postgres = PostgreSQLContainer()
      yield postgres.start_container()
      postgres.stop_if_running()
  
  
  def delete_migration_artifacts():
      logger.info("Deleting migration artifacts...")
      rootdir = os.path.abspath("./migrations/versions")
  
      for file in os.listdir(os.fsencode(rootdir)):
          filename = os.fsdecode(file)
          if "000000000000_create_table_checksum_and_logs.py" in filename:
              continue
  
          if filename.endswith(".py"):
              os.remove(os.path.join(rootdir, filename))
          else:
              continue
  
  
  class UpgradeFail(Exception):
      pass
  
  
  class Client:
      def __init__(self, schema_dicts=None):
          if schema_dicts is not None and not isinstance(schema_dicts, list):
              schema_dicts = [schema_dicts]
  
          self.schema_dicts = schema_dicts
  
          if len(self.schema_dicts) == 0:
              raise RuntimeError("Need at least one schema dict for test client")
  
      def start(self):
          delete_migration_artifacts()
  
          self.initialize_test_client()
  
          try:
              self.upgrade_loop()
          except UpgradeFail:
              logger.exception("Failed to upgrade database.")
  
      def get_test_client(self):
          return self.app.test_client()
  
      def initialize_test_client(self):
          self.data_resource_manager = DataResourceManagerSync(
              use_local_dirs=False, descriptors=self.schema_dicts
          )
          self.app = self.data_resource_manager.create_app()
  
          self.data_model_manager = DataModelManagerSync(
              use_local_dirs=False, descriptors=self.schema_dicts
          )
  
      def upgrade_loop(self):
          upgraded = False
          self.counter = 1
          self.counter_max = 10
          exponential_time = exponential_backoff(0.1, 1.05)
  
          while not upgraded and self.counter <= self.counter_max:
              try:
                  with self.app.app_context():
                      logger.info("------------- running upgrade")
                      self.data_model_manager.run(True)
                      self.data_resource_manager.run(True)
                      upgraded = True
                      return True
  
              except Exception:
                  logger.exception("Failed to upgrade client")
  
                  sleep_time = exponential_time()
                  logger.info(
                      f"Not upgraded, sleeping {sleep_time} seconds... {self.counter}/{self.counter_max} time(s)"
                  )
  
                  self.counter += 1
                  sleep(sleep_time)
  
          if self.counter > self.counter_max:
              logger.info("Max fail reached; stopping postgres container")
              raise UpgradeFail
  
      def clear_database(self):
          import contextlib
          from data_resource_api.db.base import Base, engine
  
          with contextlib.closing(engine.connect()) as con:
              trans = con.begin()
              for table in reversed(Base.metadata.sorted_tables):
                  con.execute(table.delete())
              trans.commit()
  
      def stop_container(self):
          from data_resource_api.db.base import Base, engine
  
          delete_migration_artifacts()
          Base.metadata.drop_all(engine)
          with engine.connect() as con:
              con.execute("DROP TABLE alembic_version")
  
  
  def setup_client(descriptors: list):
      client = Client(descriptors)
      client.start()
      yield client
      client.stop_container()
  
  
  def clear_db_and_get_test_client(client):
      client.clear_database()
      yield client.get_test_client()
  
  
  @pytest.fixture(scope="module")
  def _regular_client():
      """Setup the PostgreSQL database instance and run migrations.
  
      Returns:
          client (object): The Flask test client for the application.
      """
      yield from setup_client([credentials_descriptor, programs_descriptor])
  
  
  @pytest.fixture(scope="function")
  def regular_client(_regular_client):
      yield from clear_db_and_get_test_client(_regular_client)
  
  
  @pytest.fixture(scope="module")
  def _frameworks_skills_client():
      yield from setup_client([frameworks_descriptor, skills_descriptor])
  
  
  @pytest.fixture(scope="function")
  def frameworks_skills_client(_frameworks_skills_client):
      yield from clear_db_and_get_test_client(_frameworks_skills_client)
  
  
  @pytest.fixture(scope="module")
  def _json_client():
      yield from setup_client([json_descriptor])
  
  
  @pytest.fixture(scope="function")
  def json_client(_json_client):
      yield from clear_db_and_get_test_client(_json_client)
  
  
  @pytest.fixture(scope="module")
  def _everything_client():
      yield from setup_client([everything_descriptor])
  
  
  @pytest.fixture(scope="function")
  def everything_client(_everything_client):
      yield from clear_db_and_get_test_client(_everything_client)
  
  
  @pytest.fixture
  def base():
      JuncHolder.reset()
      base = declarative_base()
      yield base
      del base
  