blob: e518782194fb3527e1b3ecc7d61476ee5c89fcb8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.tools.ant.taskdefs;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildFileRule;
import org.apache.tools.ant.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.apache.tools.ant.AntAssert.assertContains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Testcase for the Manifest class used in the jar task.
*
*/
public class ManifestTest {
@Rule
public final BuildFileRule buildRule = new BuildFileRule();
private File expandedManifest;
private File outDir;
public static final String LONG_LINE
= "AReallyLongLineToTestLineBreakingInManifests-ACapabilityWhich" +
"IsSureToLeadToHundredsOfQuestionsAboutWhyAntMungesManifests" +
"OfCourseTheAnswerIsThatIsWhatTheSpecRequiresAndIfAnythingHas" +
"AProblemWithThatItIsNotABugInAnt";
public static final String LONG_70_NAME
= "ThisNameIsJustSeventyCharactersWhichIsAllowedAccordingToTheSpecsFiller";
public static final String LONG_68_NAME
= "ThisNameIsJustSixtyEightCharactersWhichIsAllowedAccordingToTheSpecsX";
public static final String NOT_LONG_NAME
= "NameIsJustUnderSeventyCharactersWhichIsAllowedAccordingTheSpec";
public static final String VALUE = "NOT_LONG";
@Before
public void setUp() {
buildRule.configureProject("src/etc/testcases/taskdefs/manifest.xml");
outDir = new File(buildRule.getProject().getProperty("output"));
expandedManifest = new File(outDir, "manifests/META-INF/MANIFEST.MF");
}
@After
public void tearDown() {
buildRule.executeTarget("tearDown");
}
/**
* Empty manifest - is OK
*/
@Test
public void test1() throws ManifestException, IOException {
buildRule.executeTarget("test1");
Manifest manifest = getManifest(expandedManifest);
String version = manifest.getManifestVersion();
assertEquals("Manifest was not created with correct version - ", "1.0", version);
}
/**
* Simple Manifest with version 2.0
*/
@Test
public void test2() throws ManifestException, IOException {
buildRule.executeTarget("test2");
Manifest manifest = getManifest(expandedManifest);
String version = manifest.getManifestVersion();
assertEquals("Manifest was not created with correct version - ", "2.0", version);
}
/**
* Malformed manifest - no : on the line
*/
@Test
public void test3() {
try {
buildRule.executeTarget("test3");
fail("BuildException expected: Manifest is invalid - no colon on header line");
} catch (BuildException ex) {
assertContains("Invalid Manifest", ex.getMessage());
}
}
/**
* Malformed manifest - starts with continuation line
*/
@Test
public void test4() {
try {
buildRule.executeTarget("test4");
fail("BuildException expected: Manifest is invalid - section starts with continuation line");
} catch (BuildException ex) {
assertContains("Invalid Manifest", ex.getMessage());
}
}
/**
* Malformed manifest - Name attribute in main section
*/
@Test
public void test5() {
buildRule.executeTarget("test5");
assertTrue("Expected warning about Name in main section", buildRule.getLog()
.contains("Manifest warning: \"Name\" attributes should not occur in the main section"));
}
/**
* New Section not starting with Name attribute.
*/
@Test
public void test6() {
try {
buildRule.executeTarget("test6");
fail("BuildException expected: Manifest is invalid - section starts with incorrect attribute");
} catch (BuildException ex) {
assertContains("Invalid Manifest", ex.getMessage());
}
assertTrue("Expected warning about section not starting with Name: attribute", buildRule.getLog()
.contains("Manifest sections should start with a \"Name\" attribute"));
}
/**
* From attribute is illegal
*/
@Test
public void test7() {
buildRule.executeTarget("test7");
assertTrue("Expected warning about From: attribute", buildRule.getLog()
.contains(Manifest.ERROR_FROM_FORBIDDEN));
}
/**
* Inline manifest - OK
*/
@Test
public void test8() throws IOException, ManifestException {
buildRule.executeTarget("test8");
Manifest manifest = getManifest(expandedManifest);
Manifest.Section mainSection = manifest.getMainSection();
String classpath = mainSection.getAttributeValue("class-path");
assertEquals("Class-Path attribute was not set correctly - ", "fubar", classpath);
Manifest.Section testSection = manifest.getSection("Test");
String testAttr = testSection.getAttributeValue("TestAttr");
assertEquals("TestAttr attribute was not set correctly - ", "Test", testAttr);
}
/**
* Inline manifest - Invalid since has a Name attribute in the section element
*/
@Test
public void test9() {
try {
buildRule.executeTarget("test9");
fail("BuildException expected: Construction is invalid - Name attribute should not be used");
} catch (BuildException ex) {
assertContains("Specify the section name using the \"name\" attribute of the <section> element",
ex.getMessage());
}
}
/**
* Inline manifest - Invalid attribute without name
*/
@Test
public void test10() {
try {
buildRule.executeTarget("test10");
fail("BuildException expected: Attribute has no name");
} catch (BuildException ex) {
assertContains("Attributes must have name and value", ex.getMessage());
}
}
/**
* Inline manifest - Invalid attribute without value
*/
@Test
public void test11() {
try {
buildRule.executeTarget("test11");
fail("BuildException expected: Attribute has no value");
} catch (BuildException ex) {
assertContains("Attributes must have name and value", ex.getMessage());
}
}
/**
* Inline manifest - Invalid attribute without value
*/
@Test
public void test12() {
try {
buildRule.executeTarget("test12");
fail("BuildException expected: Section with no name");
} catch (BuildException ex) {
assertContains("Sections must have a name", ex.getMessage());
}
}
/**
* Inline manifest - Duplicate attribute
*/
@Test
public void test13() {
try {
buildRule.executeTarget("test13");
fail("BuildException expected: Duplicate Attribute");
} catch (BuildException ex) {
assertContains("The attribute \"Test\" may not occur more than once in the same section",
ex.getMessage());
}
}
/**
* Inline manifest - OK since classpath entries can be duplicated.
*/
@Test
public void test14() throws IOException, ManifestException {
buildRule.executeTarget("test14");
Manifest manifest = getManifest(expandedManifest);
Manifest.Section mainSection = manifest.getMainSection();
String classpath = mainSection.getAttributeValue("class-path");
assertEquals("Class-Path attribute was not set correctly - ",
"Test1 Test2 Test3 Test4", classpath);
}
/**
* Tets long line wrapping
*/
@Test
public void testLongLine() throws IOException, ManifestException {
Project p = buildRule.getProject();
p.setUserProperty("test.longline", LONG_LINE);
p.setUserProperty("test.long68name", LONG_68_NAME);
p.setUserProperty("test.long70name", LONG_70_NAME);
p.setUserProperty("test.notlongname", NOT_LONG_NAME);
p.setUserProperty("test.value", VALUE);
buildRule.executeTarget("testLongLine");
Manifest manifest = getManifest(expandedManifest);
Manifest.Section mainSection = manifest.getMainSection();
String classpath = mainSection.getAttributeValue("class-path");
assertEquals("Class-Path attribute was not set correctly - ",
LONG_LINE, classpath);
String value = mainSection.getAttributeValue(LONG_68_NAME);
assertEquals("LONG_68_NAME_VALUE_MISMATCH", VALUE, value);
value = mainSection.getAttributeValue(LONG_70_NAME);
assertEquals("LONG_70_NAME_VALUE_MISMATCH", VALUE, value);
value = mainSection.getAttributeValue(NOT_LONG_NAME);
assertEquals("NOT_LONG_NAME_VALUE_MISMATCH", VALUE, value);
Set set = new HashSet();
FileReader fin = new FileReader(expandedManifest);
try {
BufferedReader in = new BufferedReader(fin);
String read = in.readLine();
while (read != null) {
set.add(read);
read = in.readLine();
}
in.close();
} finally {
fin.close();
}
assertTrue("Manifest file should have contained string ",
set.remove(" NOT_LONG"));
assertTrue("Manifest file should have contained string ",
set.remove(" NG"));
assertTrue("Manifest file should have contained string ",
set.remove(LONG_70_NAME + ": "));
assertTrue("Manifest file should have contained string ",
set.remove(NOT_LONG_NAME + ": NOT_LO"));
}
/**
* Tests ordering of sections
*/
@Test
public void testOrder1() throws IOException, ManifestException {
buildRule.executeTarget("testOrder1");
Manifest manifest = getManifest(expandedManifest);
Enumeration e = manifest.getSectionNames();
String section1 = (String) e.nextElement();
String section2 = (String) e.nextElement();
assertEquals("First section name unexpected", "Test1", section1);
assertEquals("Second section name unexpected", "Test2", section2);
Manifest.Section section = manifest.getSection("Test1");
e = section.getAttributeKeys();
String attr1Key = (String) e.nextElement();
String attr2Key = (String) e.nextElement();
String attr1 = section.getAttribute(attr1Key).getName();
String attr2 = section.getAttribute(attr2Key).getName();
assertEquals("First attribute name unexpected", "TestAttr1", attr1);
assertEquals("Second attribute name unexpected", "TestAttr2", attr2);
}
/**
* Tests ordering of sections
*/
@Test
public void testOrder2() throws IOException, ManifestException {
buildRule.executeTarget("testOrder2");
Manifest manifest = getManifest(expandedManifest);
Enumeration e = manifest.getSectionNames();
String section1 = (String) e.nextElement();
String section2 = (String) e.nextElement();
assertEquals("First section name unexpected", "Test2", section1);
assertEquals("Second section name unexpected", "Test1", section2);
Manifest.Section section = manifest.getSection("Test1");
e = section.getAttributeKeys();
String attr1Key = (String) e.nextElement();
String attr2Key = (String) e.nextElement();
String attr1 = section.getAttribute(attr1Key).getName();
String attr2 = section.getAttribute(attr2Key).getName();
assertEquals("First attribute name unexpected", "TestAttr2", attr1);
assertEquals("Second attribute name unexpected", "TestAttr1", attr2);
}
/**
* file attribute for manifest task is required.
*/
@Test
public void testNoFile() {
try {
buildRule.executeTarget("testNoFile");
fail("BuildException expected: file is required");
} catch (BuildException ex) {
//TODO assert value
}
}
/**
* replace changes Manifest-Version from 2.0 to 1.0
*/
@Test
public void testReplace() throws IOException, ManifestException {
buildRule.executeTarget("testReplace");
Manifest mf = getManifest(new File(outDir, "mftest.mf"));
assertNotNull(mf);
assertEquals(Manifest.getDefaultManifest(), mf);
}
/**
* update keeps the Manifest-Version and adds a new attribute Foo
*/
@Test
public void testUpdate() throws IOException, ManifestException {
buildRule.executeTarget("testUpdate");
Manifest mf = getManifest(new File(outDir, "mftest.mf"));
assertNotNull(mf);
assertTrue(!Manifest.getDefaultManifest().equals(mf));
String mfAsString = mf.toString();
assertNotNull(mfAsString);
assertTrue(mfAsString.startsWith("Manifest-Version: 2.0"));
assertTrue(mfAsString.contains("Foo: Bar"));
mf = getManifest(new File(outDir, "mftest2.mf"));
assertNotNull(mf);
mfAsString = mf.toString();
assertNotNull(mfAsString);
assertEquals(-1, mfAsString.indexOf("Foo: Bar"));
assertTrue(mfAsString.contains("Foo: Baz"));
}
@Test
public void testFrom() {
buildRule.executeTarget("testFrom");
assertContains(Manifest.ERROR_FROM_FORBIDDEN, buildRule.getLog());
}
@Test
public void testIllegalName() {
try {
buildRule.executeTarget("testIllegalName");
fail("BuildException expected: Manifest attribute names must not contain ' '");
} catch (BuildException ex) {
//TODO assert value
}
}
@Test
public void testIllegalNameInSection() {
try {
buildRule.executeTarget("testIllegalNameInSection");
fail("BuildException expected: Manifest attribute names must not contain ' '");
} catch (BuildException ex) {
//TODO assert value
}
}
@Test
public void testIllegalNameBegin() {
try {
buildRule.executeTarget("testIllegalNameInSection");
fail("BuildException expected: Manifest attribute names must not start with '-' at the begin.");
} catch (BuildException ex) {
//TODO assert value
}
}
@Test
public void testIllegalName2() {
try {
buildRule.executeTarget("testIllegalName");
fail("BuildException expected: Manifest attribute names must not contain '.'");
} catch (BuildException ex) {
//TODO assert value
}
}
@Test
public void testIllegalName3() {
try {
buildRule.executeTarget("testIllegalName");
fail("BuildException expected: Manifest attribute names must not contain '*'");
} catch (BuildException ex) {
//TODO assert value
}
}
/**
* Reads mftest.mf.
*/
private Manifest getManifest(File file) throws IOException, ManifestException {
FileReader r = new FileReader(file);
try {
return new Manifest(r);
} finally {
r.close();
}
}
}