def test_all_traverse(self):
        writer = autogenerate.Rewriter()

        mocker = mock.Mock(side_effect=lambda context, revision, op: op)
        writer.rewrites(ops.MigrateOperation)(mocker)

        addcolop = ops.AddColumnOp('t1', sa.Column('x', sa.Integer()))

        directives = [
            ops.MigrationScript(
                util.rev_id(),
                ops.UpgradeOps(ops=[ops.ModifyTableOps('t1', ops=[addcolop])]),
                ops.DowngradeOps(ops=[]),
            )
        ]

        ctx, rev = mock.Mock(), mock.Mock()
        writer(ctx, rev, directives)
        eq_(mocker.mock_calls, [
            mock.call(ctx, rev, directives[0]),
            mock.call(ctx, rev, directives[0].upgrade_ops),
            mock.call(ctx, rev, directives[0].upgrade_ops.ops[0]),
            mock.call(ctx, rev, addcolop),
            mock.call(ctx, rev, directives[0].downgrade_ops),
        ])
示例#2
0
    def _run_black_with_config(self,
                               input_config,
                               expected_additional_arguments_fn,
                               cwd=None):
        self.cfg = _no_sql_testing_config(directives=input_config)
        impl = mock.Mock(attrs=("foo", "bar"), module_name="black_module")
        entrypoints = mock.Mock(return_value=iter([impl]))
        with mock.patch("pkg_resources.iter_entry_points",
                        entrypoints), mock.patch(
                            "alembic.script.write_hooks.subprocess"
                        ) as mock_subprocess:

            rev = command.revision(self.cfg, message="x")

        eq_(entrypoints.mock_calls, [mock.call("console_scripts", "black")])
        eq_(
            mock_subprocess.mock_calls,
            [
                mock.call.run(
                    [
                        sys.executable,
                        "-c",
                        "import black_module; black_module.foo.bar()",
                    ] + expected_additional_arguments_fn(rev.path),
                    cwd=cwd,
                )
            ],
        )
示例#3
0
    def test_console_scripts(self):
        self.cfg = _no_sql_testing_config(
            directives=("\n[post_write_hooks]\n"
                        "hooks=black\n"
                        "black.type=console_scripts\n"
                        "black.entrypoint=black\n"
                        "black.options=-l 79\n"))

        impl = mock.Mock(attrs=("foo", "bar"), module_name="black_module")
        entrypoints = mock.Mock(return_value=iter([impl]))
        with mock.patch("pkg_resources.iter_entry_points",
                        entrypoints), mock.patch(
                            "alembic.script.write_hooks.subprocess"
                        ) as mock_subprocess:

            rev = command.revision(self.cfg, message="x")

        eq_(entrypoints.mock_calls, [mock.call("console_scripts", "black")])
        eq_(
            mock_subprocess.mock_calls,
            [
                mock.call.run([
                    sys.executable,
                    "-c",
                    "import black_module; black_module.foo.bar()",
                    rev.path,
                    "-l",
                    "79",
                ])
            ],
        )
    def test_chained_ops(self):
        writer1 = autogenerate.Rewriter()
        writer2 = autogenerate.Rewriter()

        @writer1.rewrites(ops.AddColumnOp)
        def add_column_nullable(context, revision, op):
            if op.column.nullable:
                return op
            else:
                op.column.nullable = True
                return [
                    op,
                    ops.AlterColumnOp(
                        op.table_name,
                        op.column.name,
                        modify_nullable=False,
                        existing_type=op.column.type,
                    ),
                ]

        @writer2.rewrites(ops.AddColumnOp)
        def add_column_idx(context, revision, op):
            idx_op = ops.CreateIndexOp("ixt", op.table_name, [op.column.name])
            return [op, idx_op]

        directives = [
            ops.MigrationScript(
                util.rev_id(),
                ops.UpgradeOps(ops=[
                    ops.ModifyTableOps(
                        "t1",
                        ops=[
                            ops.AddColumnOp(
                                "t1",
                                sa.Column("x", sa.Integer(), nullable=False),
                            )
                        ],
                    )
                ]),
                ops.DowngradeOps(ops=[]),
            )
        ]

        ctx, rev = mock.Mock(), mock.Mock()
        writer1.chain(writer2)(ctx, rev, directives)

        eq_(
            autogenerate.render_python_code(directives[0].upgrade_ops),
            "# ### commands auto generated by Alembic - please adjust! ###\n"
            "    op.add_column('t1', "
            "sa.Column('x', sa.Integer(), nullable=True))\n"
            "    op.create_index('ixt', 't1', ['x'], unique=False)\n"
            "    op.alter_column('t1', 'x',\n"
            "               existing_type=sa.Integer(),\n"
            "               nullable=False)\n"
            "    # ### end Alembic commands ###",
        )
    def test_no_needless_pass(self):
        writer1 = autogenerate.Rewriter()

        @writer1.rewrites(ops.AlterColumnOp)
        def rewrite_alter_column(context, revision, op):
            return []

        directives = [
            ops.MigrationScript(
                util.rev_id(),
                ops.UpgradeOps(
                    ops=[
                        ops.ModifyTableOps(
                            "t1",
                            ops=[
                                ops.AlterColumnOp(
                                    "foo",
                                    "bar",
                                    modify_nullable=False,
                                    existing_type=sa.Integer(),
                                ),
                                ops.AlterColumnOp(
                                    "foo",
                                    "bar",
                                    modify_nullable=False,
                                    existing_type=sa.Integer(),
                                ),
                            ],
                        ),
                        ops.ModifyTableOps(
                            "t1",
                            ops=[
                                ops.AlterColumnOp(
                                    "foo",
                                    "bar",
                                    modify_nullable=False,
                                    existing_type=sa.Integer(),
                                )
                            ],
                        ),
                    ]
                ),
                ops.DowngradeOps(ops=[]),
            )
        ]
        ctx, rev = mock.Mock(), mock.Mock()
        writer1(ctx, rev, directives)

        eq_(
            autogenerate.render_python_code(directives[0].upgrade_ops),
            "# ### commands auto generated by Alembic - please adjust! ###\n"
            "    pass\n"
            "    # ### end Alembic commands ###",
        )
    def _test_tz(self, timezone_arg, given, expected):
        script = ScriptDirectory(_get_staging_directory(),
                                 file_template="%(rev)s_%(slug)s_"
                                 "%(year)s_%(month)s_"
                                 "%(day)s_%(hour)s_"
                                 "%(minute)s_%(second)s",
                                 timezone=timezone_arg)

        with mock.patch(
                "alembic.script.base.datetime",
                mock.Mock(datetime=mock.Mock(utcnow=lambda: given,
                                             now=lambda: given))):
            create_date = script._generate_create_date()
        eq_(create_date, expected)
