Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add E2E test for converting boolean type to text type #1182

Closed

Conversation

sahilsaini1107
Copy link
Contributor

@sahilsaini1107 sahilsaini1107 commented Mar 16, 2022

Fixes #1127

Added E2E test to convert col type from boolean to text type.
Technical details

Screenshots

Additional Context

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the master branch of the repository
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no
    visible errors.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@sahilsaini1107 sahilsaini1107 requested review from a team, seancolsen and dmos62 March 16, 2022 11:37
@codecov-commenter
Copy link

Codecov Report

Merging #1182 (0e78e89) into master (2191fb4) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master    #1182   +/-   ##
=======================================
  Coverage   93.39%   93.39%           
=======================================
  Files         113      113           
  Lines        4332     4332           
=======================================
  Hits         4046     4046           
  Misses        286      286           
Flag Coverage Δ
pytest-backend 93.39% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2191fb4...0e78e89. Read the comment docs.

@sahilsaini1107
Copy link
Contributor Author

''' statement = "\n SELECT c.oid\n FROM pg_catalog.pg_class c\n LEFT JOIN pg_catalog.pg_namespace n O...(c.oid))\n AND c.relname = %(table_name)s AND c.relkind in\n ('r', 'v', 'm', 'f', 'p')\n "
parameters = {'table_name': 'pg_namespace'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f7697b222b0>

def do_execute(self, cursor, statement, parameters, context=None):
  cursor.execute(statement, parameters)

E sqlalchemy.exc.OperationalError: (psycopg2.errors.AdminShutdown) terminating connection due to administrator command
E server closed the connection unexpectedly
E This probably means the server terminated abnormally
E before or while processing the request.
E
E [SQL:
E SELECT c.oid
E FROM pg_catalog.pg_class c
E LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
E WHERE (pg_catalog.pg_table_is_visible(c.oid))
E AND c.relname = %(table_name)s AND c.relkind in
E ('r', 'v', 'm', 'f', 'p')
E ]
E [parameters: {'table_name': 'pg_namespace'}]
E (Background on this error at: http://sqlalche.me/e/14/e3q8)

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:717: OperationalError
____________________ ERROR at setup of test_tabs[chromium] _____________________

self = Engine(postgresql://mathesar:***@mathesar_db/mathesar_db_test)
fn = <bound method Pool.connect of <sqlalchemy.pool.impl.QueuePool object at 0x7f76afd938e0>>
connection = None

def _wrap_pool_connect(self, fn, connection):
    dialect = self.dialect
    try:
      return fn()

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:3211:


self = <sqlalchemy.pool.impl.QueuePool object at 0x7f76afd938e0>

def connect(self):
    """Return a DBAPI connection from the pool.

    The connection is instrumented such that when its
    ``close()`` method is called, the connection will be returned to
    the pool.

    """
  return _ConnectionFairy._checkout(self)

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:307:


cls = <class 'sqlalchemy.pool.base._ConnectionFairy'>
pool = <sqlalchemy.pool.impl.QueuePool object at 0x7f76afd938e0>
threadconns = None, fairy = None

@classmethod
def _checkout(cls, pool, threadconns=None, fairy=None):
    if not fairy:
      fairy = _ConnectionRecord.checkout(pool)

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:767:


cls = <class 'sqlalchemy.pool.base._ConnectionRecord'>
pool = <sqlalchemy.pool.impl.QueuePool object at 0x7f76afd938e0>

@classmethod
def checkout(cls, pool):
    rec = pool._do_get()
    try:
        dbapi_connection = rec.get_connection()
    except Exception as err:
        with util.safe_reraise():
          rec._checkin_failed(err, _fairy_was_created=False)

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:430:


self = <sqlalchemy.util.langhelpers.safe_reraise object at 0x7f7697ba8940>
type_ = None, value = None, traceback = None

def __exit__(self, type_, value, traceback):
    # see #2703 for notes
    if type_ is None:
        exc_type, exc_value, exc_tb = self._exc_info
        self._exc_info = None  # remove potential circular references
        if not self.warn_only:
          compat.raise_(
                exc_value,
                with_traceback=exc_tb,
            )

/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py:70:


def raise_(
    exception, with_traceback=None, replace_context=None, from_=False
):
    r"""implement "raise" with cause support.

    :param exception: exception to raise
    :param with_traceback: will call exception.with_traceback()
    :param replace_context: an as-yet-unsupported feature.  This is
     an exception object which we are "replacing", e.g., it's our
     "cause" but we don't want it printed.    Basically just what
     ``__suppress_context__`` does but we don't want to suppress
     the enclosing context, if any.  So for now we make it the
     cause.
    :param from\_: the cause.  this actually sets the cause and doesn't
     hope to hide it someday.

    """
    if with_traceback is not None:
        exception = exception.with_traceback(with_traceback)

    if from_ is not False:
        exception.__cause__ = from_
    elif replace_context is not None:
        # no good solution here, we would like to have the exception
        # have only the context of replace_context.__context__ so that the
        # intermediary exception does not change, but we can't figure
        # that out.
        exception.__cause__ = replace_context

    try:
      raise exception

/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:207:


cls = <class 'sqlalchemy.pool.base._ConnectionRecord'>
pool = <sqlalchemy.pool.impl.QueuePool object at 0x7f76afd938e0>

@classmethod
def checkout(cls, pool):
    rec = pool._do_get()
    try:
      dbapi_connection = rec.get_connection()

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:427:


self = <sqlalchemy.pool.base._ConnectionRecord object at 0x7f76ae6160d0>

def get_connection(self):
    recycle = False

    # NOTE: the various comparisons here are assuming that measurable time
    # passes between these state changes.  however, time.time() is not
    # guaranteed to have sub-second precision.  comparisons of
    # "invalidation time" to "starttime" should perhaps use >= so that the
    # state change can take place assuming no measurable  time has passed,
    # however this does not guarantee correct behavior here as if time
    # continues to not pass, it will try to reconnect repeatedly until
    # these timestamps diverge, so in that sense using > is safer.  Per
    # https://stackoverflow.com/a/1938096/34549, Windows time.time() may be
    # within 16 milliseconds accuracy, so unit tests for connection
    # invalidation need a sleep of at least this long between initial start
    # time and invalidation for the logic below to work reliably.
    if self.connection is None:
        self.info.clear()
      self.__connect()

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:552:


self = <sqlalchemy.pool.base._ConnectionRecord object at 0x7f76ae6160d0>

def __connect(self):
    pool = self.__pool

    # ensure any existing connection is removed, so that if
    # creator fails, this attribute stays None
    self.connection = None
    try:
        self.starttime = time.time()
        connection = pool._invoke_creator(self)
        pool.logger.debug("Created new connection %r", connection)
        self.connection = connection
        self.fresh = True
    except Exception as e:
        with util.safe_reraise():
          pool.logger.debug("Error on connect(): %s", e)

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:611:


self = <sqlalchemy.util.langhelpers.safe_reraise object at 0x7f7697ba8a60>
type_ = None, value = None, traceback = None

def __exit__(self, type_, value, traceback):
    # see #2703 for notes
    if type_ is None:
        exc_type, exc_value, exc_tb = self._exc_info
        self._exc_info = None  # remove potential circular references
        if not self.warn_only:
          compat.raise_(
                exc_value,
                with_traceback=exc_tb,
            )

/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py:70:


def raise_(
    exception, with_traceback=None, replace_context=None, from_=False
):
    r"""implement "raise" with cause support.

    :param exception: exception to raise
    :param with_traceback: will call exception.with_traceback()
    :param replace_context: an as-yet-unsupported feature.  This is
     an exception object which we are "replacing", e.g., it's our
     "cause" but we don't want it printed.    Basically just what
     ``__suppress_context__`` does but we don't want to suppress
     the enclosing context, if any.  So for now we make it the
     cause.
    :param from\_: the cause.  this actually sets the cause and doesn't
     hope to hide it someday.

    """
    if with_traceback is not None:
        exception = exception.with_traceback(with_traceback)

    if from_ is not False:
        exception.__cause__ = from_
    elif replace_context is not None:
        # no good solution here, we would like to have the exception
        # have only the context of replace_context.__context__ so that the
        # intermediary exception does not change, but we can't figure
        # that out.
        exception.__cause__ = replace_context

    try:
      raise exception

/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:207:


self = <sqlalchemy.pool.base._ConnectionRecord object at 0x7f76ae6160d0>

def __connect(self):
    pool = self.__pool

    # ensure any existing connection is removed, so that if
    # creator fails, this attribute stays None
    self.connection = None
    try:
        self.starttime = time.time()
      connection = pool._invoke_creator(self)

/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:605:


connection_record = <sqlalchemy.pool.base._ConnectionRecord object at 0x7f76ae6160d0>

def connect(connection_record=None):
    if dialect._has_events:
        for fn in dialect.dispatch.do_connect:
            connection = fn(dialect, connection_record, cargs, cparams)
            if connection is not None:
                return connection
  return dialect.connect(*cargs, **cparams)

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/create.py:578:


self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f76afd93580>
cargs = ()
cparams = {'database': 'mathesar_db_test', 'host': 'mathesar_db', 'options': '-c timezone=utc -c lc_monetary=en_US.UTF-8', 'password': 'mathesar', ...}

def connect(self, *cargs, **cparams):
    # inherits the docstring from interfaces.Dialect.connect
  return self.dbapi.connect(*cargs, **cparams)

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:584:


dsn = "host=mathesar_db user=mathesar password=mathesar options='-c timezone=utc -c lc_monetary=en_US.UTF-8' dbname=mathesar_db_test"
connection_factory = None, cursor_factory = None
kwargs = {'database': 'mathesar_db_test', 'host': 'mathesar_db', 'options': '-c timezone=utc -c lc_monetary=en_US.UTF-8', 'password': 'mathesar', ...}
kwasync = {}

def connect(dsn=None, connection_factory=None, cursor_factory=None, **kwargs):
    """
    Create a new database connection.

    The connection parameters can be specified as a string:

        conn = psycopg2.connect("dbname=test user=postgres password=secret")

    or using a set of keyword arguments:

        conn = psycopg2.connect(database="test", user="postgres", password="secret")

    Or as a mix of both. The basic connection parameters are:

    - *dbname*: the database name
    - *database*: the database name (only as keyword argument)
    - *user*: user name used to authenticate
    - *password*: password used to authenticate
    - *host*: database host address (defaults to UNIX socket if not provided)
    - *port*: connection port number (defaults to 5432 if not provided)

    Using the *connection_factory* parameter a different class or connections
    factory can be specified. It should be a callable object taking a dsn
    argument.

    Using the *cursor_factory* parameter, a new default cursor factory will be
    used by cursor().

    Using *async*=True an asynchronous connection will be created. *async_* is
    a valid alias (for Python versions where ``async`` is a keyword).

    Any other keyword parameter will be passed to the underlying client
    library: the list of supported parameters depends on the library version.

    """
    kwasync = {}
    if 'async' in kwargs:
        kwasync['async'] = kwargs.pop('async')
    if 'async_' in kwargs:
        kwasync['async_'] = kwargs.pop('async_')

    if dsn is None and not kwargs:
        raise TypeError('missing dsn and no parameters')

    dsn = _ext.make_dsn(dsn, **kwargs)
  conn = _connect(dsn, connection_factory=connection_factory, **kwasync)

E psycopg2.OperationalError: FATAL: database "mathesar_db_test" does not exist

/usr/local/lib/python3.9/site-packages/psycopg2/init.py:127: OperationalError

The above exception was the direct cause of the following exception:

create_schema = <function create_schema.._create_schema at 0x7f76ac24bee0>
schema_name = 'table_tests'

@pytest.fixture
def schema(create_schema, schema_name):
  return create_schema(schema_name)

mathesar/tests/integration/conftest.py:65:


mathesar/tests/integration/conftest.py:43: in _create_schema
create_sa_schema(schema_name, engine)
db/schemas/operations/create.py:10: in create_schema
if schema not in get_all_schemas(engine):
db/schemas/utils.py:19: in get_all_schemas
inspector = inspect(engine)
/usr/local/lib/python3.9/site-packages/sqlalchemy/inspection.py:64: in inspect
ret = reg(subject)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py:182: in _engine_insp
return Inspector._construct(Inspector._init_engine, bind)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py:117: in _construct
init(self, bind)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py:128: in _init_engine
engine.connect().close()
/usr/local/lib/python3.9/site-packages/sqlalchemy/future/engine.py:419: in connect
return super(Engine, self).connect()
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:3165: in connect
return self._connection_cls(self, close_with_result=close_with_result)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:96: in init
else engine.raw_connection()
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:3244: in raw_connection
return self._wrap_pool_connect(self.pool.connect, _connection)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:3214: in _wrap_pool_connect
Connection.handle_dbapi_exception_noconnection(
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:2068: in handle_dbapi_exception_noconnection
util.raise
(
/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:207: in raise

raise exception
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:3211: in _wrap_pool_connect
return fn()
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:307: in connect
return _ConnectionFairy._checkout(self)
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:767: in _checkout
fairy = _ConnectionRecord.checkout(pool)
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:430: in checkout
rec.checkin_failed(err, fairy_was_created=False)
/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py:70: in exit
compat.raise
(
/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:207: in raise

raise exception
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:427: in checkout
dbapi_connection = rec.get_connection()
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:552: in get_connection
self.__connect()
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:611: in connect
pool.logger.debug("Error on connect(): %s", e)
/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py:70: in exit
compat.raise
(
/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:207: in raise

raise exception
/usr/local/lib/python3.9/site-packages/sqlalchemy/pool/base.py:605: in __connect
connection = pool._invoke_creator(self)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/create.py:578: in connect
return dialect.connect(*cargs, **cparams)
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:584: in connect
return self.dbapi.connect(*cargs, **cparams)


dsn = "host=mathesar_db user=mathesar password=mathesar options='-c timezone=utc -c lc_monetary=en_US.UTF-8' dbname=mathesar_db_test"
connection_factory = None, cursor_factory = None
kwargs = {'database': 'mathesar_db_test', 'host': 'mathesar_db', 'options': '-c timezone=utc -c lc_monetary=en_US.UTF-8', 'password': 'mathesar', ...}
kwasync = {}

def connect(dsn=None, connection_factory=None, cursor_factory=None, **kwargs):
    """
    Create a new database connection.

    The connection parameters can be specified as a string:

        conn = psycopg2.connect("dbname=test user=postgres password=secret")

    or using a set of keyword arguments:

        conn = psycopg2.connect(database="test", user="postgres", password="secret")

    Or as a mix of both. The basic connection parameters are:

    - *dbname*: the database name
    - *database*: the database name (only as keyword argument)
    - *user*: user name used to authenticate
    - *password*: password used to authenticate
    - *host*: database host address (defaults to UNIX socket if not provided)
    - *port*: connection port number (defaults to 5432 if not provided)

    Using the *connection_factory* parameter a different class or connections
    factory can be specified. It should be a callable object taking a dsn
    argument.

    Using the *cursor_factory* parameter, a new default cursor factory will be
    used by cursor().

    Using *async*=True an asynchronous connection will be created. *async_* is
    a valid alias (for Python versions where ``async`` is a keyword).

    Any other keyword parameter will be passed to the underlying client
    library: the list of supported parameters depends on the library version.

    """
    kwasync = {}
    if 'async' in kwargs:
        kwasync['async'] = kwargs.pop('async')
    if 'async_' in kwargs:
        kwasync['async_'] = kwargs.pop('async_')

    if dsn is None and not kwargs:
        raise TypeError('missing dsn and no parameters')

    dsn = _ext.make_dsn(dsn, **kwargs)
  conn = _connect(dsn, connection_factory=connection_factory, **kwasync)

E sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL: database "mathesar_db_test" does not exist
E
E (Background on this error at: http://sqlalche.me/e/14/e3q8)

/usr/local/lib/python3.9/site-packages/psycopg2/init.py:127: OperationalError
___________________ ERROR at teardown of test_tabs[chromium] ___________________

self = <sqlalchemy.future.engine.Connection object at 0x7f76afa312b0>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f76afe78880>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'DROP DATABASE mathesar_db_test WITH (FORCE)', parameters = {}
execution_options = immutabledict({'autocommit': symbol('PARSE_AUTOCOMMIT'), 'isolation_level': 'AUTOCOMMIT'})
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0x7f76ac894a00>, [], <sqlalchemy.sql.elements.TextClause object at 0x7f76afe787c0>, [])
kw = {'cache_hit': symbol('CACHE_MISS')}
branched = <sqlalchemy.future.engine.Connection object at 0x7f76afa312b0>
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0x7f76ae8afa60>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f76ac407bb0>
cursor = <cursor object at 0x7f76ac63f040; closed: -1>, evt_handled = False

def _execute_context(
    self,
    dialect,
    constructor,
    statement,
    parameters,
    execution_options,
    *args,
    **kw
):
    """Create an :class:`.ExecutionContext` and execute, returning
    a :class:`_engine.CursorResult`."""

    branched = self
    if self.__branch_from:
        # if this is a "branched" connection, do everything in terms
        # of the "root" connection, *except* for .close(), which is
        # the only feature that branching provides
        self = self.__branch_from

    try:
        conn = self._dbapi_connection
        if conn is None:
            conn = self._revalidate_connection()

        context = constructor(
            dialect, self, conn, execution_options, *args, **kw
        )
    except (exc.PendingRollbackError, exc.ResourceClosedError):
        raise
    except BaseException as e:
        self._handle_dbapi_exception(
            e, util.text_type(statement), parameters, None, None
        )

    if (
        self._transaction
        and not self._transaction.is_active
        or (
            self._nested_transaction
            and not self._nested_transaction.is_active
        )
    ):
        self._invalid_transaction()

    elif self._trans_context_manager:
        TransactionalContext._trans_ctx_check(self)

    if self._is_future and self._transaction is None:
        self._autobegin()

    context.pre_exec()

    if dialect.use_setinputsizes:
        context._set_input_sizes()

    cursor, statement, parameters = (
        context.cursor,
        context.statement,
        context.parameters,
    )

    if not context.executemany:
        parameters = parameters[0]

    if self._has_events or self.engine._has_events:
        for fn in self.dispatch.before_cursor_execute:
            statement, parameters = fn(
                self,
                cursor,
                statement,
                parameters,
                context,
                context.executemany,
            )

    if self._echo:

        self._log_info(statement)

        stats = context._get_cache_stats()

        if not self.engine.hide_parameters:
            self._log_info(
                "[%s] %r",
                stats,
                sql_util._repr_params(
                    parameters, batches=10, ismulti=context.executemany
                ),
            )
        else:
            self._log_info(
                "[%s] [SQL parameters hidden due to hide_parameters=True]"
                % (stats,)
            )

    evt_handled = False
    try:
        if context.executemany:
            if self.dialect._has_events:
                for fn in self.dialect.dispatch.do_executemany:
                    if fn(cursor, statement, parameters, context):
                        evt_handled = True
                        break
            if not evt_handled:
                self.dialect.do_executemany(
                    cursor, statement, parameters, context
                )
        elif not parameters and context.no_parameters:
            if self.dialect._has_events:
                for fn in self.dialect.dispatch.do_execute_no_params:
                    if fn(cursor, statement, context):
                        evt_handled = True
                        break
            if not evt_handled:
                self.dialect.do_execute_no_params(
                    cursor, statement, context
                )
        else:
            if self.dialect._has_events:
                for fn in self.dialect.dispatch.do_execute:
                    if fn(cursor, statement, parameters, context):
                        evt_handled = True
                        break
            if not evt_handled:
              self.dialect.do_execute(
                    cursor, statement, parameters, context
                )

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1770:


self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f76afe78880>
cursor = <cursor object at 0x7f76ac63f040; closed: -1>
statement = 'DROP DATABASE mathesar_db_test WITH (FORCE)', parameters = {}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f76ac407bb0>

def do_execute(self, cursor, statement, parameters, context=None):
  cursor.execute(statement, parameters)

E psycopg2.errors.InvalidCatalogName: database "mathesar_db_test" does not exist

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:717: InvalidCatalogName

The above exception was the direct cause of the following exception:

@pytest.fixture(scope="session", autouse=True)
def test_db():
    superuser_engine = _get_superuser_engine()
    with superuser_engine.connect() as conn:
        conn.execution_options(isolation_level="AUTOCOMMIT")
        conn.execute(text(f"DROP DATABASE IF EXISTS {TEST_DB} WITH (FORCE)"))
        conn.execute(text(f"CREATE DATABASE {TEST_DB}"))
    yield TEST_DB
    with superuser_engine.connect() as conn:
        conn.execution_options(isolation_level="AUTOCOMMIT")
      conn.execute(text(f"DROP DATABASE {TEST_DB} WITH (FORCE)"))

conftest.py:28:


/usr/local/lib/python3.9/site-packages/sqlalchemy/future/engine.py:280: in execute
return self._execute_20(
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1582: in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:324: in _execute_on_connection
return connection._execute_clauseelement(
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1451: in _execute_clauseelement
ret = self._execute_context(
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1813: in _execute_context
self.handle_dbapi_exception(
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1994: in handle_dbapi_exception
util.raise
(
/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:207: in raise

raise exception
/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1770: in _execute_context
self.dialect.do_execute(


self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f76afe78880>
cursor = <cursor object at 0x7f76ac63f040; closed: -1>
statement = 'DROP DATABASE mathesar_db_test WITH (FORCE)', parameters = {}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f76ac407bb0>

def do_execute(self, cursor, statement, parameters, context=None):
  cursor.execute(statement, parameters)

E sqlalchemy.exc.ProgrammingError: (psycopg2.errors.InvalidCatalogName) database "mathesar_db_test" does not exist
E
E [SQL: DROP DATABASE mathesar_db_test WITH (FORCE)]
E (Background on this error at: http://sqlalche.me/e/14/f405)

/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:717: ProgrammingError
=================================== FAILURES ===================================
_____________________ test_import_from_clipboard[chromium] _____________________

page =
base_schema_url = 'http://localhost:39389/mathesar_db_test/8'

def test_import_from_clipboard(page, base_schema_url):
    page.goto(base_schema_url)
    expect(get_tables_list(page)).to_be_empty()
  page.click("[aria-label='New Table']")

mathesar/tests/integration/test_imports.py:9:


/usr/local/lib/python3.9/site-packages/playwright/sync_api/_generated.py:7985: in click
self._sync(
/usr/local/lib/python3.9/site-packages/playwright/_impl/_sync_base.py:111: in _sync
return task.result()
/usr/local/lib/python3.9/site-packages/playwright/_impl/_page.py:644: in click
return await self._main_frame.click(**locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_frame.py:460: in click
await self._channel.send("click", locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:39: in send
return await self.inner_send(method, params, False)


self = <playwright._impl._connection.Channel object at 0x7f76ac512460>
method = 'click', params = {'selector': "[aria-label='New Table']"}
return_as_dict = False

async def inner_send(
    self, method: str, params: Optional[Dict], return_as_dict: bool
) -> Any:
    if params is None:
        params = {}
    callback = self._connection._send_message_to_server(self._guid, method, params)
    if self._connection._error:
        error = self._connection._error
        self._connection._error = None
        raise error
    done, _ = await asyncio.wait(
        {
            self._connection._transport.on_error_future,
            callback.future,
        },
        return_when=asyncio.FIRST_COMPLETED,
    )
    if not callback.future.done():
        callback.future.cancel()
  result = next(iter(done)).result()

E playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
E =========================== logs ===========================
E waiting for selector "[aria-label='New Table']"
E selector resolved to visible <button type="button" aria-label="New Table" aria-haspop…>…
E attempting click action
E waiting for element to be visible, enabled and stable
E ============================================================

/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:63: TimeoutError
_______________________ test_import_from_file[chromium] ________________________

page =
base_schema_url = 'http://localhost:39389/mathesar_db_test/12'

def test_import_from_file(page, base_schema_url):
    page.goto(base_schema_url)
  page.click("[aria-label='New Table']")

mathesar/tests/integration/test_imports.py:20:


/usr/local/lib/python3.9/site-packages/playwright/sync_api/_generated.py:7985: in click
self._sync(
/usr/local/lib/python3.9/site-packages/playwright/_impl/_sync_base.py:111: in _sync
return task.result()
/usr/local/lib/python3.9/site-packages/playwright/_impl/_page.py:644: in click
return await self._main_frame.click(**locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_frame.py:460: in click
await self._channel.send("click", locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:39: in send
return await self.inner_send(method, params, False)


self = <playwright._impl._connection.Channel object at 0x7f76ac4243a0>
method = 'click', params = {'selector': "[aria-label='New Table']"}
return_as_dict = False

async def inner_send(
    self, method: str, params: Optional[Dict], return_as_dict: bool
) -> Any:
    if params is None:
        params = {}
    callback = self._connection._send_message_to_server(self._guid, method, params)
    if self._connection._error:
        error = self._connection._error
        self._connection._error = None
        raise error
    done, _ = await asyncio.wait(
        {
            self._connection._transport.on_error_future,
            callback.future,
        },
        return_when=asyncio.FIRST_COMPLETED,
    )
    if not callback.future.done():
        callback.future.cancel()
  result = next(iter(done)).result()

E playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
E =========================== logs ===========================
E waiting for selector "[aria-label='New Table']"
E selector resolved to visible <button type="button" aria-label="New Table" aria-haspop…>…
E attempting click action
E waiting for element to be visible, enabled and stable
E ============================================================

/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:63: TimeoutError
___________________ test_create_and_delete_schema[chromium] ____________________

page =
schemas_page_url = 'http://localhost:39389/mathesar_db_test/schemas/'

def test_create_and_delete_schema(page, schemas_page_url):
    page.goto(schemas_page_url)
    schema_name = "foo"
    schema_entry = page.locator(f".schema-list .schema-row:has-text('{schema_name}')")
    expect(schema_entry).not_to_be_visible()
  page.click("text=New Schema")

mathesar/tests/integration/test_schemas.py:9:


/usr/local/lib/python3.9/site-packages/playwright/sync_api/_generated.py:7985: in click
self._sync(
/usr/local/lib/python3.9/site-packages/playwright/_impl/_sync_base.py:111: in _sync
return task.result()
/usr/local/lib/python3.9/site-packages/playwright/_impl/_page.py:644: in click
return await self._main_frame.click(**locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_frame.py:460: in click
await self._channel.send("click", locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:39: in send
return await self.inner_send(method, params, False)


self = <playwright._impl._connection.Channel object at 0x7f76ac18d310>
method = 'click', params = {'selector': 'text=New Schema'}
return_as_dict = False

async def inner_send(
    self, method: str, params: Optional[Dict], return_as_dict: bool
) -> Any:
    if params is None:
        params = {}
    callback = self._connection._send_message_to_server(self._guid, method, params)
    if self._connection._error:
        error = self._connection._error
        self._connection._error = None
        raise error
    done, _ = await asyncio.wait(
        {
            self._connection._transport.on_error_future,
            callback.future,
        },
        return_when=asyncio.FIRST_COMPLETED,
    )
    if not callback.future.done():
        callback.future.cancel()
  result = next(iter(done)).result()

E playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
E =========================== logs ===========================
E waiting for selector "text=New Schema"
E selector resolved to visible <button type="button" class="btn btn-default size-medium…>…
E attempting click action
E waiting for element to be visible, enabled and stable
E ============================================================

/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:63: TimeoutError
______________________ test_create_empty_table[chromium] _______________________

page =
base_schema_url = 'http://localhost:39389/mathesar_db_test/32'

def test_create_empty_table(page, base_schema_url):
    page.goto(base_schema_url)
    expect(get_tables_list(page)).to_be_empty()
  page.click("[aria-label='New Table']")

mathesar/tests/integration/test_tables.py:9:


/usr/local/lib/python3.9/site-packages/playwright/sync_api/_generated.py:7985: in click
self._sync(
/usr/local/lib/python3.9/site-packages/playwright/_impl/_sync_base.py:111: in _sync
return task.result()
/usr/local/lib/python3.9/site-packages/playwright/_impl/_page.py:644: in click
return await self._main_frame.click(**locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_frame.py:460: in click
await self._channel.send("click", locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:39: in send
return await self.inner_send(method, params, False)


self = <playwright._impl._connection.Channel object at 0x7f76ac5697c0>
method = 'click', params = {'selector': "[aria-label='New Table']"}
return_as_dict = False

async def inner_send(
    self, method: str, params: Optional[Dict], return_as_dict: bool
) -> Any:
    if params is None:
        params = {}
    callback = self._connection._send_message_to_server(self._guid, method, params)
    if self._connection._error:
        error = self._connection._error
        self._connection._error = None
        raise error
    done, _ = await asyncio.wait(
        {
            self._connection._transport.on_error_future,
            callback.future,
        },
        return_when=asyncio.FIRST_COMPLETED,
    )
    if not callback.future.done():
        callback.future.cancel()
  result = next(iter(done)).result()

E playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
E =========================== logs ===========================
E waiting for selector "[aria-label='New Table']"
E selector resolved to visible <button type="button" aria-label="New Table" aria-haspop…>…
E attempting click action
E waiting for element to be visible, enabled and stable
E ============================================================

/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:63: TimeoutError
_________________ test_rename_table_of_another_table[chromium] _________________

page =
base_schema_url = 'http://localhost:39389/mathesar_db_test/36'

def test_rename_table_of_another_table(page, base_schema_url):
    page.goto(base_schema_url)
    expect(get_tables_list(page)).to_be_empty()
  page.click("[aria-label='New Table']")

mathesar/tests/integration/test_tables.py:17:


/usr/local/lib/python3.9/site-packages/playwright/sync_api/_generated.py:7985: in click
self._sync(
/usr/local/lib/python3.9/site-packages/playwright/_impl/_sync_base.py:111: in _sync
return task.result()
/usr/local/lib/python3.9/site-packages/playwright/_impl/_page.py:644: in click
return await self._main_frame.click(**locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_frame.py:460: in click
await self._channel.send("click", locals_to_params(locals()))
/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:39: in send
return await self.inner_send(method, params, False)


self = <playwright._impl._connection.Channel object at 0x7f76ac7a0eb0>
method = 'click', params = {'selector': "[aria-label='New Table']"}
return_as_dict = False

async def inner_send(
    self, method: str, params: Optional[Dict], return_as_dict: bool
) -> Any:
    if params is None:
        params = {}
    callback = self._connection._send_message_to_server(self._guid, method, params)
    if self._connection._error:
        error = self._connection._error
        self._connection._error = None
        raise error
    done, _ = await asyncio.wait(
        {
            self._connection._transport.on_error_future,
            callback.future,
        },
        return_when=asyncio.FIRST_COMPLETED,
    )
    if not callback.future.done():
        callback.future.cancel()
  result = next(iter(done)).result()

E playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
E =========================== logs ===========================
E waiting for selector "[aria-label='New Table']"
E selector resolved to visible <button type="button" aria-label="New Table" aria-haspop…>…
E attempting click action
E waiting for element to be visible, enabled and stable
E ============================================================

/usr/local/lib/python3.9/site-packages/playwright/_impl/_connection.py:63: TimeoutError
=============================== warnings summary ===============================
../usr/local/lib/python3.9/site-packages/django/utils/version.py:98
/usr/local/lib/python3.9/site-packages/django/utils/version.py:98: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
loose_version = LooseVersion(version)

../usr/local/lib/python3.9/site-packages/rest_framework_friendly_errors/settings.py:18
/usr/local/lib/python3.9/site-packages/rest_framework_friendly_errors/settings.py:18: RemovedInDjango40Warning: django.utils.translation.ugettext_lazy() is deprecated in favor of django.utils.translation.gettext_lazy().
_('Validation Failed'))

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ============================
FAILED mathesar/tests/integration/test_imports.py::test_import_from_clipboard[chromium]
FAILED mathesar/tests/integration/test_imports.py::test_import_from_file[chromium]
FAILED mathesar/tests/integration/test_schemas.py::test_create_and_delete_schema[chromium]
FAILED mathesar/tests/integration/test_tables.py::test_create_empty_table[chromium]
FAILED mathesar/tests/integration/test_tables.py::test_rename_table_of_another_table[chromium]
ERROR mathesar/tests/integration/test_base_page.py::test_page_shows_welcome_text[chromium]
ERROR mathesar/tests/integration/test_columns.py::test_add_column[chromium]
ERROR mathesar/tests/integration/test_columns.py::test_convert_text_column_to_number[chromium]
ERROR mathesar/tests/integration/test_columns.py::test_convert_boolean_col_to_text_col[chromium]
ERROR mathesar/tests/integration/test_constraints.py::test_add_and_remove_multi_column_unique_constraint[chromium]
ERROR mathesar/tests/integration/test_constraints.py::test_add_and_remove_multi_column_unique_constraint[chromium]
ERROR mathesar/tests/integration/test_constraints.py::test_try_to_dissallow_null_for_column_with_null_values[chromium]
ERROR mathesar/tests/integration/test_records.py::test_add_row[chromium] - pl...
ERROR mathesar/tests/integration/test_records.py::test_add_row[chromium] - Ty...
ERROR mathesar/tests/integration/test_records.py::test_sort_table_by_column[chromium]
ERROR mathesar/tests/integration/test_records.py::test_increment_pagination[chromium]
ERROR mathesar/tests/integration/test_records.py::test_edit_cell[chromium] - ...
ERROR mathesar/tests/integration/test_records.py::test_delete_multiple_rows[chromium]
ERROR mathesar/tests/integration/test_tables.py::test_create_empty_table[chromium]
ERROR mathesar/tests/integration/test_tables.py::test_rename_table_of_another_table[chromium]
ERROR mathesar/tests/integration/test_ui.py::test_tabs[chromium] - sqlalchemy...
ERROR mathesar/tests/integration/test_ui.py::test_tabs[chromium] - sqlalchemy...
============= 5 failed, 2 warnings, 17 errors in 326.96s (0:05:26) ============='''

