Skip to content

Commit 7a36a9c

Browse files
authored
fix(rollback): Fixes the order of rollling back. (#10)
1 parent 49434e9 commit 7a36a9c

File tree

7 files changed

+56
-28
lines changed

7 files changed

+56
-28
lines changed

src/migrate/test.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as assertRejects from 'assert-rejects';
33
import 'mocha'; // tslint:disable-line:no-import-side-effect
44
import DuplicateKeyError from '../utils/errors/DuplicateKeyError';
55
import FailingMigrationError from '../utils/errors/FailingMigrationError';
6+
import assertDateOrder from '../utils/tests/assertDateOrder';
67
import assertLocked from '../utils/tests/assertLocked';
78
import createMigrationProcess from '../utils/tests/createMigrationProcess';
89
import createTestUpMigration from '../utils/tests/createTestUpMigration';
@@ -39,18 +40,25 @@ const testMigrate: TestFactory = (createService) => {
3940
await assertRejects(promise, FailingMigrationError);
4041
});
4142

42-
it('should process migrations', async () => {
43-
const { process, getProcessed } = createMigrationProcess();
44-
const service = createService([createTestUpMigration(process)]);
43+
it('should process migrations in order', async () => {
44+
const firstProcess = createMigrationProcess();
45+
const secondProcess = createMigrationProcess();
46+
const service = createService([
47+
createTestUpMigration(firstProcess.process, 'firstMigration'),
48+
createTestUpMigration(secondProcess.process, 'secondMigration'),
49+
]);
4550
await service.migrate();
46-
assert.equal(getProcessed(), true);
51+
assert.notEqual(firstProcess.getProcessed(), undefined);
52+
assert.notEqual(secondProcess.getProcessed(), undefined);
53+
const processes = [firstProcess.getProcessed(), secondProcess.getProcessed()];
54+
assertDateOrder(processes as Date[]);
4755
});
4856

4957
it('should not reprocess migrations', async () => {
5058
const { process, getProcessed } = createMigrationProcess();
5159
await createService([createTestUpMigration()]).migrate();
5260
await createService([createTestUpMigration(process)]).migrate();
53-
assert.equal(getProcessed(), false);
61+
assert.equal(getProcessed(), undefined);
5462
});
5563

5664
it('should skip processed migrations after unprocessed migrations', async () => {
@@ -61,8 +69,8 @@ const testMigrate: TestFactory = (createService) => {
6169
createTestUpMigration(unskippedProcess.process),
6270
createTestUpMigration(skippedProcess.process, skippableKey),
6371
]).migrate();
64-
assert.equal(skippedProcess.getProcessed(), false);
65-
assert.equal(unskippedProcess.getProcessed(), true);
72+
assert.equal(skippedProcess.getProcessed(), undefined);
73+
assert.notEqual(unskippedProcess.getProcessed(), undefined);
6674
});
6775

6876
it('should skip processed migrations before unprocessed migrations', async () => {
@@ -73,8 +81,8 @@ const testMigrate: TestFactory = (createService) => {
7381
createTestUpMigration(skippedProcess.process, skippableKey),
7482
createTestUpMigration(unskippedProcess.process),
7583
]).migrate();
76-
assert.equal(skippedProcess.getProcessed(), false);
77-
assert.equal(unskippedProcess.getProcessed(), true);
84+
assert.equal(skippedProcess.getProcessed(), undefined);
85+
assert.notEqual(unskippedProcess.getProcessed(), undefined);
7886
});
7987

