package co.codewizards.cloudstore.test.repotorepo; import static co.codewizards.cloudstore.core.io.StreamUtil.*; import static co.codewizards.cloudstore.core.oio.OioFileFactory.*; import static org.assertj.core.api.Assertions.*; import co.codewizards.cloudstore.core.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Properties; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import co.codewizards.cloudstore.core.oio.File; import co.codewizards.cloudstore.core.progress.LoggerProgressMonitor; import co.codewizards.cloudstore.core.progress.NullProgressMonitor; import co.codewizards.cloudstore.core.repo.local.LocalRepoManager; import co.codewizards.cloudstore.core.repo.sync.RepoToRepoSync; import co.codewizards.cloudstore.core.util.IOUtil; import co.codewizards.cloudstore.core.util.PropertiesUtil; import co.codewizards.cloudstore.test.AbstractRepoAwareIT; public class IgnoreRulesRepoToRepoSyncIT extends AbstractRepoAwareIT { private static final Logger logger = LoggerFactory.getLogger(IgnoreRulesRepoToRepoSyncIT.class); @Test public void ignoreRulesExistBeforeAffectedFiles() throws Exception { createLocalAndRemoteRepo(); final LocalRepoManager localRepoManagerRemote = localRepoManagerFactory.createLocalRepoManagerForExistingRepository(remoteRoot); final File child_1 = createDirectory(remoteRoot, "1"); final File child_1_a = createFileWithRandomContent(child_1, "a"); final File child_1_b = createFileWithRandomContent(child_1, "b"); localRepoManagerRemote.localSync(new NullProgressMonitor()); assertThatFilesInRepoAreCorrect(remoteRoot); final RepoToRepoSync repoToRepoSync = RepoToRepoSync.create(getLocalRootWithPathPrefix(), remoteRootURLWithPathPrefix); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); assertThatFilesInRepoAreCorrect(remoteRoot); assertDirectoriesAreEqualRecursively(getLocalRootWithPathPrefix(), getRemoteRootWithPathPrefix()); // Create and sync ignore rules. Properties properties = new Properties(); properties.put("ignore[0].namePattern", "a"); // ignore a file that already exists and was already synced properties.put("ignore[1].namePattern", "c"); // ignore a new file PropertiesUtil.store(createFile(remoteRoot, ".cloudstore.properties"), properties, null); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); // Modify some files and see whether the ignore-rules are respected. try (OutputStream out = castStream(child_1_a.createOutputStream(true))) { out.write(new byte[] { 1, 2, 3 }); } try (OutputStream out = castStream(child_1_b.createOutputStream(true))) { out.write(new byte[] { 4, 5, 6 }); } final File child_1_c = createFileWithRandomContent(child_1, "c"); // new file! final File dest_child_1 = createFile(localRoot, "1"); final File dest_child_1_a = createFile(dest_child_1, "a"); final File dest_child_1_b = createFile(dest_child_1, "b"); final File dest_child_1_c = createFile(dest_child_1, "c"); byte[] src_child_1_a_data = readAll(child_1_a); byte[] dest_child_1_a_data = readAll(dest_child_1_a); assertThat(src_child_1_a_data).isNotEqualTo(dest_child_1_a_data); byte[] src_child_1_b_data = readAll(child_1_b); byte[] dest_child_1_b_data = readAll(dest_child_1_b); assertThat(src_child_1_b_data).isNotEqualTo(dest_child_1_b_data); byte[] src_child_1_c_data = readAll(child_1_c); assertThat(dest_child_1_c.getIoFile()).doesNotExist(); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); // The file "/1/a" should *not* have been synced! It's ignored! byte[] src_child_1_a_data2 = readAll(child_1_a); byte[] dest_child_1_a_data2 = readAll(dest_child_1_a); assertThat(src_child_1_a_data2).isEqualTo(src_child_1_a_data); assertThat(dest_child_1_a_data2).isEqualTo(dest_child_1_a_data); // The file "/1/b" should have been synced, because it's *not* ignored! byte[] src_child_1_b_data2 = readAll(child_1_b); byte[] dest_child_1_b_data2 = readAll(dest_child_1_b); assertThat(src_child_1_b_data2).isEqualTo(src_child_1_b_data); assertThat(dest_child_1_b_data2).isNotEqualTo(dest_child_1_b_data); assertThat(dest_child_1_b_data2).isEqualTo(src_child_1_b_data); // The file "/1/c" should *not* have been synced! It's ignored! byte[] src_child_1_c_data2 = readAll(child_1_c); assertThat(src_child_1_c_data2).isEqualTo(src_child_1_c_data); assertThat(dest_child_1_c.getIoFile()).doesNotExist(); repoToRepoSync.close(); localRepoManagerRemote.close(); } @Test public void ignoreRulesBecomeDisabled() throws Exception { createLocalAndRemoteRepo(); final LocalRepoManager localRepoManagerRemote = localRepoManagerFactory.createLocalRepoManagerForExistingRepository(remoteRoot); final File child_1 = createDirectory(remoteRoot, "1"); final File child_1_a = createFileWithRandomContent(child_1, "a"); final File child_1_b = createFileWithRandomContent(child_1, "b"); localRepoManagerRemote.localSync(new NullProgressMonitor()); assertThatFilesInRepoAreCorrect(remoteRoot); final RepoToRepoSync repoToRepoSync = RepoToRepoSync.create(getLocalRootWithPathPrefix(), remoteRootURLWithPathPrefix); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); assertThatFilesInRepoAreCorrect(remoteRoot); assertDirectoriesAreEqualRecursively(getLocalRootWithPathPrefix(), getRemoteRootWithPathPrefix()); // Create and sync ignore rules. Properties properties = new Properties(); properties.put("ignore[a].namePattern", "a"); // ignore a file that already exists and was already synced properties.put("ignore[c].namePattern", "c"); // ignore a new file properties.put("ignore[dir1].namePattern", "dir1"); // ignore a new directory PropertiesUtil.store(createFile(remoteRoot, ".cloudstore.properties"), properties, null); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); // Modify some files and see whether the ignore-rules are respected. try (OutputStream out = castStream(child_1_a.createOutputStream(true))) { out.write(new byte[] { 1, 2, 3 }); } try (OutputStream out = castStream(child_1_b.createOutputStream(true))) { out.write(new byte[] { 4, 5, 6 }); } final File child_1_c = createFileWithRandomContent(child_1, "c"); // new file! final File src_dir1 = createDirectory(child_1, "dir1"); final File src_dir1_aaa = createFileWithRandomContent(src_dir1, "aaa"); byte[] src_dir1_aaa_data = readAll(src_dir1_aaa); final File dest_child_1 = createFile(localRoot, "1"); final File dest_child_1_a = createFile(dest_child_1, "a"); final File dest_child_1_b = createFile(dest_child_1, "b"); final File dest_child_1_c = createFile(dest_child_1, "c"); final File dest_dir1 = createFile(dest_child_1, "dir1"); final File dest_dir1_aaa = createFile(dest_dir1, "aaa"); byte[] src_child_1_a_data = readAll(child_1_a); byte[] dest_child_1_a_data = readAll(dest_child_1_a); assertThat(src_child_1_a_data).isNotEqualTo(dest_child_1_a_data); byte[] src_child_1_b_data = readAll(child_1_b); byte[] dest_child_1_b_data = readAll(dest_child_1_b); assertThat(src_child_1_b_data).isNotEqualTo(dest_child_1_b_data); byte[] src_child_1_c_data = readAll(child_1_c); assertThat(dest_child_1_c.getIoFile()).doesNotExist(); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); // The file "/1/a" should *not* have been synced! It's ignored! byte[] src_child_1_a_data2 = readAll(child_1_a); byte[] dest_child_1_a_data2 = readAll(dest_child_1_a); assertThat(src_child_1_a_data2).isEqualTo(src_child_1_a_data); assertThat(dest_child_1_a_data2).isEqualTo(dest_child_1_a_data); // The file "/1/b" should have been synced, because it's *not* ignored! byte[] src_child_1_b_data2 = readAll(child_1_b); byte[] dest_child_1_b_data2 = readAll(dest_child_1_b); assertThat(src_child_1_b_data2).isEqualTo(src_child_1_b_data); assertThat(dest_child_1_b_data2).isNotEqualTo(dest_child_1_b_data); assertThat(dest_child_1_b_data2).isEqualTo(src_child_1_b_data); // The file "/1/c" should *not* have been synced! It's ignored! byte[] src_child_1_c_data2 = readAll(child_1_c); assertThat(src_child_1_c_data2).isEqualTo(src_child_1_c_data); assertThat(dest_child_1_c.getIoFile()).doesNotExist(); // The directory dir1 should *not* have been synced! assertThat(src_dir1.getIoFile()).isDirectory(); assertThat(src_dir1_aaa.getIoFile()).isFile(); byte[] src_dir1_aaa_data1 = readAll(src_dir1_aaa); assertThat(src_dir1_aaa_data1).isEqualTo(src_dir1_aaa_data); assertThat(dest_dir1.getIoFile()).doesNotExist(); assertThat(dest_dir1_aaa.getIoFile()).doesNotExist(); // Disable ignore rules. properties = new Properties(); properties.put("ignore[a].enabled", "false"); properties.put("ignore[c].enabled", "false"); properties.put("ignore[dir1].enabled", "false"); PropertiesUtil.store(createFile(child_1, ".cloudstore.properties"), properties, null); repoToRepoSync.sync(new LoggerProgressMonitor(logger)); // Now, the previously ignored file "/1/a" should have been synced! byte[] src_child_1_a_data3 = readAll(child_1_a); byte[] dest_child_1_a_data3 = readAll(dest_child_1_a); assertThat(dest_child_1_a_data3).isEqualTo(src_child_1_a_data3); // And the previously ignoed file "/1/c" should have been synced, too! byte[] src_child_1_c_data3 = readAll(child_1_c); assertThat(src_child_1_c_data3).isEqualTo(src_child_1_c_data); assertThat(dest_child_1_c.getIoFile()).exists(); byte[] dest_child_1_c_data3 = readAll(child_1_c); assertThat(dest_child_1_c_data3).isEqualTo(src_child_1_c_data3); // The previously ignored directory dir1 should have been synced! assertThat(src_dir1.getIoFile()).isDirectory(); assertThat(src_dir1_aaa.getIoFile()).isFile(); byte[] src_dir1_aaa_data2 = readAll(src_dir1_aaa); assertThat(src_dir1_aaa_data2).isEqualTo(src_dir1_aaa_data); assertThat(dest_dir1.getIoFile()).isDirectory(); assertThat(dest_dir1_aaa.getIoFile()).isFile(); byte[] dest_dir1_aaa_data = readAll(dest_dir1_aaa); assertThat(dest_dir1_aaa_data).isEqualTo(src_dir1_aaa_data); repoToRepoSync.close(); localRepoManagerRemote.close(); } private static byte[] readAll(File f) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (InputStream in = castStream(f.createInputStream())) { IOUtil.transferStreamData(in, out); } return out.toByteArray(); } }