Skip to content
Permalink
Browse files

JENKINS-15681: Support for Cloudbees Folders

  • Loading branch information...
tofuatgit committed Dec 8, 2012
1 parent 5f80b49 commit 85a3c94074a24d7f513bd445c14b34c39be04eae
@@ -0,0 +1 @@
/target
20 pom.xml
@@ -86,12 +86,30 @@
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<artifactId>junit-dep</artifactId>
<version>4.10</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
@@ -16,6 +16,7 @@
*/
package org.jvnet.hudson.plugins.thinbackup.backup;

import groovy.swing.factory.HBoxFactory;
import hudson.PluginWrapper;
import hudson.model.Hudson;

@@ -46,6 +47,7 @@
import org.jvnet.hudson.plugins.thinbackup.utils.Utils;

public class HudsonBackup {

private static final Logger LOGGER = Logger.getLogger("hudson.plugins.thinbackup");

public static final String BUILDS_DIR_NAME = "builds";
@@ -55,6 +57,7 @@
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 CONFIG_XML = "config.xml";
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;
@@ -163,39 +166,48 @@ private void backupJobs() throws IOException {
final File jobsDirectory = new File(hudsonHome.getAbsolutePath(), JOBS_DIR_NAME);
final File jobsBackupDirectory = new File(backupDirectory.getAbsolutePath(), JOBS_DIR_NAME);

Collection<String> jobNames;
final Hudson hudson = Hudson.getInstance();
if (hudson != null) {
jobNames = hudson.getJobNames();
} else {
jobNames = Arrays.asList(jobsDirectory.list());
}
backupJobsDirectory(jobsDirectory, jobsBackupDirectory);
LOGGER.fine("DONE backing up job specific configuration files.");
}

private void backupJobsDirectory(final File jobsDirectory, final File jobsBackupDirectory) throws IOException {
Collection<String> jobNames = Arrays.asList(jobsDirectory.list());
LOGGER.info(String.format("Found %d jobs to back up.", jobNames.size()));
LOGGER.fine(String.format("\t%s", jobNames));
LOGGER.fine(String.format("\t%s", jobNames));

for (final String jobName : jobNames) {
final File jobDirectory = new File(jobsDirectory, jobName);
if (jobDirectory.exists()) { // sub jobs e.g. maven modules need not be copied
if (jobDirectory.canRead()) {
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);
}
}

File childJobsFolder = new File(jobDirectory, HudsonBackup.JOBS_DIR_NAME);
if (childJobsFolder.exists()) { // found CloudBeesFolder
File folderBackupDirectory = new File(jobsBackupDirectory, jobName);
File folderJobsBackupDirectory = new File(folderBackupDirectory, JOBS_DIR_NAME);
folderJobsBackupDirectory.mkdirs();
FileUtils.copyFile(new File(jobDirectory, CONFIG_XML), new File(folderBackupDirectory, CONFIG_XML));
backupJobsDirectory(childJobsFolder, folderJobsBackupDirectory);
} else
backupJob(jobDirectory, jobsBackupDirectory, jobName);
} else {
final String msg = String.format("Read access denied on directory '%s', cannot back up the job '%s'.", jobDirectory.getAbsolutePath(), jobName);
LOGGER.severe(msg);
}
}
}
LOGGER.fine("DONE backing up job specific configuration files.");
}

private void backupJob(final File jobDirectory, final File jobsBackupDirectory, final String jobName) 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);
}
}
}