示例#7
0
    def test_double_migrate_table(self):
        writer = autogenerate.Rewriter()

        idx_ops = []

        @writer.rewrites(ops.ModifyTableOps)
        def second_table(context, revision, op):
            return [
                op,
                ops.ModifyTableOps('t2', ops=[
                    ops.AddColumnOp('t2', sa.Column('x', sa.Integer()))
                ])
            ]

        @writer.rewrites(ops.AddColumnOp)
        def add_column(context, revision, op):
            idx_op = ops.CreateIndexOp('ixt', op.table_name, [op.column.name])
            idx_ops.append(idx_op)
            return [
                op,
                idx_op
            ]

        directives = [
            ops.MigrationScript(
                util.rev_id(),
                ops.UpgradeOps(ops=[
                    ops.ModifyTableOps('t1', ops=[
                        ops.AddColumnOp('t1', sa.Column('x', sa.Integer()))
                    ])
                ]),
                ops.DowngradeOps(ops=[]),
            )
        ]

        ctx, rev = mock.Mock(), mock.Mock()
        writer(ctx, rev, directives)
        eq_(
            [d.table_name for d in directives[0].upgrade_ops.ops],
            ['t1', 't2']
        )
        is_(
            directives[0].upgrade_ops.ops[0].ops[1],
            idx_ops[0]
        )
        is_(
            directives[0].upgrade_ops.ops[1].ops[1],
            idx_ops[1]
        )
示例#8
0
    def test_uses_custom_compare_type_function(self):
        my_compare_type = mock.Mock()
        self.context._user_compare_type = my_compare_type

        uo = ops.UpgradeOps(ops=[])

        ctx = self.autogen_context
        autogenerate._produce_net_changes(ctx, uo)

        first_table = self.m2.tables["sometable"]
        first_column = first_table.columns["id"]

        eq_(len(my_compare_type.mock_calls), 2)

        # We'll just test the first call
        _, args, _ = my_compare_type.mock_calls[0]
        (
            context,
            inspected_column,
            metadata_column,
            inspected_type,
            metadata_type,
        ) = args
        eq_(context, self.context)
        eq_(metadata_column, first_column)
        eq_(metadata_type, first_column.type)
        eq_(inspected_column.name, first_column.name)
        eq_(type(inspected_type), INTEGER)
