/*
* Copyright 2016-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.assertArrayEquals;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.junit.Before;
import org.junit.Test;
public class DeterministicManifestTest {
private DeterministicManifest manifestWriter;
private ByteArrayOutputStream outputStream;
@Before
public void setUp() {
outputStream = new ByteArrayOutputStream();
manifestWriter = new DeterministicManifest();
}
@Test
public void testManifestAttributesSeparatedFromEntries() throws IOException {
manifestWriter.setManifestAttribute(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
manifestWriter.setEntryAttribute("Z", "Foo", "Bar");
manifestWriter.setEntryAttribute("A", "Foo", "Bar");
manifestWriter.write(outputStream);
assertManifestContents(
"Manifest-Version: 1.0\r\n"
+ "\r\n"
+ "Name: A\r\n"
+ "Foo: Bar\r\n"
+ "\r\n"
+ "Name: Z\r\n"
+ "Foo: Bar\r\n"
+ "\r\n");
}
@Test
public void testEntriesWrittenInSortedOrder() throws IOException {
manifestWriter.setEntryAttribute("Z", "Foo", "Bar");
manifestWriter.setEntryAttribute("A", "Foo", "Bar");
manifestWriter.write(outputStream);
assertManifestContents(
"\r\n" + "Name: A\r\n" + "Foo: Bar\r\n" + "\r\n" + "Name: Z\r\n" + "Foo: Bar\r\n" + "\r\n");
}
@Test
public void testAttributesWrittenInSortedOrder() throws IOException {
manifestWriter.setEntryAttribute("A", "Foo", "Bar");
manifestWriter.setEntryAttribute("A", "Baz", "Bar");
manifestWriter.write(outputStream);
assertManifestContents("\r\n" + "Name: A\r\n" + "Baz: Bar\r\n" + "Foo: Bar\r\n" + "\r\n");
}
@Test
public void testShortLinesWrittenOnOneLine() throws IOException {
assertEntryWrittenAs("\r\n" + "Name: Entry\r\n" + "Key: value\r\n" + "\r\n", "Key", "value");
}
@Test
public void testLongLineSplit() throws IOException {
assertEntryWrittenAs(
"\r\n"
+ "Name: Entry\r\n"
+ "12345678: 69-char value + 8 char key + 2 char padding = 79 chars. |\r\n"
+ " next line\r\n"
+ "\r\n",
"12345678",
"69-char value + 8 char key + 2 char padding = 79 chars. |" + "next line");
}
@Test
public void testReallyLongLineSplit() throws IOException {
assertEntryWrittenAs(
"\r\n"
+ "Name: Entry\r\n"
+ "12345678: 138-char value + 8 char key + 2 char padding = 148 chars. |\r\n"
+ " 69-character second line |\r\n"
+ " last line\r\n"
+ "\r\n",
"12345678",
"138-char value + 8 char key + 2 char padding = 148 chars. |"
+ "69-character second line |"
+ "last line");
}
@Test
public void testReallyLongLineSplitExact() throws IOException {
assertEntryWrittenAs(
"\r\n"
+ "Name: Entry\r\n"
+ "12345678: 138-char value + 8 char key + 2 char padding = 148 chars. |\r\n"
+ " 69-character second line |\r\n"
+ "\r\n",
"12345678",
"138-char value + 8 char key + 2 char padding = 148 chars. |"
+ "69-character second line |");
}
@Test
public void testReallyLongLineSplitOneExtra() throws IOException {
assertEntryWrittenAs(
"\r\n"
+ "Name: Entry\r\n"
+ "12345678: 138-char value + 8 char key + 2 char padding = 148 chars. |\r\n"
+ " 69-character second line |\r\n"
+ " X\r\n"
+ "\r\n",
"12345678",
"138-char value + 8 char key + 2 char padding = 148 chars. |"
+ "69-character second line |"
+ "X");
}
@Test
public void testLinesSplitLikeJavaImpl() throws IOException {
final String entryName = "test";
final String key = "12345678";
final String value =
"138-char value + 8 char key + 2 char padding = 148 chars. |"
+ "69-character second line |"
+ "last line";
manifestWriter.setEntryAttribute(entryName, key, value);
manifestWriter.write(outputStream);
Manifest jdkManifest = new Manifest();
Attributes attrs = new Attributes();
attrs.putValue(key, value);
jdkManifest.getEntries().put(entryName, attrs);
ByteArrayOutputStream expected = new ByteArrayOutputStream();
jdkManifest.write(expected);
assertArrayEquals(expected.toByteArray(), outputStream.toByteArray());
}
private void assertEntryWrittenAs(String expected, String key, String value) throws IOException {
manifestWriter.setEntryAttribute("Entry", key, value);
manifestWriter.write(outputStream);
assertManifestContents(expected);
}
private void assertManifestContents(String expected) {
assertArrayEquals(expected.getBytes(StandardCharsets.UTF_8), outputStream.toByteArray());
}
}