문제 상황
mocha + typescript + node.js + mongoDB (contianer) 환경
테스트 코드 작성
파일 단위로 테스트 완료 후 DB clean-up 을 DB Drop 하는 함수로 감싼다.
DB 초기화 함수
import {MongoClient} from 'mongodb'
const DEFAULT_MONGO_DB_NAMES = ['admin', 'config', 'local'];
export async function initDB() : Promise<void> {
const dbClient = new MongoClient(config);
await dbClient.connect();
const res = await dbClient.db().admin().listDatabases();
const databases = res['databases'];
const dbNames = databases.map(db=>db.name);
const promises = []
for(const dbName of dbNames) {
if (!DEFAULT_MONGO_DB_NAMES.includes(dbName)) {
console.log(`target name : ${dbName}`)
promises.push(dbClient.db(dbName.toString()).dropDatabase());
}
}
await Promise.all(promises);
await dbClient.close();
}
test.ts
describe('DB integration test', ()=>{
after(async ()=>{
await initDB()
})
// DB Drop 성공
it('Not related to DB', (done)=>{
//NOTHING Related to DB
})
// DB Drop 실패
it('insert', async()=>{
const a = Model.create(something)
model.insert(a)
})
})
DB 연산을 하는 케이스에서
DB Drop 이 안된다.
Test 가 끝났다면 DB를 drop 시켜야하는데
DB 연산을 동작시키는 코드에서는 DB 드랍이 작동하지 않는다.
추정 원인
1. 혹시 Collection 이 존재하면 Drop 연산이 무시되나?
No.
'Not releated to DB' 테스트를 단독으로 돌리면 Collection 에 데이터가 있는 상태여도 DB가 Drop 된다.
2. Collection Lock 상태라 Drop 연산이 무시되나?
No
아래 테스트 코드에서 insert A 와 insert B 를 단독으로 따로 시킨다고 가정하면
B를 실행할 때 A 컬렉션'만' 삭제되고
A를 실행할 때 B 컬렉션'만' 삭제된다.
이로써 Collection Lock 이 발생함을 알 수 있었다.
describe('DB integration test', ()=>{
after(async ()=>{
await initDB()
})
// DB Drop A는 실패, B는 성공
it('insert A', async()=>{
const a = Model.create('a')
model.insert(a)
})
// DB Drop B 는 실패, A는 성공
it('insert B', async()=>{
const b = Model.create('b')
model.insert(b)
})
})
Collection 존재 여부도, Lock 도 아니였다.
Background 에서 insert 가 실행되는 프로세스가 있어서였다.
(Worker Threads)
after() Hook 의 DB drop 은 정상 실행되고 나서 background 에서 insert 된 것 뿐이였다.
왠지 테스트가 종료되도 process 가 종료되지 않아서 의아했는데..
이런 부분을 짚고 넘어가야한다.
'DataBase > NoSQL' 카테고리의 다른 글
mongodb active:failed Error (0) | 2020.01.31 |
---|---|
MongoDB dump 백업 & 복구 (mongorestore) (0) | 2020.01.16 |
NoSQL (0) | 2020.01.05 |