diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd index c59197f9f..6c80d2e8c 100755 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd @@ -86,9 +86,11 @@ + + - + @@ -135,13 +137,16 @@ - + A collection of architecture-dependent archives. - + diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java index 68b475ad5..fe30239ac 100755 --- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java +++ b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java @@ -16,15 +16,15 @@ package com.android.sdklib.repository; -import com.android.sdklib.repository.SdkRepositoryConstants; - import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import java.io.InputStream; +import java.io.StringReader; import javax.xml.XMLConstants; +import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; @@ -50,34 +50,10 @@ public class TestSdkRepository extends TestCase { super.tearDown(); } - public void testValidateLocalRepositoryFile() throws Exception { - - InputStream xsdStream = SdkRepositoryConstants.getXsdStream(); - InputStream xmlStream = TestSdkRepository.class.getResourceAsStream("repository_sample.xml"); - - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - - Validator validator = schema.newValidator(); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - validator.setErrorHandler(handler); - - validator.validate(new StreamSource(xmlStream)); - - String warnings = handler.getWarnings(); - if (warnings.length() > 0) { - System.err.println(warnings); - } - - String errors = handler.getErrors(); - if (errors.length() > 0) { - System.err.println(errors); - fail(errors); - } - } - + /** + * A SAX error handler that captures the errors and warnings. + * This allows us to capture *all* errors and just not get an exception on the first one. + */ private static class CaptureErrorHandler implements ErrorHandler { private String mWarnings = ""; @@ -91,6 +67,22 @@ public class TestSdkRepository extends TestCase { return mWarnings; } + /** + * Verifies if the handler captures some errors or warnings. + * Prints them on stderr. + * Also fails the unit test if any error was generated. + */ + public void verify() { + if (mWarnings.length() > 0) { + System.err.println(mWarnings); + } + + if (mErrors.length() > 0) { + System.err.println(mErrors); + fail(mErrors); + } + } + /** * @throws SAXException */ @@ -98,9 +90,11 @@ public class TestSdkRepository extends TestCase { mErrors += "Error: " + ex.getMessage() + "\n"; } + /** + * @throws SAXException + */ public void fatalError(SAXParseException ex) throws SAXException { mErrors += "Fatal Error: " + ex.getMessage() + "\n"; - throw ex; } /** @@ -112,4 +106,143 @@ public class TestSdkRepository extends TestCase { } + // --- Helpers ------------ + + /** Helper method that returns a validator for our XSD */ + private Validator getValidator(CaptureErrorHandler handler) throws SAXException { + InputStream xsdStream = SdkRepositoryConstants.getXsdStream(); + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = factory.newSchema(new StreamSource(xsdStream)); + Validator validator = schema.newValidator(); + if (handler != null) { + validator.setErrorHandler(handler); + } + + return validator; + } + + /** Validate a valid sample using an InputStream */ + public void testValidateLocalRepositoryFile() throws Exception { + + InputStream xmlStream = + TestSdkRepository.class.getResourceAsStream("repository_sample.xml"); + Source source = new StreamSource(xmlStream); + + CaptureErrorHandler handler = new CaptureErrorHandler(); + Validator validator = getValidator(handler); + validator.validate(source); + handler.verify(); + } + + /** An helper that validates a string against an expected regexp. */ + private void assertRegex(String expectedRegexp, String actualString) { + assertNotNull(actualString); + assertTrue( + String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n", + expectedRegexp, actualString), + actualString.matches(expectedRegexp)); + } + + // --- Tests ------------ + + /** A document should at least have a root to be valid */ + public void testEmptyXml() throws Exception { + String document = ""; + + Source source = new StreamSource(new StringReader(document)); + + CaptureErrorHandler handler = new CaptureErrorHandler(); + Validator validator = getValidator(handler); + + try { + validator.validate(source); + } catch (SAXParseException e) { + // We expect to get this specific exception message + assertRegex("Premature end of file.*", e.getMessage()); + return; + } + // We shouldn't get here + handler.verify(); + fail(); + } + + /** A document with a root element containing no platform, addon, etc., is valid. */ + public void testEmptyRootXml() throws Exception { + String document = "" + + ""; + + Source source = new StreamSource(new StringReader(document)); + + CaptureErrorHandler handler = new CaptureErrorHandler(); + Validator validator = getValidator(handler); + validator.validate(source); + handler.verify(); + } + + /** A document with an unknown element. */ + public void testUnknownContentXml() throws Exception { + String document = "" + + "" + + "" + + ""; + + Source source = new StreamSource(new StringReader(document)); + + // don't capture the validator errors, we want it to fail and catch the exception + Validator validator = getValidator(null); + try { + validator.validate(source); + } catch (SAXParseException e) { + // We expect a parse expression referring to this grammar rule + assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage()); + return; + } + // If we get here, the validator has not failed as we expected it to. + fail(); + } + + /** A document with an incomplete element. */ + public void testIncompleteContentXml() throws Exception { + String document = "" + + "" + + " 1 " + + ""; + + Source source = new StreamSource(new StringReader(document)); + + // don't capture the validator errors, we want it to fail and catch the exception + Validator validator = getValidator(null); + try { + validator.validate(source); + } catch (SAXParseException e) { + // We expect a parse error referring to this grammar rule + assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage()); + return; + } + // If we get here, the validator has not failed as we expected it to. + fail(); + } + + /** A document with a wrong type element. */ + public void testWrongTypeContentXml() throws Exception { + String document = "" + + "" + + " NotAnInteger " + + ""; + + Source source = new StreamSource(new StringReader(document)); + + // don't capture the validator errors, we want it to fail and catch the exception + Validator validator = getValidator(null); + try { + validator.validate(source); + } catch (SAXParseException e) { + // We expect a parse error referring to this grammar rule + assertRegex("cvc-datatype-valid.1.2.1: 'NotAnInteger' is not a valid value.*", + e.getMessage()); + return; + } + // If we get here, the validator has not failed as we expected it to. + fail(); + } } diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml index 0643185b5..fb6283d9b 100755 --- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml +++ b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml @@ -17,12 +17,17 @@ + + + 1.0 1 3 Some optional description http://www.example.com/platform1.html + 65536 @@ -31,6 +36,48 @@ + + + 1 + 1 + Some optional description + http://www.example.com/docs.html + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + http://www.example.com/docs/docs1.zip + + + + + + My First add-on + 1 + John Doe + 1 + Some optional description + http://www.example.com/myfirstaddon + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + http://www.example.com/add-ons/first.zip + + + + + + android.blah.somelib + The description for this library. + + + + com.android.mymaps + + + + 1.1 2 @@ -65,31 +112,7 @@ - - My First add-on - 1 - John Doe - 1 - Some optional description - http://www.example.com/myfirstaddon - - - 65536 - 2822ae37115ebf13412bbef91339ee0d9454525e - http://www.example.com/add-ons/first.zip - - - - - android.blah.somelib - The description for this library. - - - - com.android.mymaps - - - + My Second add-on 2 @@ -117,19 +140,20 @@ - - 1 + + 1 Some optional description - http://www.example.com/docs.html + http://www.example.com/tools.html 65536 2822ae37115ebf13412bbef91339ee0d9454525e - http://www.example.com/docs/docs1.zip + http://www.example.com/files/tools1.zip - + + 2 42 @@ -151,18 +175,7 @@ - - 1 - Some optional description - http://www.example.com/tools.html - - - 65536 - 2822ae37115ebf13412bbef91339ee0d9454525e - http://www.example.com/files/tools1.zip - - - + 42 @@ -183,4 +196,21 @@ + + + This add-on has no libraries + 4 + Joe Bar + 3 + + + 65536 + 2822ae37115ebf13412bbef91339ee0d9454525e + distrib/imnotanarchiveimadoctorjim.zip + + + + + +