示例#9
0
    def test_steps(self):
        import alembic
        alembic.mock_event_listener = None
        self._env_file_fixture()
        with mock.patch('alembic.mock_event_listener', mock.Mock()) as mymock:
            super(CallbackEnvironmentTest, self).test_steps()
        calls = mymock.call_args_list
        assert calls
        for call in calls:
            args, kw = call
            assert not args
            assert set(kw.keys()) >= self.exp_kwargs
            assert kw['run_args'] == {}
            assert hasattr(kw['ctx'], 'get_current_revision')

            step = kw['step']
            assert isinstance(step.is_upgrade, bool)
            assert isinstance(step.is_stamp, bool)
            assert isinstance(step.is_migration, bool)
            assert isinstance(step.up_revision_id, compat.string_types)
            assert isinstance(step.up_revision, Script)

            for revtype in 'up', 'down', 'source', 'destination':
                revs = getattr(step, '%s_revisions' % revtype)
                assert isinstance(revs, tuple)
                for rev in revs:
                    assert isinstance(rev, Script)
                revids = getattr(step, '%s_revision_ids' % revtype)
                for revid in revids:
                    assert isinstance(revid, compat.string_types)

            heads = kw['heads']
            assert hasattr(heads, '__iter__')
            for h in heads:
                assert h is None or isinstance(h, compat.string_types)
示例#10
0
    def _run_black_with_config(self,
                               input_config,
                               expected_additional_arguments_fn,
                               cwd=None):
        self.cfg = _no_sql_testing_config(directives=input_config)

        class MocksCantName:
            name = "black"
            attr = "bar"
            module = "black_module.foo"

        importlib_metadata_get = mock.Mock(return_value=iter([MocksCantName]))
        with mock.patch(
                "alembic.util.compat.importlib_metadata_get",
                importlib_metadata_get,
        ), mock.patch(
                "alembic.script.write_hooks.subprocess") as mock_subprocess:

            rev = command.revision(self.cfg, message="x")

        eq_(importlib_metadata_get.mock_calls, [mock.call("console_scripts")])
        eq_(
            mock_subprocess.mock_calls,
            [
                mock.call.run(
                    [
                        sys.executable,
                        "-c",
                        "import black_module.foo; black_module.foo.bar()",
                    ] + expected_additional_arguments_fn(rev.path),
                    cwd=cwd,
                )
            ],
        )
示例#11
0
    def test_upgrade(self):
        head = HeadMaintainer(mock.Mock(), [self.a.revision])
        """
        upgrade a -> b2, b2
        upgrade a -> b3, b3
        upgrade b2, b3 -> c2, c2
        upgrade c2 -> d2, d2
        upgrade a -> b1, b1
        upgrade b1, b2 -> c1, c1
        upgrade c1 -> d1, d1
        """

        steps = [
            (self.up_(self.b2), ('b2', )),
            (self.up_(self.b3), (
                'b2',
                'b3',
            )),
            (self.up_(self.c2), ('c2', )),
            (self.up_(self.d2), ('d2', )),
            (self.up_(self.b1), (
                'b1',
                'd2',
            )),
            (self.up_(self.c1), ('c1', 'd2')),
            (self.up_(self.d1), ('d1', 'd2')),
        ]
        for step, assert_ in steps:
            head.update_to_step(step)
            eq_(head.heads, set(assert_))
示例#12
0
 def test_downgrade_branch_dependency(self):
     """c2branch depends on c1branch so taking down c1branch requires taking
     down both"""
     destination = "c1branch@{}".format(self.b.revision)
     source = self.d1.revision, self.d2.revision
     revs = self.env._downgrade_revs(destination, source)
     # Drops c1, d1 as requested, also drops d2 due to dependence on d1.
     # Full ordering of migrations is not consistent so verify partial
     # ordering only.
     rev_ids = [rev.revision.revision for rev in revs]
     assert set(rev_ids) == {
         self.c1.revision,
         self.d1.revision,
         self.d2.revision,
     }
     assert rev_ids.index(self.d1.revision) < rev_ids.index(
         self.c1.revision)
     assert rev_ids.index(self.d2.revision) < rev_ids.index(
         self.c1.revision)
     # Verify final state.
     heads = set(util.to_tuple(source, default=()))
     head = HeadMaintainer(mock.Mock(), heads)
     for rev in revs:
         head.update_to_step(rev)
     eq_(head.heads, set([self.c2.revision]))
示例#13
0
    def test_script_location(self):
        config = _no_sql_testing_config()

        script = ScriptDirectory.from_config(config)

        def normpath(path):
            return path.replace("/", ":NORM:")

        normpath = mock.Mock(side_effect=normpath)

        with mock.patch("os.path.normpath", normpath):
            eq_(
                script._version_locations,
                (
                    os.path.abspath(
                        os.path.join(
                            _get_staging_directory(), "scripts", "versions"
                        )
                    ).replace("/", ":NORM:"),
                ),
            )

            eq_(
                script.versions,
                os.path.abspath(
                    os.path.join(
                        _get_staging_directory(), "scripts", "versions"
                    )
                ).replace("/", ":NORM:"),
            )
