/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2015 ForgeRock AS. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://forgerock.org/license/CDDLv1.0.html
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at http://forgerock.org/license/CDDLv1.0.html
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*/
package org.forgerock.openidm.maintenance.upgrade;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.forgerock.util.Function;
import org.mockito.Matchers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.forgerock.openidm.maintenance.upgrade.StaticFileUpdate.NEW_SUFFIX;
import static org.forgerock.openidm.maintenance.upgrade.StaticFileUpdate.OLD_SUFFIX;
import static org.mockito.Mockito.*;
import static org.testng.AssertJUnit.assertFalse;
/**
* Tests updating static files.
*/
public class StaticFileUpdateTest {
private static final ProductVersion oldVersion = new ProductVersion("3.2.0", "5000");
private static final ProductVersion newVersion = new ProductVersion("4.0.0", "6000");
private static final long timestamp = new Date().getTime();
private static final byte[] oldBytes = "oldcontent".getBytes();
private static final byte[] newBytes = "newcontent".getBytes();
private Path getOldVersionPath(Path file) {
return Paths.get(file + OLD_SUFFIX + timestamp);
}
private Path getNewVersionPath(Path file) {
return Paths.get(file + NEW_SUFFIX + timestamp);
}
private Path tempPath;
private Path tempFile;
@BeforeSuite
public void createTempDirPath() throws IOException {
tempPath = Files.createTempDirectory(this.getClass().getSimpleName());
}
@AfterSuite
public void destroyTempDirPath() throws IOException {
FileUtils.deleteDirectory(tempPath.toFile());
}
@BeforeMethod
public void createTempFile() throws IOException {
tempFile = Files.createTempFile(tempPath, null, null);
}
@AfterMethod
public void deleteTempFile() throws IOException {
Files.deleteIfExists(tempFile.resolveSibling(getNewVersionPath(tempFile)));
Files.deleteIfExists(tempFile.resolveSibling(getOldVersionPath(tempFile)));
Files.delete(tempFile);
}
private StaticFileUpdate getStaticFileUpdate(FileStateChecker fileStateChecker) throws IOException {
Archive archive = mock(Archive.class);
when(archive.getVersion()).thenReturn(newVersion);
when(archive.withInputStreamForPath(eq(tempFile), Matchers.<Function<InputStream, Void, IOException>>any()))
.then(
new Answer<Void>() {
@Override
@SuppressWarnings("unchecked")
public Void answer(InvocationOnMock invocation) throws Throwable {
// first argument - (Path) invocation.getArguments()[0] - is the Path, unused
Function<InputStream, Void, IOException> function =
(Function<InputStream, Void, IOException>) invocation.getArguments()[1];
return function.apply(new ByteArrayInputStream(newBytes));
}
});
return new StaticFileUpdate(fileStateChecker, tempPath, archive, oldVersion, timestamp);
}
/**
* Test a replacement on an unchanged path.
*/
@Test
public void testReplaceIsUnchanged() throws IOException {
FileStateChecker fileStateChecker = mock(FileStateChecker.class);
when(fileStateChecker.getCurrentFileState(tempFile)).thenReturn(FileState.UNCHANGED);
StaticFileUpdate update = getStaticFileUpdate(fileStateChecker);
update.replace(tempFile);
assertThat(Files.readAllBytes(tempFile)).isEqualTo(newBytes);
assertFalse(Files.exists(getOldVersionPath(tempFile)));
assertFalse(Files.exists(getNewVersionPath(tempFile)));
}
/**
* Test a replacement on a path with differences. The file should be updated, with the old content
* moved to <filename>.idm-old
*/
@Test
public void testReplaceDiffers() throws IOException {
Files.write(tempFile, oldBytes);
FileStateChecker fileStateChecker = mock(FileStateChecker.class);
when(fileStateChecker.getCurrentFileState(tempFile)).thenReturn(FileState.DIFFERS);
StaticFileUpdate update = getStaticFileUpdate(fileStateChecker);
update.replace(tempFile);
assertThat(Files.readAllBytes(tempFile)).isEqualTo(newBytes);
assertThat(Files.readAllBytes(getOldVersionPath(tempFile))).isEqualTo(oldBytes);
assertFalse(Files.exists(getNewVersionPath(tempFile)));
}
/**
* Test keeping a file with no differences. This should throw an exception as there are no differences
* to keep.
*/
@Test
public void testKeepIsUnchanged() throws IOException {
Files.write(tempFile, oldBytes);
FileStateChecker fileStateChecker = mock(FileStateChecker.class);
when(fileStateChecker.getCurrentFileState(tempFile)).thenReturn(FileState.UNCHANGED);
StaticFileUpdate update = getStaticFileUpdate(fileStateChecker);
assertThat(update.keep(tempFile)).isNull();
}
/**
* Test keeping a file with differences. The file should retain the old content, with the new content
* written to <filename>.idm-new.
*/
@Test
public void testKeepDiffers() throws IOException {
Files.write(tempFile, oldBytes);
FileStateChecker fileStateChecker = mock(FileStateChecker.class);
when(fileStateChecker.getCurrentFileState(tempFile)).thenReturn(FileState.DIFFERS);
StaticFileUpdate update = getStaticFileUpdate(fileStateChecker);
update.keep(tempFile);
assertThat(Files.readAllBytes(tempFile)).isEqualTo(oldBytes);
assertThat(Files.readAllBytes(getNewVersionPath(tempFile))).isEqualTo(newBytes);
assertFalse(Files.exists(getOldVersionPath(tempFile)));
}
}