/*
* The MIT License
*
* Copyright 2013 Mirko Friedenhagen.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.jobConfigHistory;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.SortedMap;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import hudson.Util;
import hudson.XmlFile;
import hudson.model.AbstractItem;
import hudson.model.Node;
import hudson.model.User;
import hudson.util.IOUtils;
import jenkins.model.Jenkins;
/**
*
* @author Mirko Friedenhagen
*/
public class FileHistoryDaoTest {
@Rule
public final UnpackResourceZip unpackResourceZip = UnpackResourceZip
.create();
private final User mockedUser = mock(User.class);
private final AbstractItem mockedItem = mock(AbstractItem.class);
private File jenkinsHome;
private XmlFile test1Config;
private File historyRoot;
private File test1History;
private FileHistoryDao sutWithoutUserAndDuplicateHistory;
private FileHistoryDao sutWithUserAndNoDuplicateHistory;
private static final String FULL_NAME = "Full Name";
private static final String USER_ID = "userId";
private File test1JobDirectory;
private final Node mockedNode = mock(Node.class);
public FileHistoryDaoTest() {
}
@Before
public void setFieldsFromUnpackResource() {
jenkinsHome = unpackResourceZip.getRoot();
test1Config = new XmlFile(
unpackResourceZip.getResource("jobs/Test1/config.xml"));
test1JobDirectory = test1Config.getFile().getParentFile();
historyRoot = unpackResourceZip.getResource("config-history");
test1History = new File(historyRoot, "jobs/Test1");
sutWithoutUserAndDuplicateHistory = new FileHistoryDao(historyRoot,
jenkinsHome, null, 0, true);
sutWithUserAndNoDuplicateHistory = new FileHistoryDao(historyRoot,
jenkinsHome, mockedUser, 0, false);
when(mockedUser.getFullName()).thenReturn(FULL_NAME);
when(mockedUser.getId()).thenReturn(USER_ID);
}
/**
* Test of createNewHistoryEntry method, of class FileHistoryDao.
*/
@Test
public void testCreateNewHistoryEntry() throws IOException {
sutWithoutUserAndDuplicateHistory.createNewHistoryEntry(test1Config,
"foo", null, null);
final int newLength = getHistoryLength();
assertEquals(6, newLength);
}
/**
* Test of createNewHistoryEntry method, of class FileHistoryDao.
*/
@Test
public void testCreateNewHistoryEntryRTE() throws IOException {
final XmlFile xmlFile = test1Config;
FileHistoryDao sut = new FileHistoryDao(historyRoot, jenkinsHome, null,
0, false) {
@Override
File getRootDir(XmlFile xmlFile,
AtomicReference<Calendar> timestampHolder) {
throw new RuntimeException("oops");
}
};
try {
sut.createNewHistoryEntry(xmlFile, "foo", null, null);
fail("Should throw RTE");
} catch (RuntimeException e) {
final int newLength = getHistoryLength();
assertEquals(5, newLength);
}
}
/**
* Test of getIdFormatter method, of class FileHistoryDao.
*/
@Test
public void testGetIdFormatter() {
SimpleDateFormat result = FileHistoryDao.getIdFormatter();
final String formattedDate = result.format(new Date(0));
// workaround for timezone issues, as cloudbees is in the far east :-)
// and returns 1969 :-).
assertThat(formattedDate, startsWith("19"));
assertThat(formattedDate, endsWith("00-00"));
}
/**
* Test of copyConfigFile method, of class FileHistoryDao.
*/
@Test
public void testCopyConfigFile() throws Exception {
File currentConfig = test1Config.getFile();
File timestampedDir = new File(jenkinsHome, "timestamp");
timestampedDir.mkdir();
FileHistoryDao.copyConfigFile(currentConfig, timestampedDir);
final File copy = new File(timestampedDir, currentConfig.getName());
assertTrue(copy.exists());
}
/**
* Test of copyConfigFile method, of class FileHistoryDao.
*/
@Test(expected = FileNotFoundException.class)
public void testCopyConfigFileIOE() throws Exception {
File currentConfig = test1Config.getFile();
File timestampedDir = new File(jenkinsHome, "timestamp");
// do *not* create the directory
FileHistoryDao.copyConfigFile(currentConfig, timestampedDir);
}
/**
* Test of createHistoryXmlFile method, of class FileHistoryDao.
*/
@Test
public void testCreateHistoryXmlFile() throws Exception {
testCreateHistoryXmlFile(sutWithUserAndNoDuplicateHistory, FULL_NAME);
}
/**
* Test of createHistoryXmlFile method, of class FileHistoryDao.
*/
@Test
public void testCreateHistoryXmlFileAnonym() throws Exception {
testCreateHistoryXmlFile(sutWithoutUserAndDuplicateHistory, "Anonym");
}
private void testCreateHistoryXmlFile(FileHistoryDao sut,
final String fullName) throws IOException {
Calendar timestamp = new GregorianCalendar();
File timestampedDir = new File(historyRoot, "timestampedDir");
sut.createHistoryXmlFile(timestamp, timestampedDir, "foo", null, null);
final File historyFile = new File(timestampedDir,
JobConfigHistoryConsts.HISTORY_FILE);
assertTrue(historyFile.exists());
final String historyContent = Util.loadFile(historyFile,
Charset.forName("utf-8"));
assertThat(historyContent, startsWith("<?xml"));
assertThat(historyContent, endsWith("HistoryDescr>"));
assertThat(historyContent, containsString("<user>" + fullName));
assertThat(historyContent, containsString("foo"));
}
/**
* Test of createNewHistoryDir method, of class FileHistoryDao.
*/
@Test
public void testCreateNewHistoryDir() throws IOException {
final AtomicReference<Calendar> timestampHolder = new AtomicReference<Calendar>();
final File first = FileHistoryDao.createNewHistoryDir(historyRoot,
timestampHolder);
assertTrue(first.exists());
assertTrue(first.isDirectory());
// Should provoke clash
final File second = FileHistoryDao.createNewHistoryDir(historyRoot,
timestampHolder);
assertTrue(second.exists());
assertTrue(second.isDirectory());
assertNotEquals(first.getAbsolutePath(), second.getAbsolutePath());
}
/**
* Test of getRootDir method, of class FileHistoryDao.
*/
@Test
public void testGetRootDir() {
AtomicReference<Calendar> timestampHolder = new AtomicReference<Calendar>();
File result = sutWithoutUserAndDuplicateHistory.getRootDir(test1Config,
timestampHolder);
assertTrue(result.exists());
assertThat(result.getPath(), containsString("config-history"
+ File.separator + "jobs" + File.separator + "Test1"));
}
/**
* Test of createNewItem method, of class FileHistoryDao.
*/
@Test
public void testCreateNewItem() throws IOException {
final File jobDir = new File(jenkinsHome, "jobs/MyTest");
jobDir.mkdirs();
IOUtils.copy(test1Config.getFile(),
new FileOutputStream(new File(jobDir, "config.xml")));
when(mockedItem.getRootDir()).thenReturn(jobDir);
sutWithUserAndNoDuplicateHistory.createNewItem(mockedItem);
assertTrue(new File(jobDir, "config.xml").exists());
final File historyDir = new File(jenkinsHome,
"config-history/jobs/MyTest");
assertTrue(historyDir.exists());
assertEquals(1, historyDir.list().length);
}
/**
* Test of saveItem method, of class FileHistoryDao.
*/
@Test
public void testSaveItem_AbstractItem() throws IOException {
when(mockedItem.getRootDir()).thenReturn(test1JobDirectory);
sutWithUserAndNoDuplicateHistory.saveItem(mockedItem.getConfigFile());
assertEquals(5, getHistoryLength());
}
/**
* Test of saveItem method, of class FileHistoryDao.
*/
@Test
public void testSaveItem_XmlFile() {
sutWithUserAndNoDuplicateHistory.saveItem(test1Config);
assertEquals(5, getHistoryLength());
}
/**
* Test of saveItem method, of class FileHistoryDao.
*/
@Test
public void testSaveItem_XmlFileDuplicate() {
sutWithoutUserAndDuplicateHistory.saveItem(test1Config);
assertEquals(6, getHistoryLength());
}
private int getHistoryLength() {
return test1History.list().length;
}
/**
* Test of deleteItem method, of class FileHistoryDao.
*/
@Test
public void testDeleteItem() {
when(mockedItem.getRootDir()).thenReturn(test1JobDirectory);
sutWithUserAndNoDuplicateHistory.deleteItem(mockedItem);
}
/**
* Test of renameItem method, of class FileHistoryDao.
*/
@Test
public void testRenameItem() throws IOException {
String newName = "NewName";
File newJobDir = unpackResourceZip.getResource("jobs/" + newName);
// Rename of Job is already done in Listener.
FileUtils.touch(new File(newJobDir, "config.xml"));
when(mockedItem.getRootDir()).thenReturn(newJobDir);
when(mockedItem.getName()).thenReturn("Test1");
sutWithUserAndNoDuplicateHistory.renameItem(mockedItem, "Test1",
"NewName");
final File newHistoryDir = new File(historyRoot, "jobs/" + newName);
assertTrue(newHistoryDir.exists());
assertEquals(6, newHistoryDir.list().length);
}
/**
* Test of getRevisions method, of class FileHistoryDao.
*/
@Test
public void testGetRevisions_XmlFile() throws IOException {
SortedMap<String, HistoryDescr> result = sutWithUserAndNoDuplicateHistory
.getRevisions(test1Config);
testGetRevisions(result);
}
private void testGetRevisions(SortedMap<String, HistoryDescr> result) {
assertEquals(5, result.size());
assertEquals("2012-11-21_11-29-12", result.firstKey());
assertEquals("2012-11-21_11-42-05", result.lastKey());
final HistoryDescr firstValue = result.get(result.firstKey());
final HistoryDescr lastValue = result.get(result.lastKey());
assertEquals("Created", firstValue.getOperation());
assertEquals("anonymous", firstValue.getUserID());
assertEquals("Changed", lastValue.getOperation());
}
/**
* Test of getRevisions method, of class FileHistoryDao.
*/
@Test
public void testGetRevisionsForItemWithoutHistory() throws IOException {
final String jobWithoutHistory = "NewJobWithoutHistory";
final File configFile = new File(
unpackResourceZip.getResource("jobs/" + jobWithoutHistory),
"config.xml");
FileUtils.touch(configFile);
assertEquals(0, sutWithUserAndNoDuplicateHistory
.getRevisions(new XmlFile(configFile)).size());
}
/**
* Test of getOldRevision method, of class FileHistoryDao.
*/
@Test
public void testGetOldRevision_Item() throws IOException {
when(mockedItem.getRootDir()).thenReturn(test1JobDirectory);
String identifier = "2012-11-21_11-42-05";
final XmlFile result = sutWithUserAndNoDuplicateHistory
.getOldRevision(mockedItem, identifier);
testGetOldRevision(result);
}
/**
* Test of getOldRevision method, of class FileHistoryDao.
*/
@Test
public void testGetOldRevision_XmlFile() throws IOException {
String identifier = "2012-11-21_11-42-05";
final XmlFile result = sutWithUserAndNoDuplicateHistory
.getOldRevision(test1Config, identifier);
testGetOldRevision(result);
}
private void testGetOldRevision(final XmlFile result) throws IOException {
final String xml = result.asString();
assertThat(xml, startsWith("<?xml version='1.0' encoding='UTF-8'?>"));
assertThat(xml, endsWith("</project>"));
}
/**
* Test of getOldRevision method, of class FileHistoryDao.
*/
@Test
public void testHasOldRevision_Item() throws IOException {
when(mockedItem.getRootDir()).thenReturn(test1JobDirectory);
assertTrue(sutWithUserAndNoDuplicateHistory.hasOldRevision(
mockedItem.getConfigFile(), "2012-11-21_11-42-05"));
assertFalse(sutWithUserAndNoDuplicateHistory.hasOldRevision(
mockedItem.getConfigFile(), "1914-11-21_11-42-05"));
}
/**
* Test of getOldRevision method, of class FileHistoryDao.
*/
@Test
public void testHasOldRevision_XmlFile() throws IOException {
assertTrue(sutWithUserAndNoDuplicateHistory.hasOldRevision(test1Config,
"2012-11-21_11-42-05"));
assertFalse(sutWithUserAndNoDuplicateHistory.hasOldRevision(test1Config,
"1914-11-21_11-42-05"));
}
/**
* Test of getHistoryDir method, of class FileHistoryDao.
*/
@Test
public void testGetHistoryDir() {
final File configFile = test1Config.getFile();
File result = sutWithUserAndNoDuplicateHistory
.getHistoryDir(configFile);
assertEquals(test1History, result);
}
/**
* Test of getHistoryDir method, of class FileHistoryDao.
*/
@Test
public void testGetHistoryDirWithFolder() throws IOException {
String folderName = "FolderName";
final File destDir = unpackResourceZip.getResource(
"config-history/jobs/" + folderName + "/jobs/Test1");
// Create folders
FileUtils.copyDirectory(
unpackResourceZip.getResource("config-history/jobs/Test1"),
destDir);
final File configFile = unpackResourceZip
.getResource("jobs/" + folderName + "/jobs/Test1/config.xml");
File result = sutWithUserAndNoDuplicateHistory
.getHistoryDir(configFile);
assertEquals(destDir, result);
}
/**
* Test of getHistoryDir method, of class FileHistoryDao.
*/
@Test
public void testGetHistoryDirOfSystemXml() throws IOException {
final XmlFile systemXmlFile = new XmlFile(
new File(jenkinsHome, "jenkins.xml"));
final File configFile = systemXmlFile.getFile();
File result = sutWithUserAndNoDuplicateHistory
.getHistoryDir(configFile);
assertThat(result.getPath(), endsWith(File.separatorChar + "jenkins"));
}
/**
* Test of getJobHistoryRootDir method, of class FileHistoryDao.
*/
@Test
public void testGetJobHistoryRootDir() {
assertEquals(unpackResourceZip.getResource("config-history/jobs"),
sutWithUserAndNoDuplicateHistory.getJobHistoryRootDir());
}
/**
* Test of purgeOldEntries method, of class FileHistoryDao.
*/
@Test
public void testPurgeOldEntriesNoEntriesToDelete() {
final int maxEntries = 0;
final int expectedLength = 5;
testPurgeOldEntries(maxEntries, expectedLength);
}
/**
* Test of purgeOldEntries method, of class FileHistoryDao.
*/
@Test
public void testPurgeOldEntriesOnlyTwoExistingOneBecauseOfCreatedStatus() {
final int maxEntries = 2;
final int expectedLength = 2;
testPurgeOldEntries(maxEntries, expectedLength);
}
private void testPurgeOldEntries(int maxEntries, final int expectedLength) {
sutWithUserAndNoDuplicateHistory.purgeOldEntries(test1History,
maxEntries);
final int newLength = getHistoryLength();
assertEquals(expectedLength, newLength);
}
/**
* Test of hasDuplicateHistory method, of class FileHistoryDao.
*/
@Test
public void testHasDuplicateHistoryNoDuplicates() throws IOException {
XmlFile xmlFile = new XmlFile(
new File(test1History, "2012-11-21_11-41-14/history.xml"));
final File configFile = new File(test1JobDirectory, "config.xml");
IOUtils.write(xmlFile.asString(), new FileOutputStream(configFile));
boolean result = sutWithUserAndNoDuplicateHistory
.hasDuplicateHistory(new XmlFile(configFile));
assertEquals(false, result);
}
/**
* Test of hasDuplicateHistory method, of class FileHistoryDao.
*/
@Test
public void testHasDuplicateHistoryDuplicates() throws IOException {
final File configFile = new File(test1JobDirectory, "config.xml");
boolean result = sutWithUserAndNoDuplicateHistory
.hasDuplicateHistory(new XmlFile(configFile));
assertEquals(true, result);
}
/**
* Test of hasDuplicateHistory method, of class FileHistoryDao.
*/
@Test
public void testHasDuplicateHistoryNoHistory() throws IOException {
final File configFile = new File(jenkinsHome, "jobs/Test2/config.xml");
boolean result = sutWithUserAndNoDuplicateHistory
.hasDuplicateHistory(new XmlFile(configFile));
assertEquals(false, result);
}
/**
* Test of checkDuplicate method, of class FileHistoryDao.
*/
@Test
public void testCheckDuplicate() throws IOException {
XmlFile xmlFile = new XmlFile(
new File(test1JobDirectory, "config.xml"));
boolean result = sutWithoutUserAndDuplicateHistory
.checkDuplicate(xmlFile);
assertEquals(true, result);
}
/**
* Test of checkDuplicate method, of class FileHistoryDao.
*/
@Test
public void testCheckDuplicateSkip() {
XmlFile xmlFile = new XmlFile(
new File(test1JobDirectory, "config.xml"));
boolean result = sutWithUserAndNoDuplicateHistory
.checkDuplicate(xmlFile);
assertEquals(false, result);
}
/**
* Test of checkDuplicate method, of class FileHistoryDao.
*/
@Test
public void testCheckDuplicateHasDuplicate() {
XmlFile xmlFile = new XmlFile(
new File(jenkinsHome, "jobs/Test2/config.xml"));
boolean result = sutWithUserAndNoDuplicateHistory
.checkDuplicate(xmlFile);
assertEquals(true, result);
}
/**
* Test of getSystemConfigs method, of class FileHistoryDao.
*/
@Test
public void testGetSystemConfigs() {
final File[] systemConfigs = sutWithoutUserAndDuplicateHistory
.getSystemConfigs();
assertEquals(1, systemConfigs.length);
assertEquals("config", systemConfigs[0].getName());
}
/**
* Test of getSystemConfigs method, of class FileHistoryDao.
*/
@Test
public void testGetSystemConfigsWithoutData() {
new File(jenkinsHome, "config-history")
.renameTo(new File(jenkinsHome, "invalid"));
final File[] systemConfigs = sutWithoutUserAndDuplicateHistory
.getSystemConfigs();
assertEquals(0, systemConfigs.length);
}
/**
* Test of getDeletedJobs method, of class FileHistoryDao.
*/
@Test
public void testGetDeletedJobs() {
final File[] deletedJobs = sutWithoutUserAndDuplicateHistory
.getDeletedJobs("");
assertEquals(1, deletedJobs.length);
final String name = deletedJobs[0].getName();
assertThat(name, containsString("Foo"));
}
/**
* Test of getDeletedJobs method, of class FileHistoryDao.
*/
@Test
public void testGetJobs() {
final File[] jobs = sutWithoutUserAndDuplicateHistory.getJobs("");
assertEquals(1, jobs.length);
final String name = jobs[0].getName();
assertThat(name, containsString("Test1"));
}
/**
* Test of getJobHistory method, of class FileHistoryDao.
*/
@Test
public void testGetJobHistory() {
final SortedMap<String, HistoryDescr> result = sutWithUserAndNoDuplicateHistory
.getJobHistory("Test1");
assertEquals(5, result.size());
assertEquals("2012-11-21_11-29-12", result.firstKey());
}
/**
* Test of getJobHistory method, of class FileHistoryDao.
*/
@Test
public void testGetJobHistoryNonExistent() {
final SortedMap<String, HistoryDescr> result = sutWithUserAndNoDuplicateHistory
.getJobHistory("JobDoesNotExist");
assertTrue(result.isEmpty());
}
/**
* Test of getSystemHistory method, of class FileHistoryDao.
*/
@Test
public void testGetSystemHistory() {
final SortedMap<String, HistoryDescr> result = sutWithUserAndNoDuplicateHistory
.getSystemHistory("config");
assertEquals(5, result.size());
assertEquals("2013-01-18_17-34-22", result.firstKey());
}
/**
* Test of getSystemHistory method, of class FileHistoryDao.
*/
@Test
public void testGetSystemHistoryNonExistent() {
final SortedMap<String, HistoryDescr> result = sutWithUserAndNoDuplicateHistory
.getSystemHistory("config-does-not-exist");
assertTrue(result.isEmpty());
}
/**
* Test of copyHistoryAndDelete method, of class FileHistoryDao.
*/
@Test
public void testMoveHistory() {
sutWithUserAndNoDuplicateHistory
.copyHistoryAndDelete("Foo_deleted_20130830_223932_071", "Foo");
assertEquals(3,
sutWithUserAndNoDuplicateHistory.getJobHistory("Foo").size());
}
/**
* Test of copyHistoryAndDelete method, of class FileHistoryDao.
*/
@Test(expected = IllegalArgumentException.class)
public void testMoveHistoryIOException() {
sutWithUserAndNoDuplicateHistory.copyHistoryAndDelete("Test1", "Test1");
}
@Test
public void testCreateNewNode() throws Exception {
when(mockedNode.getNodeName()).thenReturn("slave1");
sutWithUserAndNoDuplicateHistory.createNewNode(mockedNode);
File file = sutWithUserAndNoDuplicateHistory.getNodeHistoryRootDir();
File revisions = new File(file, "slave1");
assertEquals("Slave1 should have only one save history.", 1,
revisions.list().length);
File config = new File(revisions.listFiles()[0], "config.xml");
assertTrue("File config.xml should be saved.", config.exists());
File history = new File(revisions.listFiles()[0],
JobConfigHistoryConsts.HISTORY_FILE);
assertTrue("File history.xml should be saved.", history.exists());
}
/**
* Runs a test, which renames or deletes a node. This method decouples the
* shared logic from {@link #testDeleteNode()} and
* {@link #testRenameNode()}.
*/
private void printTestData(Callable<Void> func) throws Exception {
when(mockedNode.getNodeName()).thenReturn("slave1");
File file = sutWithUserAndNoDuplicateHistory.getNodeHistoryRootDir();
File revisions = new File(file, "slave1");
File revision = new File(revisions, "2014-01-20_10-12-34");
revision.mkdirs();
File config = new File(revision, "config.xml");
File history = new File(revision, JobConfigHistoryConsts.HISTORY_FILE);
HistoryDescr descr = new HistoryDescr("User", "user", "created",
"2014-01-20_10-12-34", null, null);
OutputStream configsFile = new PrintStream(config);
OutputStream historyFile = new FileOutputStream(history);
try {
Jenkins.XSTREAM2.toXMLUTF8(mockedNode, configsFile);
Jenkins.XSTREAM2.toXMLUTF8(descr, historyFile);
} finally {
configsFile.close();
historyFile.close();
}
// Call method an check that all files have been deleted
func.call();
assertFalse("File config.xml should be deleted.", config.exists());
assertFalse("File history.xml should be deleted.", history.exists());
assertFalse("Previous revision directory should be deleted",
revision.exists());
}
@Test
public void testDeleteNode() throws Exception {
printTestData(new Callable<Void>() {
@Override
public Void call() throws Exception {
sutWithUserAndNoDuplicateHistory.deleteNode(mockedNode);
return null;
}
});
}
@Test
public void testRenameNode() throws Exception {
printTestData(new Callable<Void>() {
@Override
public Void call() throws Exception {
sutWithUserAndNoDuplicateHistory.renameNode(mockedNode,
mockedNode.getNodeName(),
mockedNode.getNodeName() + "_renamed");
return null;
}
});
}
@Test
public void testGetRevisions() throws Exception {
when(mockedNode.getNodeName()).thenReturn("slave1");
createNodeRevision("2014-01-18_10-12-34", mockedNode);
createNodeRevision("2014-01-19_10-12-34", mockedNode);
createNodeRevision("2014-01-20_10-12-34", mockedNode);
createNodeRevision("2014-01-20_10-21-34", mockedNode);
SortedMap<String, HistoryDescr> revisions = sutWithUserAndNoDuplicateHistory
.getRevisions(mockedNode);
assertNotNull("Revisiosn 2014-01-18_10-12-34 should be returned.",
revisions.get("2014-01-18_10-12-34"));
assertNotNull("Revisiosn 2014-01-19_10-12-34 should be returned.",
revisions.get("2014-01-19_10-12-34"));
assertNotNull("Revisiosn 2014-01-20_10-12-34 should be returned.",
revisions.get("2014-01-20_10-12-34"));
assertNotNull("Revisiosn 2014-01-20_10-21-34 should be returned.",
revisions.get("2014-01-20_10-21-34"));
}
private File createNodeRevision(String timestamp, Node mockedNode)
throws Exception {
File file = sutWithUserAndNoDuplicateHistory.getNodeHistoryRootDir();
File revisions = new File(file, "slave1");
File revision = new File(revisions, timestamp);
revision.mkdirs();
Jenkins.XSTREAM2.toXMLUTF8(mockedNode,
new PrintStream(new File(revision, "config.xml")));
HistoryDescr descr = new HistoryDescr("User", "user", "created",
timestamp, null, null);
Jenkins.XSTREAM2.toXMLUTF8(descr, new FileOutputStream(
new File(revision, JobConfigHistoryConsts.HISTORY_FILE)));
return revision;
}
@Test
public void testSaveNode() {
when(mockedNode.getNodeName()).thenReturn("slave1");
File file = sutWithUserAndNoDuplicateHistory.getNodeHistoryRootDir();
File revisions = new File(file, "slave1");
sutWithUserAndNoDuplicateHistory.saveNode(mockedNode);
assertEquals("New revision should be saved.", 1,
revisions.list().length);
}
@Test
public void testGetOldRevision_Node() throws Exception {
when(mockedNode.getNodeName()).thenReturn("slave1");
when(mockedNode.getNumExecutors()).thenReturn(1);
File revision1 = createNodeRevision("2014-01-18_10-12-34", mockedNode);
when(mockedNode.getNumExecutors()).thenReturn(2);
File revision2 = createNodeRevision("2014-01-19_10-12-34", mockedNode);
when(mockedNode.getNumExecutors()).thenReturn(3);
File revision3 = createNodeRevision("2014-01-20_10-12-34", mockedNode);
XmlFile file1 = sutWithUserAndNoDuplicateHistory
.getOldRevision(mockedNode, "2014-01-18_10-12-34");
XmlFile file2 = sutWithUserAndNoDuplicateHistory
.getOldRevision(mockedNode, "2014-01-19_10-12-34");
XmlFile file3 = sutWithUserAndNoDuplicateHistory
.getOldRevision(mockedNode, "2014-01-20_10-12-34");
assertEquals(
"Should return config.xml file of revision 2014-01-18_10-12-34",
new File(revision1, "config.xml").getAbsolutePath(),
file1.getFile().getAbsolutePath());
assertEquals(
"Should return config.xml file of revision 2014-01-19_10-12-34",
new File(revision2, "config.xml").getAbsolutePath(),
file2.getFile().getAbsolutePath());
assertEquals(
"Should return config.xml file of revision 2014-01-20_10-12-34",
new File(revision3, "config.xml").getAbsolutePath(),
file3.getFile().getAbsolutePath());
}
}