@pavish
Copy link
Member

pavish commented Mar 16, 2022

@sahilsaini110 Since this PR isn't fully ready, I'm marking it as a draft. Feel free to @ anyone directly for help.

@pavish pavish marked this pull request as draft March 16, 2022 13:33
@sahilsaini1107
Copy link
Contributor Author

@ManishShah120 may you please help me with this issue

@ManishShah120
Copy link
Contributor

@ManishShah120 may you please help me with this issue

Ok, trying.

Comment on lines +23 to +70
def test_convert_boolean_col_to_text_col(page, base_schema_url):
page.goto(base_schema_url)
page.click("[aria-label='New Table']")
page.click("button:has-text('Import Data')")
page.click("text=Copy and Paste Text")
page.fill("textarea", "foo,bar\ntrue,false")
page.click("button:has-text('Continue')")
page.click("button:has-text('Finish Import')")
page.click("button:has-text('foo')")
page.click("button:has-text('Boolean')")
page.click("text=T Text")
page.click("button:has-text('Save')")
page.locator(".dropdown .container .section .btn:has-text('Text')")
Copy link
Contributor

@ManishShah120 ManishShah120 Mar 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def test_convert_boolean_col_to_text_col(page, patent_schema, base_schema_url):

pass patent_schema as the argument.

