Skip to content

Commit

Permalink
JENKINS-12173: thinBackup does not include build results for matrix p…
Browse files Browse the repository at this point in the history
…rojects when nodes axis is used

git-svn-id: https://svn.jenkins-ci.org/trunk/hudson/plugins/thinBackup@40679 71c3de6d-444a-0410-be80-ed276b4c234a
  • Loading branch information
tofuatjava committed Jul 25, 2012
1 parent e125d99 commit 34b45f4
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 125 deletions.
Expand Up @@ -21,8 +21,10 @@

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -39,6 +41,7 @@
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.jvnet.hudson.plugins.thinbackup.ThinBackupPeriodicWork.BackupType;
import org.jvnet.hudson.plugins.thinbackup.ThinBackupPluginImpl;
import org.jvnet.hudson.plugins.thinbackup.utils.Utils;
Expand All @@ -47,11 +50,12 @@ public class HudsonBackup {
private static final Logger LOGGER = Logger.getLogger("hudson.plugins.thinbackup");

public static final String BUILDS_DIR_NAME = "builds";
public static final String CONFIGURATIONS_DIR_NAME = "configurations";
public static final String JOBS_DIR_NAME = "jobs";
public static final String USERS_DIR_NAME = "users";
public static final String ARCHIVE_DIR_NAME = "archive";
public static final String USERSCONTENTS_DIR_NAME = "userContent";
public static final String NEXT_BUILD_NUMBER_FILE_NAME = "nextBuildNumber";
public static final String ARCHIVE_DIR_NAME = "archive";
public static final String XML_FILE_EXTENSION = ".xml";
public static final String ZIP_FILE_EXTENSION = ".zip";
public static final String INSTALLED_PLUGINS_XML = "installedPlugins" + XML_FILE_EXTENSION;
Expand Down Expand Up @@ -178,6 +182,15 @@ private void backupJobs() throws IOException {
final File jobBackupDirectory = new File(jobsBackupDirectory, jobName);
backupJobConfigFor(jobDirectory, jobBackupDirectory);
backupBuildsFor(jobDirectory, jobBackupDirectory);
if (isMatrixJob(jobDirectory)) {
List<File> configurations = findAllConfigurations(new File(jobDirectory, HudsonBackup.CONFIGURATIONS_DIR_NAME));
for (File configurationDirectory : configurations) {
File configurationBackupDirectory = createConfigurationBackupDirectory(jobBackupDirectory, jobDirectory, configurationDirectory);
backupJobConfigFor(configurationDirectory, configurationBackupDirectory);
backupBuildsFor(configurationDirectory, configurationBackupDirectory);
}
}

} else {
final String msg = String.format("Read access denied on directory '%s', cannot back up the job '%s'.",
jobDirectory.getAbsolutePath(), jobName);
Expand All @@ -188,6 +201,28 @@ private void backupJobs() throws IOException {
LOGGER.fine("DONE backing up job specific configuration files.");
}

private File createConfigurationBackupDirectory(File jobBackupdirectory, File jobDirectory, File configurationDirectory) {
String pathToConfiguration = configurationDirectory.getAbsolutePath();
String pathToJob = jobDirectory.getAbsolutePath();

return new File(jobBackupdirectory, pathToConfiguration.substring(pathToJob.length()));
}

private List<File> findAllConfigurations(File dir) {
Collection<File> listFiles = FileUtils.listFiles(dir, FileFilterUtils.nameFileFilter("config.xml"), TrueFileFilter.INSTANCE);

List<File> confs = new ArrayList<File>();
for (File file : listFiles) {
confs.add(file.getParentFile());
}

return confs;
}

private boolean isMatrixJob(File jobDirectory) {
return new File(jobDirectory, CONFIGURATIONS_DIR_NAME).isDirectory();
}

private void backupJobConfigFor(final File jobDirectory, final File jobBackupDirectory) throws IOException {
IOFileFilter filter = FileFilterUtils.suffixFileFilter(XML_FILE_EXTENSION);
filter = FileFilterUtils.andFileFilter(filter, getFileAgeDiffFilter());
Expand Down Expand Up @@ -239,7 +274,7 @@ private void backupBuildFiles(final File srcDir, final File destDir) throws IOEx
private void backupBuildArchive(final File buildSrcDir, final File buildDestDir) throws IOException {
if (plugin.isBackupBuildArchive()) {
final File archiveSrcDir = new File(buildSrcDir, ARCHIVE_DIR_NAME);
if (archiveSrcDir.exists() && archiveSrcDir.isDirectory()) {
if (archiveSrcDir.isDirectory()) {
final IOFileFilter filter = FileFilterUtils.andFileFilter(FileFileFilter.FILE, getFileAgeDiffFilter());
FileUtils.copyDirectory(archiveSrcDir, new File(buildDestDir, "archive"), filter);
}
Expand Down Expand Up @@ -390,7 +425,6 @@ private Date getLatestFullBackupDate() {

return result;
}

}

/**
Expand All @@ -417,5 +451,4 @@ public void run() {
}
LOGGER.fine("DONE zipping.");
}

}
Expand Up @@ -8,45 +8,41 @@
import java.io.Writer;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.jvnet.hudson.plugins.thinbackup.backup.HudsonBackup;
import org.jvnet.hudson.plugins.thinbackup.utils.Utils;
import org.mortbay.io.ByteArrayBuffer;

public class HudsonDirectoryStructureSetup {

public class TestHelper {
public static final String CONFIG_XML_CONTENTS = "FILLED WITH DATA... ";
public static final String CONCRET_BUILD_DIRECTORY_NAME = "2011-01-08_22-26-40";
public static final String TEST_JOB_NAME = "test";
public static final String BACKUP_DIRECTORY_NAME = "2011-01-08_22-26-40";

protected File root;
protected File backupDir;

protected List<String> originalFiles;

public HudsonDirectoryStructureSetup() {
super();
}

@Before
public void setup() throws Exception {
final File tempDir = new File(System.getProperty("java.io.tmpdir"));
root = new File(tempDir, "RootDirForHudsonBackupTest");
public static File createBasicFolderStructure(File base) throws IOException {
File root = new File(base, "RootDirForHudsonBackupTest");
root.mkdir();
backupDir = new File(tempDir, "BackupDirForHudsonBackupTest");
backupDir.mkdir();

new File(root, "config.xml").createNewFile();
new File(root, "thinBackup.xml").createNewFile();
new File(root, "secret.key").createNewFile();
new File(root, "nodeMonitors.xml").createNewFile();
new File(root, "hudson.model.UpdateCenter.xml").createNewFile();

final File jobsDir = new File(root, HudsonBackup.JOBS_DIR_NAME);
jobsDir.mkdir();
final File testJob = new File(jobsDir, TEST_JOB_NAME);
new File(root, HudsonBackup.JOBS_DIR_NAME).mkdir();
new File(root, HudsonBackup.USERS_DIR_NAME).mkdir();
new File(root, HudsonBackup.USERSCONTENTS_DIR_NAME).mkdir();
new File(root, "plugins").mkdir();

return root;
}

public static File createBackupFolder(File base) {
File backupDir = new File(base, "BackupDirForHudsonBackupTest");
backupDir.mkdir();

return backupDir;
}

public static File createJob(File jenkinsHome, String jobName) throws IOException {
final File jobsDir = new File(jenkinsHome, HudsonBackup.JOBS_DIR_NAME);
final File testJob = new File(jobsDir , jobName);
testJob.mkdir();
final File config = new File(testJob, "config.xml");
config.createNewFile();
Expand All @@ -56,33 +52,76 @@ public void setup() throws Exception {
final File nextBuildNumberFile = new File(testJob, HudsonBackup.NEXT_BUILD_NUMBER_FILE_NAME);
nextBuildNumberFile.createNewFile();
addBuildNumber(nextBuildNumberFile);
new File(testJob, "workspace").mkdir();
new File(testJob, "modules").mkdir();
final File builds = new File(testJob, HudsonBackup.BUILDS_DIR_NAME);
File workspace = new File(testJob, "workspace");
workspace.mkdir();
new File(workspace, "neverBackupMe.txt").createNewFile();

return testJob;
}

public static File addNewBuildToJob(File job) throws IOException {
final File builds = new File(job, HudsonBackup.BUILDS_DIR_NAME);
builds.mkdir();
final File build = new File(builds, BACKUP_DIRECTORY_NAME);
final File build = new File(builds, CONCRET_BUILD_DIRECTORY_NAME);
build.mkdir();

final File changelogDir = new File(build, HudsonBackup.CHANGELOG_HISTORY_PLUGIN_DIR_NAME);
changelogDir.mkdir();
new File(changelogDir, "1.xml").createNewFile();
new File(changelogDir, "2.xml").createNewFile();

final File archiveDir = new File(build, HudsonBackup.ARCHIVE_DIR_NAME);
archiveDir.mkdir();
new File(build, "build.xml").createNewFile();
new File(build, "changelog.xml").createNewFile();
new File(build, "log").createNewFile();
new File(build, "revision.txt").createNewFile();
new File(build, "logfile.log").createNewFile();
new File(build, "logfile.xlog").createNewFile();

final File archiveDir = new File(build, HudsonBackup.ARCHIVE_DIR_NAME);
archiveDir.mkdir();
new File(archiveDir, "someFile.log").createNewFile();

final FileCollector fc = new FileCollector();
originalFiles = fc.getFilesAsString(root);

return build;
}

public static void addSingleConfigurationResult(File job) throws IOException {
File configurations = new File(job, HudsonBackup.CONFIGURATIONS_DIR_NAME);
configurations.mkdir();
File axis_x = new File(configurations, "axis-x");
axis_x.mkdir();
File xValueA = new File(axis_x, "a");
xValueA.mkdir();
File xValueB = new File(axis_x, "b");
xValueB.mkdir();

addNewBuildToJob(xValueA);
addNewBuildToJob(xValueB);

new File(xValueA, "config.xml").createNewFile();
File nextBuildnumber = new File(xValueA, "nextBuildNumber");
nextBuildnumber.createNewFile();
addBuildNumber(nextBuildnumber);

new File(xValueB, "config.xml").createNewFile();
nextBuildnumber = new File(xValueB, "nextBuildNumber");
nextBuildnumber.createNewFile();
addBuildNumber(nextBuildnumber);
}

public static boolean containsStringEndingWith(final List<String> strings, final String pattern) {
boolean contains = false;

private void addBuildNumber(final File nextBuildNumberFile) {
for (final String string : strings) {
if (string.endsWith(pattern)) {
contains = true;
break;
}
}

return contains;
}

private static void addBuildNumber(final File nextBuildNumberFile) {
Writer w = null;
try {
w = new FileWriter(nextBuildNumberFile);
Expand All @@ -99,25 +138,4 @@ private void addBuildNumber(final File nextBuildNumberFile) {
}
}
}

@After
public void tearDown() throws Exception {
FileUtils.deleteDirectory(root);
FileUtils.deleteDirectory(backupDir);
FileUtils.deleteDirectory(new File(Utils.THINBACKUP_TMP_DIR));
}

protected boolean containsStringEndingWith(final List<String> strings, final String pattern) {
boolean contains = false;

for (final String string : strings) {
if (string.endsWith(pattern)) {
contains = true;
break;
}
}

return contains;
}

}
@@ -0,0 +1,89 @@
package org.jvnet.hudson.plugins.thinbackup.backup;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import groovy.swing.factory.HBoxFactory;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;

import junit.framework.Assert;

import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.jvnet.hudson.plugins.thinbackup.TestHelper;
import org.jvnet.hudson.plugins.thinbackup.ThinBackupPeriodicWork.BackupType;
import org.jvnet.hudson.plugins.thinbackup.ThinBackupPluginImpl;
import org.jvnet.hudson.plugins.thinbackup.utils.Utils;

public class TestBackupMatrixJob {

private File backupDir;
private File jenkinsHome;

@Before
public void setup() throws IOException {
File base = new File(System.getProperty("java.io.tmpdir"));
backupDir = TestHelper.createBackupFolder(base);

jenkinsHome = TestHelper.createBasicFolderStructure(base);
File jobDir = TestHelper.createJob(jenkinsHome, TestHelper.TEST_JOB_NAME);
TestHelper.addNewBuildToJob(jobDir);

TestHelper.addSingleConfigurationResult(jobDir);
}

@After
public void tearDown() throws Exception {
FileUtils.deleteDirectory(jenkinsHome);
FileUtils.deleteDirectory(backupDir);
FileUtils.deleteDirectory(new File(Utils.THINBACKUP_TMP_DIR));
}

private ThinBackupPluginImpl createMockPlugin() {
final ThinBackupPluginImpl mockPlugin = mock(ThinBackupPluginImpl.class);

when(mockPlugin.getHudsonHome()).thenReturn(jenkinsHome);
when(mockPlugin.getFullBackupSchedule()).thenReturn("");
when(mockPlugin.getDiffBackupSchedule()).thenReturn("");
when(mockPlugin.getExpandedBackupPath()).thenReturn(backupDir.getAbsolutePath());
when(mockPlugin.getNrMaxStoredFull()).thenReturn(-1);
when(mockPlugin.isCleanupDiff()).thenReturn(false);
when(mockPlugin.isMoveOldBackupsToZipFile()).thenReturn(false);
when(mockPlugin.isBackupBuildResults()).thenReturn(true);
when(mockPlugin.isBackupBuildArchive()).thenReturn(false);
when(mockPlugin.isBackupNextBuildNumber()).thenReturn(false);
when(mockPlugin.getExcludedFilesRegex()).thenReturn("");

return mockPlugin;
}

@Test
public void testFullBuildResultsBackup() throws IOException {
final Calendar cal = Calendar.getInstance();
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE - 10));

final ThinBackupPluginImpl mockPlugin = createMockPlugin();

new HudsonBackup(mockPlugin, BackupType.FULL, cal.getTime()).backup();

String[] list = backupDir.list();
Assert.assertEquals(1, list.length);
final File backup = new File(backupDir, list[0]);
list = backup.list();
Assert.assertEquals(6, list.length);

File jobBackup = new File(backup, "jobs/"+TestHelper.TEST_JOB_NAME);

Assert.assertTrue(new File(jobBackup, HudsonBackup.CONFIGURATIONS_DIR_NAME).exists());
Assert.assertTrue(new File(jobBackup, HudsonBackup.CONFIGURATIONS_DIR_NAME+"/axis-x/a").exists());
Assert.assertTrue(new File(jobBackup, HudsonBackup.CONFIGURATIONS_DIR_NAME+"/axis-x/b").exists());
Assert.assertTrue(new File(jobBackup, HudsonBackup.CONFIGURATIONS_DIR_NAME+"/axis-x/a/"+HudsonBackup.BUILDS_DIR_NAME+"/"+TestHelper.CONCRET_BUILD_DIRECTORY_NAME+"/build.xml").exists());
Assert.assertTrue(new File(jobBackup, HudsonBackup.CONFIGURATIONS_DIR_NAME+"/axis-x/b/"+HudsonBackup.BUILDS_DIR_NAME+"/"+TestHelper.CONCRET_BUILD_DIRECTORY_NAME+"/build.xml").exists());
}

}

0 comments on commit 34b45f4

Please sign in to comment.