blob: 57696c7fd53af3cedb70cabc912e6932eb7de3d7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.tests.datatransfer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.tests.harness.FileSystemHelper;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileExportOperation;
import org.eclipse.ui.internal.wizards.datatransfer.TarEntry;
import org.eclipse.ui.internal.wizards.datatransfer.TarException;
import org.eclipse.ui.internal.wizards.datatransfer.TarFile;
import org.eclipse.ui.tests.harness.util.FileUtil;
import org.eclipse.ui.tests.harness.util.UITestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ExportArchiveFileOperationTest extends UITestCase implements
IOverwriteQuery {
private static final String FILE_NAME = "test";
private static final String ZIP_FILE_EXT = "zip";
private static final String TAR_FILE_EXT = "tar";
private static final String[] directoryNames = { "dir1", "dir2" };
private static final String[] emptyDirectoryNames = { "dir3" };
private static final String[] fileNames = { "file1.txt", "file2.txt" };
private String localDirectory;
private String filePath;
private IProject project;
private boolean flattenPaths = false;
private boolean excludeProjectPath = false;
public ExportArchiveFileOperationTest() {
super(ExportArchiveFileOperationTest.class.getSimpleName());
}
@Override
public String queryOverwrite(String pathString) {
return "";
}
@Test
public void testExportStatus(){
List<IProject> resources = new ArrayList<>();
resources.add(project);
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, localDirectory);
assertTrue(operation.getStatus().getCode() == IStatus.OK);
}
@Test
public void testExportZip() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT;
List<IProject> resources = new ArrayList<>();
resources.add(project);
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setUseCompression(false);
operation.setUseTarFormat(false);
operation.run(new NullProgressMonitor());
// +1 for .settings
verifyFolders(directoryNames.length + emptyDirectoryNames.length + 1, ZIP_FILE_EXT);
}
@Test
public void testExportZipCompressed() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT;
List<IProject> resources = new ArrayList<>();
resources.add(project);
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setUseCompression(true);
operation.setUseTarFormat(false);
operation.run(new NullProgressMonitor());
verifyCompressed(ZIP_FILE_EXT);
}
@Test
public void testExportZipCreateSelectedDirectories() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT;
List<IResource> resources = new ArrayList<>();
IResource[] members = project.members();
for (IResource member : members) {
if (isDirectory(member)){
IResource[] folderMembers = ((IFolder)member).members();
for (IResource folderMember : folderMembers) {
if (isFile(folderMember)){
resources.add(folderMember);
}
}
}
}
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(false);
operation.setUseTarFormat(false);
operation.run(new NullProgressMonitor());
flattenPaths = true;
verifyFolders(directoryNames.length + emptyDirectoryNames.length, ZIP_FILE_EXT);
}
@Test
public void testExportZipCreateSelectedDirectoriesProject() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT;
ArchiveFileExportOperation operation = new ArchiveFileExportOperation(project, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(false);
operation.setUseTarFormat(false);
operation.run(new NullProgressMonitor());
// +1 for .settings
verifyFolders(directoryNames.length + emptyDirectoryNames.length + 1, ZIP_FILE_EXT);
try (ZipFile zipFile = new ZipFile(filePath)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String name = entry.getName();
assertTrue(name, name.startsWith(project.getName() + "/"));
}
}
}
@Test
public void testExportZipCreateSelectedDirectoriesWithFolders() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT;
List<IResource> resources = new ArrayList<>();
IResource[] members = project.members();
for (IResource member : members) {
if (isDirectory(member)) {
resources.add(member);
}
}
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(false);
operation.setUseTarFormat(false);
operation.run(new NullProgressMonitor());
excludeProjectPath = true;
verifyFolders(directoryNames.length + emptyDirectoryNames.length, ZIP_FILE_EXT);
}
@Test
public void testExportZipCreateSelectedDirectoriesCompressed() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT;
List<IResource> resources = new ArrayList<>();
IResource[] members = project.members();
for (IResource member : members) {
if (isDirectory(member)){
IResource[] folderMembers = ((IFolder)member).members();
for (IResource folderMember : folderMembers) {
if (isFile(folderMember)){
resources.add(folderMember);
}
}
}
}
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(true);
operation.setUseTarFormat(false);
operation.run(new NullProgressMonitor());
flattenPaths = true;
verifyCompressed(ZIP_FILE_EXT);
verifyFolders(directoryNames.length + emptyDirectoryNames.length, ZIP_FILE_EXT);
}
@Test
public void testExportTar() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT;
List<IResource> resources = new ArrayList<>();
resources.add(project);
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setUseTarFormat(true);
operation.setUseCompression(false);
operation.run(new NullProgressMonitor());
// +1 for .settings
verifyFolders(directoryNames.length + emptyDirectoryNames.length + 1, TAR_FILE_EXT);
}
@Test
public void testExportTarCompressed() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT;
List<IResource> resources = new ArrayList<>();
resources.add(project);
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setUseTarFormat(true);
operation.setUseCompression(true);
operation.run(new NullProgressMonitor());
verifyCompressed(TAR_FILE_EXT);
}
@Test
public void testExportTarCreateSelectedDirectories() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT;
List<IResource> resources = new ArrayList<>();
IResource[] members = project.members();
for (IResource member : members) {
if (isDirectory(member)){
IResource[] folderMembers = ((IFolder)member).members();
for (IResource folderMember : folderMembers) {
if (isFile(folderMember)){
resources.add(folderMember);
}
}
}
}
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(false);
operation.setUseTarFormat(true);
operation.run(new NullProgressMonitor());
flattenPaths = true;
verifyFolders(directoryNames.length + emptyDirectoryNames.length, TAR_FILE_EXT);
}
@Test
public void testExportTarCreateSelectedDirectoriesWithFolders() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT;
List<IResource> resources = new ArrayList<>();
IResource[] members = project.members();
for (IResource member : members) {
if (isDirectory(member)) {
resources.add(member);
}
}
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(false);
operation.setUseTarFormat(true);
operation.run(new NullProgressMonitor());
excludeProjectPath = true;
verifyFolders(directoryNames.length + emptyDirectoryNames.length, TAR_FILE_EXT);
}
@Test
public void testExportTarCreateSelectedDirectoriesCompressed() throws Exception {
filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT;
List<IResource> resources = new ArrayList<>();
IResource[] members = project.members();
for (IResource member : members) {
if (isDirectory(member)){
IResource[] folderMembers = ((IFolder)member).members();
for (IResource folderMember : folderMembers) {
if (isFile(folderMember)){
resources.add(folderMember);
}
}
}
}
ArchiveFileExportOperation operation =
new ArchiveFileExportOperation(resources, filePath);
operation.setCreateLeadupStructure(false);
operation.setUseCompression(true);
operation.setUseTarFormat(true);
operation.run(new NullProgressMonitor());
flattenPaths = true;
verifyCompressed(TAR_FILE_EXT);
verifyFolders(directoryNames.length + emptyDirectoryNames.length, TAR_FILE_EXT);
}
@Override
protected void doSetUp() throws Exception {
super.doSetUp();
project = FileUtil.createProject("Export" + getName());
File destination =
new File(FileSystemHelper.getRandomLocation(FileSystemHelper.getTempDir())
.toOSString());
localDirectory = destination.getAbsolutePath();
if (!destination.mkdirs()) {
fail("Could not set up destination directory for " + getName());
}
setUpData();
flattenPaths = false;
excludeProjectPath = false;
}
@Override
protected void doTearDown() throws Exception {
super.doTearDown();
// delete exported data
File root = new File(localDirectory);
if (root.exists()){
File[] files = root.listFiles();
if (files != null){
for (File file : files) {
if (!file.delete()) {
fail("Could not delete " + file.getAbsolutePath());
}
}
}
root.delete();
}
try {
project.delete(true, true, null);
} catch (CoreException e) {
fail(e.toString());
}
finally{
project = null;
localDirectory = null;
filePath = null;
}
}
private void setUpData(){
try{
for (String directoryName : directoryNames) {
IFolder folder = project.getFolder(directoryName);
folder.create(false, true, new NullProgressMonitor());
for (String fileName : fileNames) {
IFile file = folder.getFile(fileName);
String contents =
directoryName + ", " + fileName;
file.create(new ByteArrayInputStream(contents.getBytes()),
true, new NullProgressMonitor());
}
}
// create empty folders to test bug 278402
for (String emptyDirectoryName : emptyDirectoryNames) {
IFolder folder = project.getFolder(emptyDirectoryName);
folder.create(false, true, new NullProgressMonitor());
}
}
catch(Exception e){
fail(e.toString());
}
}
private void verifyCompressed(String type){
String fileName = "";
boolean compressed = false;
try {
if (ZIP_FILE_EXT.equals(type)) {
try (ZipFile zipFile = new ZipFile(filePath)) {
fileName = zipFile.getName();
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
compressed = entry.getMethod() == ZipEntry.DEFLATED;
}
}
} else {
File file = new File(filePath);
try (InputStream fin = new FileInputStream(file)) {
// Check if it's a GZIPInputStream.
try (InputStream in = new GZIPInputStream(fin)) {
compressed = true;
} catch (IOException e) {
compressed = false;
}
fileName = file.getName();
}
}
} catch (IOException e) {
fail(e.getMessage());
}
assertTrue(fileName + " does not appear to be compressed.", compressed);
}
private void verifyFolders(int folderCount, String type){
try{
List<String> allEntries = new ArrayList<>();
if (ZIP_FILE_EXT.equals(type)){
try (ZipFile zipFile = new ZipFile(filePath)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
allEntries.add(entry.getName());
}
}
}
else{
TarFile tarFile = new TarFile(filePath);
Enumeration<?> entries = tarFile.entries();
while (entries.hasMoreElements()){
TarEntry entry = (TarEntry)entries.nextElement();
allEntries.add(entry.getName());
}
tarFile.close();
}
if (flattenPaths) {
verifyFiles(allEntries);
} else {
verifyArchive(folderCount, allEntries);
}
}
catch (IOException | TarException e){
fail(e.getMessage());
}
}
private void verifyArchive(int folderCount, List<String> entries) {
int count = 0;
Set<String> folderNames = new HashSet<>();
List<String> files = new ArrayList<>();
Iterator<String> archiveEntries = entries.iterator();
while (archiveEntries.hasNext()){
String entryName = archiveEntries.next();
int idx = entryName.lastIndexOf('/');
String folderPath = entryName.substring(0, idx);
String fileName = entryName.substring(idx+1, entryName.length());
// we get empty strings for folder entries, don't add them as a file name
if (!fileName.isEmpty()) {
files.add(fileName);
}
int idx2 = folderPath.lastIndexOf('/');
if (idx2 != -1){
String folderName = folderPath.substring(idx2 + 1, folderPath.length());
folderNames.add(folderName);
} else {
folderNames.add(folderPath);
}
}
verifyFolders(folderNames);
verifyFiles(files);
count += folderNames.size();
if (!flattenPaths && !excludeProjectPath) {
folderCount++;
}
assertTrue(
"Number of folders expected and found not equal: expected=" + folderCount + ", actual=" + count,
folderCount == count);
}
private void verifyFiles(List<String> files) {
Iterator<String> iter = files.iterator();
while (iter.hasNext()){
String file = iter.next();
verifyFile(file);
}
}
private void verifyFile(String entryName){
for (String fileName : fileNames) {
boolean dotProjectFileShouldBePresent = ".project".equals(entryName) && !flattenPaths && !excludeProjectPath;
if (fileName.equals(entryName) || dotProjectFileShouldBePresent) {
return;
}
}
if (entryName.equals("org.eclipse.core.resources.prefs")) {
return;
}
fail("Could not find file named: " + entryName);
}
private void verifyFolders(Set<String> folderNames) {
Iterator<String> folders = folderNames.iterator();
while (folders.hasNext()){
String folderName = folders.next();
if (".settings".equals(folderName)) {
continue;
}
if (!isDirectory(folderName)){
if (flattenPaths) {
fail(folderName + " is not an expected folder");
} else if (!project.getName().equals(folderName)) {
fail(folderName + " is not an expected folder");
}
}
}
}
private boolean isDirectory(String name){
for (String directoryName : directoryNames) {
if (directoryName.equals(name)) {
return true;
}
}
for (String emptyDirectoryName : emptyDirectoryNames) {
if (emptyDirectoryName.equals(name)) {
return true;
}
}
return false;
}
private boolean isDirectory(IResource resource){
return isDirectory(resource.getName());
}
private boolean isFile(IResource resource){
for (String fileName : fileNames) {
if (fileName.equals(resource.getName())) {
return true;
}
}
return false;
}
}