blob: 577c2bc88de04d85a34256b26ba4c699261bb760 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.updater;
import junit.framework.TestCase;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
public class RunnerAdditionalTest extends TestCase {
private final LinkedList<File> myFiles = new LinkedList<File>();
private final ArrayList<NamePair> myFileNames = new ArrayList<NamePair>();
@Override
public void setUp() throws Exception {
super.setUp();
myFiles.clear();
myFileNames.clear();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
while (!myFiles.isEmpty()) {
remove(myFiles.removeLast());
}
}
public void testUpdater1() throws Exception {
File dir1 = add(createTempDir("old", ".dir"));
File dir2 = add(createTempDir("new", ".dir"));
File f3 = add(createFileContent(dir1, "something.txt", "Content version 1"));
File f4 = add(createFileContent(dir2, "something.txt", "Content version 2"));
File inputJar5 = add(File.createTempFile("input", ".jar"));
File tmpPatch6 = add(File.createTempFile("temp", ".patch"));
final File patch7 = add(File.createTempFile("output", ".jar"));
createEmptyJar(inputJar5);
//noinspection ResultOfMethodCallIgnored
patch7.delete();
assertFalse(patch7.exists());
MockUpdaterUI ui1 = new MockUpdaterUI();
Runner.createImpl("1.2", //oldBuildDesc
"1.3", //newBuildDesc
dir1.getAbsolutePath(), //oldFolder
dir2.getAbsolutePath(), //newFolder
patch7.getAbsolutePath(), //outPatchJar
tmpPatch6, //tempPatchFile
new ArrayList<String>(), //ignoredFiles
new ArrayList<String>(), //criticalFiles
new ArrayList<String>(), //optionalFiles
ui1, //ui
inputJar5); //resolvedJar
assertEquals(
"[Start ] Calculating difference...\n" +
"[Status ] something.txt\n" +
"[Status ] something.txt\n" +
"[Start ] Preparing actions...\n" +
"[Status ] something.txt\n" +
"[Start ] Creating the patch file 'file-6_temp.patch'...\n" +
"[Status ] Packing something.txt\n" +
"[Start ] Packing jar file 'file-7_output.jar'...\n" +
"[Start ] Cleaning up...\n" +
"[Indeterminate Progress]\n",
ui1.toString());
assertTrue(patch7.exists());
File dir8 = add(createTempDir("extracted", ".dir"));
File f9 = add(createFileContent(dir8, "something.txt", "Content version 1"));
assertTrue(f9.exists());
MockUpdaterUI ui2 = new MockUpdaterUI();
Runner.doInstallImpl(ui2,
dir8.getAbsolutePath(),
new Runner.IJarResolver() {
@Override
public File resolveJar() throws IOException {
return patch7;
}
});
assertEquals(
"[Start ] Extracting patch file...\n" +
"[Indeterminate Progress]\n" +
"[Start ] Validating installation...\n" +
"[Status ] something.txt\n" +
"[Progress] 100\n" +
"[Start ] Backing up files...\n" +
"[Status ] something.txt\n" +
"[Progress] 100\n" +
"[Start ] Applying patch...\n" +
"[Status ] something.txt\n" +
"[Progress] 100\n" +
"[Start ] Cleaning up...\n" +
"[Indeterminate Progress]\n",
ui2.toString());
assertEquals("Content version 2", getFileContent(f9));
}
//---- utilities -----
private File createTempDir(String prefix, String suffix) throws IOException {
File d = File.createTempFile(prefix, suffix);
if (!d.delete()) throw new IOException("Failed to delete directory " + d.getAbsolutePath());
if (!d.mkdirs()) throw new IOException("Failed to mkdirs " + d.getAbsolutePath());
return d;
}
private static void createEmptyJar(File jar) throws IOException {
FileOutputStream outStream = new FileOutputStream(jar);
try {
ZipOutputWrapper out = new ZipOutputWrapper(outStream);
// zip file can't be empty, add one dummy entry
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("dummy entry".getBytes("UTF-8"));
out.zipBytes("dummy.txt", baos);
out.finish();
} finally {
outStream.close();
}
}
private File add(File f) {
myFiles.add(f);
String unique = f.getName().replaceAll("[^a-zA-Z.]", "");
NamePair fromTo = new NamePair(f.getAbsolutePath(),
(f.isDirectory() ? "dir-" : "file-") + (myFileNames.size() + 1) + '_' + unique);
myFileNames.add(fromTo);
Collections.sort(myFileNames);
return f;
}
private String getFileContent(File file) throws IOException {
if (!file.exists()) throw new IOException("File not found, expected file: " + replaceFileNames(file.getAbsolutePath()));
BufferedReader br = new BufferedReader(new FileReader(file));
try {
return br.readLine();
} finally {
br.close();
}
}
private static File createFileContent(File parentDir, String fileName, String fileContent) throws IOException {
File f = new File(parentDir, fileName);
OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(f), Charset.forName("UTF-8"));
try {
fw.write(fileContent);
} finally {
fw.close();
}
return f;
}
private static void remove(File... files) {
for (File f : files) {
if (f != null && f.exists()) {
if (!f.delete()) {
f.deleteOnExit();
}
}
}
}
private String replaceFileNames(String str) {
for (NamePair name : myFileNames) {
str = str.replace(name.getFrom(), name.getTo());
}
return str;
}
/**
* A list of from->to name pairs, ordered by descending from
* (to get the longer ones first.)
*/
private static class NamePair implements Comparable<NamePair> {
private final String myFrom;
private final String myTo;
public NamePair(String from, String to) {
myFrom = from;
myTo = to;
}
public String getFrom() {
return myFrom;
}
public String getTo() {
return myTo;
}
@Override
public int compareTo(NamePair n2) {
return -1 * this.getFrom().compareTo(n2.getFrom());
}
}
/**
* Mock UpdaterUI that dumps all the text to a string buffer, which can be
* grabbed using toString(). It also replaces all the filenames using the
* provided name pair list.
*/
private class MockUpdaterUI implements UpdaterUI {
private final StringBuilder myOutput = new StringBuilder();
private MockUpdaterUI() {
}
@Override
public void startProcess(String title) {
title = replaceFileNames(title);
myOutput.append("[Start ] ").append(title).append('\n');
}
@Override
public void setProgress(int percentage) {
myOutput.append("[Progress] ").append(percentage).append('\n');
}
@Override
public void setProgressIndeterminate() {
myOutput.append("[Indeterminate Progress]\n");
}
@Override
public void setStatus(String status) {
status = replaceFileNames(status);
myOutput.append("[Status ] ").append(status).append('\n');
}
@Override
public void showError(Throwable e) {
myOutput.append("[Error ] ").append(e.toString()).append('\n');
}
@Override
public void checkCancelled() throws OperationCancelledException {
// no-op
}
@Override
public Map<String, ValidationResult.Option> askUser(List<ValidationResult> validationResults) throws OperationCancelledException {
return Collections.emptyMap();
}
@Override
public String toString() {
return myOutput.toString();
}
}
}