001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.integration.http.api; 019 020import java.io.IOException; 021import java.io.UncheckedIOException; 022import java.nio.file.Files; 023import java.util.concurrent.atomic.AtomicBoolean; 024 025import org.fcrepo.config.OcflPropsConfig; 026import org.fcrepo.persistence.ocfl.RepositoryInitializer; 027 028import org.apache.commons.io.FileUtils; 029import org.flywaydb.core.Flyway; 030import org.springframework.test.context.TestContext; 031 032import edu.wisc.library.ocfl.api.MutableOcflRepository; 033 034/** 035 * Listener that baselines the DB and OCFL repo between every test. 036 * It does not baseline on Windows due to difficulties associated with deleting and immediately recreating directories. 037 * 038 * @author pwinckles 039 */ 040public class TestIsolationExecutionListener extends BaseTestExecutionListener { 041 042 @Override 043 public void afterTestMethod(final TestContext testContext) throws Exception { 044 final var ocflRepo = getBean(testContext, MutableOcflRepository.class); 045 final var ocflConfig = getBean(testContext, OcflPropsConfig.class); 046 final var flyway = getBean(testContext, Flyway.class); 047 048 flyway.clean(); 049 flyway.migrate(); 050 051 cleanDb(testContext); 052 053 final var hasError = new AtomicBoolean(false); 054 055 ocflRepo.listObjectIds().forEach(object -> { 056 try { 057 ocflRepo.purgeObject(object); 058 } catch (final RuntimeException e) { 059 // Recursive deletes don't behave well on Windows and it's possible for the above to error out. 060 hasError.set(true); 061 } 062 }); 063 064 if (hasError.get()) { 065 // If one of the purge operations failed, attempt to nuke everything. Maybe it'll work second time round? 066 // We still need the purgeObject calls first so that objects are removed from the ocfl-java cache. 067 try (final var files = Files.list(ocflConfig.getOcflRepoRoot())) { 068 files.filter(Files::isDirectory).forEach(childDir -> { 069 try { 070 FileUtils.cleanDirectory(childDir.toFile()); 071 } catch (final IOException e) { 072 throw new UncheckedIOException(e); 073 } 074 }); 075 } 076 } 077 078 final var initializer = getBean(testContext, RepositoryInitializer.class); 079 initializer.initialize(); 080 } 081}