Also

28    page.fill("textarea", "foo\ntrue\nfalse\nfalse\ntrue")

Copy link
Contributor

@ManishShah120 ManishShah120 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things look good, could you try doing the above suggestion once. In my case after doing the changes it worked, i.e., the test passed.

Comment on lines +69 to +121
def base_schema_url(patent_schema, live_server):
return f"{live_server}/{patent_schema.database.name}/{patent_schema.id}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do these changes too, so try once undoing it.

@sahilsaini1107
Copy link
Contributor Author

Hello @ManishShah120 I have tried the above changes but still errors are there.

@ManishShah120
Copy link
Contributor

Hello @ManishShah120 I have tried the above changes but still errors are there.

Ohh, I see. there must be other reason then!!

@silentninja
Copy link
Contributor

@sahilsaini110 #1168 should solve the issue you are facing. I will mark this issue as blocked until #1168 is fixed

@kgodey
Copy link
Contributor

kgodey commented Mar 25, 2022

This should be unblocked now.

@kgodey kgodey removed the needs: unblocking Blocked by other work label Mar 25, 2022
@kgodey
Copy link
Contributor

kgodey commented Apr 3, 2022

@sahilsaini110 I'm following up since it's been a few days since this PR was updated, are you still working on this?

@sahilsaini1107
Copy link
Contributor Author

@sahilsaini110 I'm following up since it's been a few days since this PR was updated, are you still working on this?

yes I am, will try to resolve all the checks and put them for review again.

@sahilsaini1107 sahilsaini1107 force-pushed the fix#1127 branch 2 times, most recently from 3512335 to f0c5539 Compare April 8, 2022 13:52
@sahilsaini1107
Copy link
Contributor Author

@ManishShah120 may you please check why still this check is failing.

@sahilsaini1107
Copy link
Contributor Author

I'm closing this pull request and starting a new one because this one has a lot of commits and is causing unnecessary work to be messed up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Add E2E test for converting a boolean column to a text column
6 participants