示例#14
0
    def test_invoke(self):
        my_formatter = mock.Mock()
        write_hooks.register("my_writer")(my_formatter)

        write_hooks._invoke("my_writer", "/some/path", {"option": 1})

        my_formatter.assert_called_once_with("/some/path", {"option": 1})
示例#15
0
    def test_run_cmd_args_missing(self):
        canary = mock.Mock()

        orig_revision = command.revision

        # the command function has "process_revision_directives"
        # however the ArgumentParser does not.  ensure things work
        def revision(
            config,
            message=None,
            autogenerate=False,
            sql=False,
            head="head",
            splice=False,
            branch_label=None,
            version_path=None,
            rev_id=None,
            depends_on=None,
            process_revision_directives=None,
        ):
            canary(config, message=message)

        revision.__module__ = "alembic.command"

        # CommandLine() pulls the function into the ArgumentParser
        # and needs the full signature, so we can't patch the "revision"
        # command normally as ArgumentParser gives us no way to get to it.
        config.command.revision = revision
        try:
            commandline = config.CommandLine()
            options = commandline.parser.parse_args(["revision", "-m", "foo"])
            commandline.run_cmd(self.cfg, options)
        finally:
            config.command.revision = orig_revision
        eq_(canary.mock_calls, [mock.call(self.cfg, message="foo")])
    def test_script_location_muliple(self):
        config = _multi_dir_testing_config()

        script = ScriptDirectory.from_config(config)

        def normpath(path):
            return path.replace("/", ":NORM:")

        normpath = mock.Mock(side_effect=normpath)

        with mock.patch("os.path.normpath", normpath):
            eq_(
                script._version_locations,
                [
                    os.path.abspath(
                        os.path.join(_get_staging_directory(),
                                     "model1/")).replace("/", ":NORM:"),
                    os.path.abspath(
                        os.path.join(_get_staging_directory(),
                                     "model2/")).replace("/", ":NORM:"),
                    os.path.abspath(
                        os.path.join(_get_staging_directory(),
                                     "model3/")).replace("/", ":NORM:"),
                ],
            )
示例#17
0
 def test_ascii_unicode(self):
     stdout = mock.Mock(encoding=None)
     cfg = config.Config(stdout=stdout)
     cfg.print_stdout(compat.u("méil %s %s"), "x", "y")
     eq_(
         stdout.mock_calls,
         [mock.call.write("m?il x y"), mock.call.write("\n")],
     )
示例#18
0
 def test_utf8_unicode(self):
     stdout = mock.Mock(encoding="latin-1")
     cfg = config.Config(stdout=stdout)
     cfg.print_stdout(compat.u("méil %s %s"), "x", "y")
     eq_(
         stdout.mock_calls,
         [mock.call.write(compat.u("méil x y")), mock.call.write("\n")],
     )
示例#19
0
 def test_only_formats_output_with_args(self):
     stdout = mock.Mock(encoding=None)
     cfg = config.Config(stdout=stdout)
     cfg.print_stdout(compat.u("test 3%"))
     eq_(
         stdout.mock_calls,
         [mock.call.write("test 3%"), mock.call.write("\n")],
     )
示例#20
0
 def test_plain(self):
     stdout = mock.Mock(encoding="latin-1")
     cfg = config.Config(stdout=stdout)
     cfg.print_stdout("test %s %s", "x", "y")
     eq_(
         stdout.mock_calls,
         [mock.call.write("test x y"), mock.call.write("\n")],
     )
示例#21
0
 def _assert_upgrade(self, destination, source, expected, expected_heads):
     revs = self.env._upgrade_revs(destination, source)
     eq_(revs, expected)
     heads = set(util.to_tuple(source, default=()))
     head = HeadMaintainer(mock.Mock(), heads)
     for rev in revs:
         head.update_to_step(rev)
     eq_(head.heads, expected_heads)
示例#22
0
    def _fixture(self):
        migration_context = mock.Mock(opts={})
        op = Operations(migration_context)
        batch = op.batch_alter_table('tname', recreate='never').__enter__()

        with mock.patch("alembic.operations.sa_schema") as mock_schema:
            yield batch
        batch.impl.flush()
        self.mock_schema = mock_schema
