# Path: postgraas_server/create_app.py
# def create_app(config):
#     app = Flask(__name__)
# 
#     app.config['SQLALCHEMY_DATABASE_URI'] = get_meta_db_config_path(config)
#     app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#     app.config['BUNDLE_ERRORS'] = True
#     app_config = get_application_config(config)
# 
#     for key in app_config:
#         app.config[key.upper()] = int(app_config[key]) if key.upper() in INT_OPTIONS else app_config[key]
#     app.config['SENTRY_INCLUDE_PATHS'] = [
#         'postgraas_server',
#     ]
#     app.config['SENTRY_RELEASE'] = postgraas_server.__version__
#     sentry.init_app(app)
# 
#     restful_api = Api(app)
#     restful_api.add_resource(DBInstanceResource, "/api/v2/postgraas_instances/<int:id>")
#     restful_api.add_resource(DBInstanceCollectionResource, "/api/v2/postgraas_instances")
#     db.init_app(app)
#     app.postgraas_backend = get_backend(config)
# 
#     @app.route('/health')
#     def health():
#         return "ok"
# 
#     return app
# 
# Path: postgraas_server/management_database.py
# def is_sane_database(Base, session):  # pragma: no cover
#     """
#     from: http://stackoverflow.com/questions/30428639/check-database-schema-matches-sqlalchemy-models-on-application-startup
#     Check whether the current database matches the models declared in model base.
# 
#     Currently we check that all tables exist with all columns. What is not checked
# 
#     * Column types are not verified
# 
#     * Relationships are not verified at all (TODO)
# 
#     :param Base: Declarative Base for SQLAlchemy models to check
# 
#     :param session: SQLAlchemy session bound to an engine
# 
#     :return: True if all declared models have corresponding tables and columns.
#     """
#     engine = session.get_bind()
#     iengine = inspect(engine)
#     errors = False
#     tables = iengine.get_table_names()
# 
#     # Go through all SQLAlchemy models
#     for name, klass in Base._decl_class_registry.items():
#         if isinstance(klass, _ModuleMarker):
#             # Not a model
#             continue
#         table = klass.__tablename__
#         if table in tables:
#             # Check all columns are found
#             # Looks like [{'default': "nextval('sanity_check_test_id_seq'::regclass)", 'autoincrement': True, 'nullable': False, 'type': INTEGER(), 'name': 'id'}]
#             columns = [c["name"] for c in iengine.get_columns(table)]
#             mapper = inspect(klass)
#             for column_prop in mapper.attrs:
#                 if isinstance(column_prop, RelationshipProperty):
#                     # TODO: Add sanity checks for relations
#                     pass
#                 else:
#                     for column in column_prop.columns:
#                         # Assume normal flat column
#                         if column.key not in columns:
#                             logger.error(
#                                 "Model %s declares column %s which does not exist in database %s",
#                                 klass, column.key, engine
#                             )
#                             errors = True
#         else:
#             logger.error(
#                 "Model %s declares table %s which does not exist in database %s", klass, table,
#                 engine
#             )
#             errors = True
#     return not errors


import unittest
import os
import postgraas_server.configuration as configuration
from postgraas_server.create_app import create_app
from postgraas_server.management_database import is_sane_database
        from postgraas_server.management_resources import db
        from postgraas_server.management_resources import db
        from postgraas_server.management_resources import db




class TestManagementDatabase(unittest.TestCase):
    def setUp(self):
        self.module_path = os.path.abspath(os.path.dirname(__file__))
        self.this_app = create_app(
            configuration.get_config(os.path.join(self.module_path, 'application.cfg'))
        )
        self.this_app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite://"
        self.this_app.use_reloader = False
        self.this_app.config['TESTING'] = True

    def tearDown(self):
        with self.this_app.app_context():
            db.drop_all()

    def test_is_sane_database(self):
        with self.this_app.app_context():
            db.drop_all()
            db.create_all()
            is_sane = is_sane_database(db.Model, db.session)

        self.assertEqual(True, is_sane)

    def test_is_not_sane_database(self):
        with self.this_app.app_context():

