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
+
+
+
+
+
+