private File createConfigurationBackupDirectory(File jobBackupdirectory, File jobDirectory, File configurationDirectory) {
@@ -207,7 +219,7 @@ private File createConfigurationBackupDirectory(File jobBackupdirectory, File jo

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

List<File> confs = new ArrayList<File>();
for (File file : listFiles) {
@@ -1,7 +1,11 @@
package org.jvnet.hudson.plugins.thinbackup;

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

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
@@ -40,15 +44,21 @@ public static File createBackupFolder(File base) {
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");
public static File createCloudBeesFolder(File jenkinsHome, String folderName) throws FileNotFoundException, IOException {
final File folderDir = new File(new File(jenkinsHome, HudsonBackup.JOBS_DIR_NAME), folderName);
folderDir.mkdirs();

final File config = new File(folderDir, "config.xml");
config.createNewFile();
final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(config));
out.write(new ByteArrayBuffer(CONFIG_XML_CONTENTS).array());
out.close();

return folderDir;
}

public static File createJob(File jenkinsHome, String jobName) throws IOException {
final File testJob = createJobsFolderWithConfiguration(jenkinsHome, jobName);
final File nextBuildNumberFile = new File(testJob, HudsonBackup.NEXT_BUILD_NUMBER_FILE_NAME);
nextBuildNumberFile.createNewFile();
addBuildNumber(nextBuildNumberFile);
@@ -58,6 +68,17 @@ public static File createJob(File jenkinsHome, String jobName) throws IOExceptio

return testJob;
}

private static File createJobsFolderWithConfiguration(File jenkinsHome, String jobName) throws IOException, FileNotFoundException {
final File testJob = new File(new File(jenkinsHome, HudsonBackup.JOBS_DIR_NAME), jobName);
testJob.mkdirs();
final File config = new File(testJob, "config.xml");
config.createNewFile();
final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(config));
out.write(new ByteArrayBuffer(CONFIG_XML_CONTENTS).array());
out.close();
return testJob;
}

public static File addNewBuildToJob(File job) throws IOException {
final File builds = new File(job, HudsonBackup.BUILDS_DIR_NAME);
@@ -138,4 +159,22 @@ private static void addBuildNumber(final File nextBuildNumberFile) {
}
}
}

public static ThinBackupPluginImpl createMockPlugin(File jenkinsHome, File backupDir) {
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;
}
}
@@ -0,0 +1,92 @@
package org.jvnet.hudson.plugins.thinbackup.backup;

import static org.junit.Assert.*;

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

import org.apache.commons.io.FileUtils;
import org.hamcrest.Matchers;
import org.junit.Assert;
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.utils.Utils;
import org.jvnet.hudson.plugins.thinbackup.ThinBackupPluginImpl;

public class TestBackupWithCloudBeesFolder {
private static final String TEST_FOLDER = "testFolder";
private File backupDir;
private File jenkinsHome;
private File cloudBeesFolder;

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

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

}

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

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

final ThinBackupPluginImpl mockPlugin = TestHelper.createMockPlugin(jenkinsHome, backupDir);
new HudsonBackup(mockPlugin, BackupType.FULL, cal.getTime()).backup();

final File backup = new File(backupDir, backupDir.list()[0]);
File rootJobsFolder = new File(backup, HudsonBackup.JOBS_DIR_NAME);
String[] list = rootJobsFolder.list();
Assert.assertThat(list, Matchers.arrayContainingInAnyOrder(TEST_FOLDER));

File cloudBeesFolder = new File(rootJobsFolder, list[0]);
list = cloudBeesFolder.list();
Assert.assertThat(list, Matchers.arrayContainingInAnyOrder(HudsonBackup.JOBS_DIR_NAME, HudsonBackup.CONFIG_XML));

File childJobsFolder = new File(cloudBeesFolder, HudsonBackup.JOBS_DIR_NAME);
list = childJobsFolder.list();
Assert.assertThat(list, Matchers.arrayContainingInAnyOrder(TestHelper.TEST_JOB_NAME));

File jobFolder = new File(childJobsFolder, TestHelper.TEST_JOB_NAME);
list = jobFolder.list();
Assert.assertThat(list, Matchers.arrayContainingInAnyOrder(HudsonBackup.BUILDS_DIR_NAME, HudsonBackup.CONFIG_XML));
}

@Test
public void testRecursiveFolderBackup() throws Exception {
File subFolderDirectory = TestHelper.createCloudBeesFolder(cloudBeesFolder, "subFolder");
TestHelper.createJob(subFolderDirectory, "folderJob");

final Calendar cal = Calendar.getInstance();
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE - 10));

final ThinBackupPluginImpl mockPlugin = TestHelper.createMockPlugin(jenkinsHome, backupDir);
new HudsonBackup(mockPlugin, BackupType.FULL, cal.getTime()).backup();

File subFolderJobsBackupDirectory = new File(backupDir, backupDir.list()[0]+"/jobs/"+TEST_FOLDER+"/jobs/subFolder/jobs");
String[] list = subFolderJobsBackupDirectory.list();
Assert.assertThat(list , Matchers.arrayContainingInAnyOrder("folderJob"));

File jobFolder = new File(subFolderJobsBackupDirectory, "folderJob");
list = jobFolder.list();
Assert.assertThat(list, Matchers.arrayContainingInAnyOrder(HudsonBackup.CONFIG_XML));
}

}

1 comment on commit 85a3c94

@jglick

This comment has been minimized.

Copy link
Member

jglick commented on 85a3c94 Jan 3, 2013

BTW probably irrelevant for these tests (since you seem to be working at the File level), but MockFolder in newer cores can be used to test behavior against folder-like Items.

Please sign in to comment.
You can’t perform that action at this time.