# Path: postgraas_server/create_app.py
# def create_app(config):
#     app = Flask(__name__)
# 
#     app.config['SQLALCHEMY_DATABASE_URI'] = get_meta_db_config_path(config)
#     app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#     app.config['BUNDLE_ERRORS'] = True
#     app_config = get_application_config(config)
# 
#     for key in app_config:
#         app.config[key.upper()] = int(app_config[key]) if key.upper() in INT_OPTIONS else app_config[key]
#     app.config['SENTRY_INCLUDE_PATHS'] = [
#         'postgraas_server',
#     ]
#     app.config['SENTRY_RELEASE'] = postgraas_server.__version__
#     sentry.init_app(app)
# 
#     restful_api = Api(app)
#     restful_api.add_resource(DBInstanceResource, "/api/v2/postgraas_instances/<int:id>")
#     restful_api.add_resource(DBInstanceCollectionResource, "/api/v2/postgraas_instances")
#     db.init_app(app)
#     app.postgraas_backend = get_backend(config)
# 
#     @app.route('/health')
#     def health():
#         return "ok"
# 
#     return app
# 
# Path: postgraas_server/management_database.py
# def is_sane_database(Base, session):  # pragma: no cover
#     """
#     from: http://stackoverflow.com/questions/30428639/check-database-schema-matches-sqlalchemy-models-on-application-startup
#     Check whether the current database matches the models declared in model base.
# 
#     Currently we check that all tables exist with all columns. What is not checked
# 
#     * Column types are not verified
# 
#     * Relationships are not verified at all (TODO)
# 
#     :param Base: Declarative Base for SQLAlchemy models to check
# 
#     :param session: SQLAlchemy session bound to an engine
# 
#     :return: True if all declared models have corresponding tables and columns.
#     """
#     engine = session.get_bind()
#     iengine = inspect(engine)
#     errors = False
#     tables = iengine.get_table_names()
# 
#     # Go through all SQLAlchemy models
#     for name, klass in Base._decl_class_registry.items():
#         if isinstance(klass, _ModuleMarker):
#             # Not a model
#             continue
#         table = klass.__tablename__
#         if table in tables:
#             # Check all columns are found
#             # Looks like [{'default': "nextval('sanity_check_test_id_seq'::regclass)", 'autoincrement': True, 'nullable': False, 'type': INTEGER(), 'name': 'id'}]
#             columns = [c["name"] for c in iengine.get_columns(table)]
#             mapper = inspect(klass)
#             for column_prop in mapper.attrs:
#                 if isinstance(column_prop, RelationshipProperty):
#                     # TODO: Add sanity checks for relations
#                     pass
#                 else:
#                     for column in column_prop.columns:
#                         # Assume normal flat column
#                         if column.key not in columns:
#                             logger.error(
#                                 "Model %s declares column %s which does not exist in database %s",
#                                 klass, column.key, engine
#                             )
#                             errors = True
#         else:
#             logger.error(
#                 "Model %s declares table %s which does not exist in database %s", klass, table,
#                 engine
#             )
#             errors = True
#     return not errors


# Path: tests/test_integration/test_management_database.py
import unittest
import os
import postgraas_server.configuration as configuration
from postgraas_server.create_app import create_app
from postgraas_server.management_database import is_sane_database
        from postgraas_server.management_resources import db
        from postgraas_server.management_resources import db
        from postgraas_server.management_resources import db





class TestManagementDatabase(unittest.TestCase):
    def setUp(self):
        self.module_path = os.path.abspath(os.path.dirname(__file__))
        self.this_app = create_app(
            configuration.get_config(os.path.join(self.module_path, 'application.cfg'))
        )
        self.this_app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite://"
        self.this_app.use_reloader = False
        self.this_app.config['TESTING'] = True

    def tearDown(self):
        with self.this_app.app_context():
            db.drop_all()

    def test_is_sane_database(self):
        with self.this_app.app_context():
            db.drop_all()
            db.create_all()
            is_sane = is_sane_database(db.Model, db.session)

        self.assertEqual(True, is_sane)

    def test_is_not_sane_database(self):
        with self.this_app.app_context():

            is_sane = is_sane_database(db.Model, db.session)