com.facebook.buck.zip.UnzipTest.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.zip.UnzipTest.java

Source

/*
 * Copyright 2013-present Facebook, Inc.
 *
 * 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.facebook.buck.zip;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeThat;

import com.facebook.buck.io.MoreFiles;
import com.facebook.buck.io.MorePosixFilePermissions;
import com.facebook.buck.testutil.Zip;
import com.facebook.buck.testutil.integration.TemporaryPaths;
import com.facebook.buck.util.environment.Platform;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.zip.ZipEntry;

public class UnzipTest {
    private static final byte[] DUMMY_FILE_CONTENTS = "BUCK Unzip Test String!\nNihao\n".getBytes();

    @Rule
    public TemporaryPaths tmpFolder = new TemporaryPaths();

    private Path zipFile;

    @Before
    public void setUp() {
        zipFile = tmpFolder.getRoot().resolve("tmp.zip");
    }

    @Test
    public void testExtractZipFile() throws IOException {

        try (Zip zip = new Zip(zipFile, true)) {
            zip.add("1.bin", DUMMY_FILE_CONTENTS);
            zip.add("subdir/2.bin", DUMMY_FILE_CONTENTS);
            zip.addDir("emptydir");
        }

        Path extractFolder = tmpFolder.newFolder();
        ImmutableList<Path> result = Unzip.extractZipFile(zipFile.toAbsolutePath(), extractFolder.toAbsolutePath(),
                Unzip.ExistingFileMode.OVERWRITE);
        assertTrue(Files.exists(extractFolder.toAbsolutePath().resolve("1.bin")));
        Path bin2 = extractFolder.toAbsolutePath().resolve("subdir/2.bin");
        assertTrue(Files.exists(bin2));
        assertTrue(Files.isDirectory(extractFolder.toAbsolutePath().resolve("emptydir")));
        try (InputStream input = Files.newInputStream(bin2)) {
            byte[] buffer = new byte[DUMMY_FILE_CONTENTS.length];
            int bytesRead = input.read(buffer, 0, DUMMY_FILE_CONTENTS.length);
            assertEquals(DUMMY_FILE_CONTENTS.length, bytesRead);
            for (int i = 0; i < DUMMY_FILE_CONTENTS.length; i++) {
                assertEquals(DUMMY_FILE_CONTENTS[i], buffer[i]);
            }
        }
        assertEquals(ImmutableList.of(extractFolder.resolve("1.bin"), extractFolder.resolve("subdir/2.bin")),
                result);
    }

    @Test
    public void testExtractZipFilePreservesExecutePermissionsAndModificationTime() throws IOException {

        // getFakeTime returs time with some non-zero millis. By doing division and multiplication by
        // 1000 we get rid of that.
        final long time = ZipConstants.getFakeTime() / 1000 * 1000;

        // Create a simple zip archive using apache's commons-compress to store executable info.
        try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(zipFile.toFile())) {
            ZipArchiveEntry entry = new ZipArchiveEntry("test.exe");
            entry.setUnixMode((int) MorePosixFilePermissions.toMode(PosixFilePermissions.fromString("r-x------")));
            entry.setSize(DUMMY_FILE_CONTENTS.length);
            entry.setMethod(ZipEntry.STORED);
            entry.setTime(time);
            zip.putArchiveEntry(entry);
            zip.write(DUMMY_FILE_CONTENTS);
            zip.closeArchiveEntry();
        }

        // Now run `Unzip.extractZipFile` on our test zip and verify that the file is executable.
        Path extractFolder = tmpFolder.newFolder();
        ImmutableList<Path> result = Unzip.extractZipFile(zipFile.toAbsolutePath(), extractFolder.toAbsolutePath(),
                Unzip.ExistingFileMode.OVERWRITE);
        Path exe = extractFolder.toAbsolutePath().resolve("test.exe");
        assertTrue(Files.exists(exe));
        assertThat(Files.getLastModifiedTime(exe).toMillis(), Matchers.equalTo(time));
        assertTrue(Files.isExecutable(exe));
        assertEquals(ImmutableList.of(extractFolder.resolve("test.exe")), result);
    }

    @Test
    public void testExtractSymlink() throws IOException {
        assumeThat(Platform.detect(), Matchers.is(Matchers.not(Platform.WINDOWS)));

        // Create a simple zip archive using apache's commons-compress to store executable info.
        try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(zipFile.toFile())) {
            ZipArchiveEntry entry = new ZipArchiveEntry("link.txt");
            entry.setUnixMode((int) MoreFiles.S_IFLNK);
            String target = "target.txt";
            entry.setSize(target.getBytes(Charsets.UTF_8).length);
            entry.setMethod(ZipEntry.STORED);
            zip.putArchiveEntry(entry);
            zip.write(target.getBytes(Charsets.UTF_8));
            zip.closeArchiveEntry();
        }

        // Now run `Unzip.extractZipFile` on our test zip and verify that the file is executable.
        Path extractFolder = tmpFolder.newFolder();
        Unzip.extractZipFile(zipFile.toAbsolutePath(), extractFolder.toAbsolutePath(),
                Unzip.ExistingFileMode.OVERWRITE);
        Path link = extractFolder.toAbsolutePath().resolve("link.txt");
        assertTrue(Files.isSymbolicLink(link));
        assertThat(Files.readSymbolicLink(link).toString(), Matchers.equalTo("target.txt"));
    }

}