8088
it('should error when migrations are locked', async () => {

src/migrateByKey/test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const testMigrateByKey: TestFactory = (createService) => {
4242
const { process, getProcessed } = createMigrationProcess();
4343
const service = createService([createTestUpMigration(process)]);
4444
await service.migrateByKey({ key: testMigrationKey });
45-
assert.equal(getProcessed(), true);
45+
assert.notEqual(getProcessed(), undefined);
4646
});
4747

4848
it('should error when reprocessing migrations without force', async () => {
@@ -51,15 +51,15 @@ const testMigrateByKey: TestFactory = (createService) => {
5151
const service = createService([createTestUpMigration(process)]);
5252
const promise = service.migrateByKey({ key: testMigrationKey });
5353
await assertRejects(promise, ProcessedMigrationError);
54-
assert.equal(getProcessed(), false);
54+
assert.equal(getProcessed(), undefined);
5555
});
5656

5757
it('should reprocess migration when using force', async () => {
5858
const { process, getProcessed } = createMigrationProcess();
5959
await createService([createTestUpMigration()]).migrate();
6060
const service = createService([createTestUpMigration(process)]);
6161
await service.migrateByKey({ key: testMigrationKey, force: true });
62-
assert.equal(getProcessed(), true);
62+
assert.notEqual(getProcessed(), undefined);
6363
});
6464

6565
it('should error when migrations are locked', async () => {

src/rollback/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Signature, { Opts } from './Signature';
88
export default (config: FacadeConfig): Signature => {
99
return async ({ dryRun = false }: Opts = {}) => {
1010
await handleLocks(config, async () => {
11-
const lastBatchKeys = await getLastBatchKeys(config);
11+
const lastBatchKeys = (await getLastBatchKeys(config)).reverse();
1212

1313
await Promise.resolve(reduce(lastBatchKeys, async (_result, key) => {
1414
await rollbackKey({ config, key, dryRun });

src/rollback/test.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'mocha'; // tslint:disable-line:no-import-side-effect
55
import DuplicateKeyError from '../utils/errors/DuplicateKeyError';
66
import FailingMigrationError from '../utils/errors/FailingMigrationError';
77
import MissingMigrationError from '../utils/errors/MissingMigrationError';
8+
import assertDateOrder from '../utils/tests/assertDateOrder';
89
import assertLocked from '../utils/tests/assertLocked';
910
import createMigrationProcess from '../utils/tests/createMigrationProcess';
1011
import createTestDownMigration from '../utils/tests/createTestDownMigration';
@@ -57,19 +58,26 @@ const testRollback: TestFactory = (createService) => {
5758
await assertRejects(promise, FailingMigrationError);
5859
});
5960

60-
it('should process rollback for a processed migration', async () => {
61-
const { process, getProcessed } = createMigrationProcess();
62-
const service = createService([createTestDownMigration(process)]);
61+
it('should process rollbacks for processed migrations in reverse order', async () => {
62+
const firstProcess = createMigrationProcess();
63+
const secondProcess = createMigrationProcess();
64+
const service = createService([
65+
createTestDownMigration(firstProcess.process, 'firstMigration'),
66+
createTestDownMigration(secondProcess.process, 'secondMigration'),
67+
]);
6368
await service.migrate();
6469
await service.rollback();
65-
assert.equal(getProcessed(), true);
70+
assert.notEqual(firstProcess.getProcessed(), undefined);
71+
assert.notEqual(secondProcess.getProcessed(), undefined);
72+
const processes = [secondProcess.getProcessed(), firstProcess.getProcessed()];
73+
assertDateOrder(processes as Date[]);
6674
});
6775

6876
it('should not process rollback for a unprocessed migration', async () => {
6977
const { process, getProcessed } = createMigrationProcess();
7078
const service = createService([createTestDownMigration(process)]);
7179
await service.rollback();
72-
assert.equal(getProcessed(), false);
80+
assert.equal(getProcessed(), undefined);
7381
});
7482

7583
it('should skip unprocessed migrations after processed migrations', async () => {
@@ -80,8 +88,8 @@ const testRollback: TestFactory = (createService) => {
8088
createTestDownMigration(unskippedProcess.process, unskippableKey),
8189
createTestDownMigration(skippedProcess.process),
8290
]).rollback();
83-
assert.equal(skippedProcess.getProcessed(), false);
84-
assert.equal(unskippedProcess.getProcessed(), true);
91+
assert.equal(skippedProcess.getProcessed(), undefined);
92+
assert.notEqual(unskippedProcess.getProcessed(), undefined);
8593
});
8694

8795
it('should skip unprocessed migrations before processed migrations', async () => {
@@ -92,8 +100,8 @@ const testRollback: TestFactory = (createService) => {
92100
createTestDownMigration(skippedProcess.process),
93101
createTestDownMigration(unskippedProcess.process, unskippableKey),
94102
]).rollback();
95-
assert.equal(skippedProcess.getProcessed(), false);
96-
assert.equal(unskippedProcess.getProcessed(), true);
103+
assert.equal(skippedProcess.getProcessed(), undefined);
104+
assert.notEqual(unskippedProcess.getProcessed(), undefined);
97105
});
98106

99107
it('should error when migrations are locked', async () => {

src/rollbackByKey/test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,22 @@ const testRollbackByKey: TestFactory = (createService) => {
4646
const service = createService([createTestDownMigration(process)]);
4747
await service.migrate();
4848
await service.rollbackByKey({ key: testMigrationKey });
49-
assert.equal(getProcessed(), true);
49+
assert.notEqual(getProcessed(), undefined);
5050
});
5151

5252
it('should error when rolling back unprocessed migrations without force', async () => {
5353
const { process, getProcessed } = createMigrationProcess();
5454
const service = createService([createTestDownMigration(process)]);
5555
const promise = service.rollbackByKey({ key: testMigrationKey });
5656
await assertRejects(promise, UnprocessedMigrationError);
57-
assert.equal(getProcessed(), false);
57+
assert.equal(getProcessed(), undefined);
5858
});
5959

6060
it('should rollback when rolling back a unprocessed migration with force', async () => {
6161
const { process, getProcessed } = createMigrationProcess();
6262
const service = createService([createTestDownMigration(process)]);
6363
await service.rollbackByKey({ key: testMigrationKey, force: true });
64-
assert.equal(getProcessed(), true);
64+
assert.notEqual(getProcessed(), undefined);
6565
});
6666

6767
it('should error when migrations are locked', async () => {

src/utils/tests/assertDateOrder.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as assert from 'assert';
2+
3+
export default (dates: Date[]) => {
4+
const expectedDates = dates.map((date) => {
5+
return date.toISOString();
6+
});
7+
const sortedDates = [...expectedDates].sort();
8+
assert.deepEqual(sortedDates, expectedDates);
9+
};

src/utils/tests/createMigrationProcess.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import { delay } from 'bluebird';
2+
13
export default () => {
2-
let processed = false; // tslint:disable-line:no-let
3-
const process = () => {
4-
processed = true;
4+
let processed: Date | undefined; // tslint:disable-line:no-let
5+
const process = async () => {
6+
await Promise.resolve(delay(1));
7+
processed = new Date();
58
};
69
const getProcessed = () => {
710
return processed;

0 commit comments

Comments
 (0)