示例#23
0
    def test_generic(self):
        hook1 = mock.Mock()
        hook2 = mock.Mock()

        write_hooks.register("hook1")(hook1)
        write_hooks.register("hook2")(hook2)

        self.cfg = _no_sql_testing_config(directives=("\n[post_write_hooks]\n"
                                                      "hooks=hook1,hook2\n"
                                                      "hook1.type=hook1\n"
                                                      "hook1.arg1=foo\n"
                                                      "hook2.type=hook2\n"
                                                      "hook2.arg1=bar\n"))

        rev = command.revision(self.cfg, message="x")

        eq_(
            hook1.mock_calls,
            [
                mock.call(
                    rev.path,
                    {
                        "type": "hook1",
                        "arg1": "foo",
                        "_hook_name": "hook1"
                    },
                )
            ],
        )
        eq_(
            hook2.mock_calls,
            [
                mock.call(
                    rev.path,
                    {
                        "type": "hook2",
                        "arg1": "bar",
                        "_hook_name": "hook2"
                    },
                )
            ],
        )
示例#24
0
    def test_column_type_not_modified_custom_compare_type_returns_False(self):
        my_compare_type = mock.Mock()
        my_compare_type.return_value = False
        self.context._user_compare_type = my_compare_type

        diffs = []
        ctx = self.autogen_context
        diffs = []
        autogenerate._produce_net_changes(ctx, diffs)

        eq_(diffs, [])
示例#25
0
    def test_column_type_modified_custom_compare_type_returns_True(self):
        my_compare_type = mock.Mock()
        my_compare_type.return_value = True
        self.context._user_compare_type = my_compare_type

        ctx = self.autogen_context
        uo = ops.UpgradeOps(ops=[])
        autogenerate._produce_net_changes(ctx, uo)
        diffs = uo.as_diffs()

        eq_(diffs[0][0][0], "modify_type")
        eq_(diffs[1][0][0], "modify_type")
示例#26
0
    def _fixture(self, schema=None):
        migration_context = mock.Mock(
            opts={}, impl=mock.MagicMock(__dialect__='sqlite'))
        op = Operations(migration_context)
        batch = op.batch_alter_table('tname', recreate='never',
                                     schema=schema).__enter__()

        mock_schema = mock.MagicMock()
        with mock.patch("alembic.operations.schemaobj.sa_schema", mock_schema):
            yield batch
        batch.impl.flush()
        self.mock_schema = mock_schema
    def test_stamp_api_creates_table(self):
        context = self.make_one(connection=self.connection)
        assert ('alembic_version'
                not in Inspector(self.connection).get_table_names())

        script = mock.Mock(
            _stamp_revs=lambda revision, heads:
            [_up(None, 'a', True), _up(None, 'b', True)])

        context.stamp(script, 'b')
        eq_(context.get_current_heads(), ('a', 'b'))
        assert ('alembic_version'
                in Inspector(self.connection).get_table_names())
示例#28
0
    def test_stamp_api_creates_table(self):
        context = self.make_one(connection=self.connection)
        assert ("alembic_version"
                not in inspect(self.connection).get_table_names())

        script = mock.Mock(_stamp_revs=lambda revision, heads: [
            _up(None, "a", True),
            _up(None, "b", True),
        ])

        context.stamp(script, "b")
        eq_(context.get_current_heads(), ("a", "b"))
        assert "alembic_version" in inspect(self.connection).get_table_names()
示例#29
0
    def test_upgrade(self):
        head = HeadMaintainer(mock.Mock(), [self.a.revision])

        steps = [
            (self.up_(self.b3), ('b3',)),
            (self.up_(self.b1), ('b1', 'b3',)),
            (self.up_(self.b2), ('b1', 'b2', 'b3',)),
            (self.up_(self.c2), ('c2',)),
            (self.up_(self.d2), ('d2',)),
            (self.up_(self.c1), ('c1', 'd2')),
            (self.up_(self.d1), ('d1', 'd2')),
        ]
        for step, assert_ in steps:
            head.update_to_step(step)
            eq_(head.heads, set(assert_))
示例#30
0
    def test_upgrade(self):
        head = HeadMaintainer(mock.Mock(), [self.a.revision])

        steps = [
            (self.up_(self.b3), ("b3", )),
            (self.up_(self.b1), ("b1", "b3")),
            (self.up_(self.b2), ("b1", "b2", "b3")),
            (self.up_(self.c2), ("c2", )),
            (self.up_(self.d2), ("d2", )),
            (self.up_(self.c1), ("c1", "d2")),
            (self.up_(self.d1), ("d1", "d2")),
        ]
        for step, assert_ in steps:
            head.update_to_step(step)
            eq_(head.heads, set(assert_))