You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/09/20 09:43:37 UTC

[sling-org-apache-sling-feature-analyser] 02/02: SLING-7925 - Donate new AnalyzerTask which is able to validate APIs/Regions

This is an automated email from the ASF dual-hosted git repository.

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-analyser.git

commit 2223816471b7d0ed97f4931d50fea5c5c9c41bbb
Author: Simo Tripodi <st...@adobe.com>
AuthorDate: Wed Sep 19 16:36:50 2018 +0200

    SLING-7925 - Donate new AnalyzerTask which is able to validate
    APIs/Regions
    
     * added unit tests
     * added guard against not valid/expected JSON
---
 pom.xml                                            |   6 +
 .../analyser/task/impl/CheckApiRegions.java        |  12 +-
 .../analyser/task/impl/CheckApiRegionsTest.java    | 182 +++++++++++++++++++++
 3 files changed, 199 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 6511b76..478ea2a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,5 +164,11 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>2.22.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegions.java b/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegions.java
index 6ef2b89..cb0502f 100644
--- a/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegions.java
+++ b/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegions.java
@@ -29,6 +29,7 @@ import java.util.TreeSet;
 import javax.json.Json;
 import javax.json.stream.JsonParser;
 import javax.json.stream.JsonParser.Event;
+import javax.json.stream.JsonParsingException;
 
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.Extensions;
@@ -78,7 +79,16 @@ public class CheckApiRegions implements AnalyserTask {
 
         // read the api-regions and create a Sieve data structure for checks
 
-        ApiRegions apiRegions = fromJson(jsonRepresentation);
+        ApiRegions apiRegions;
+        try {
+            apiRegions = fromJson(jsonRepresentation);
+        } catch (JsonParsingException e) {
+            ctx.reportError("API Regions '"
+                    + jsonRepresentation
+                    + "' does not represent a valid JSON 'api-regions': "
+                    + e.getMessage());
+            return;
+        }
 
         // then, for each bundle, get the Export-Package and process the packages
 
diff --git a/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsTest.java b/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsTest.java
new file mode 100644
index 0000000..bfbf446
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsTest.java
@@ -0,0 +1,182 @@
+/*
+ * 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.sling.feature.analyser.task.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.jar.Manifest;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Extensions;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.analyser.task.AnalyserTask;
+import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
+import org.apache.sling.feature.scanner.BundleDescriptor;
+import org.apache.sling.feature.scanner.FeatureDescriptor;
+import org.apache.sling.feature.scanner.PackageInfo;
+import org.junit.Test;
+
+public class CheckApiRegionsTest {
+
+    private AnalyserTask checkApiRegions = new CheckApiRegions();
+
+    @Test
+    public void testNoApiRegionsExtension() throws Exception {
+        List<String> errors = execute((Extension) null);
+        assertTrue(errors.isEmpty());
+    }
+
+    @Test
+    public void testNullApiRegionsJSON() throws Exception {
+        List<String> errors = execute((String) null);
+        assertTrue(errors.isEmpty());
+    }
+
+    @Test
+    public void testEmptyApiRegionsJSON() throws Exception {
+        List<String> errors = execute("");
+        assertTrue(errors.isEmpty());
+    }
+
+    @Test
+    public void testApiRegionsIsNotJSON() throws Exception {
+        List<String> errors = execute("this is not a JSON string");
+
+        assertFalse(errors.isEmpty());
+        assertTrue(errors.iterator().next().contains("does not represent a valid JSON 'api-regions'"));
+    }
+
+    @Test
+    public void testNotValidApiRegionJson() throws Exception {
+        List<String> errors = execute("[{\"name\": \"global\",\"exports\": [\"org.osgi.util.function.doesnotexist\"]}]");
+
+        assertFalse(errors.isEmpty());
+        assertTrue(errors.iterator()
+                .next()
+                .startsWith("Region 'global' defined in feature 'org.apache.sling.testing:org.apache.sling.testing.apiregions:1.0.0' declares 1 package which is not exported by any bundle"));
+    }
+
+    @Test
+    public void testValidApiRegionJson() throws Exception {
+        List<String> errors = execute("[{\"name\": \"global\",\"exports\": [\"org.osgi.util.function\"]}]");
+        assertTrue(errors.isEmpty());
+    }
+
+    private List<String> execute(String apiRegionJSON) throws Exception {
+        Extension extension = mock(Extension.class);
+        when(extension.getJSON()).thenReturn(apiRegionJSON);
+
+        return execute(extension);
+    }
+
+    private List<String> execute(Extension extension) throws Exception {
+        Extensions extensions = mock(Extensions.class);
+        when(extensions.getByName("api-regions")).thenReturn(extension);
+
+        Feature feature = mock(Feature.class);
+        when(feature.getId()).thenReturn(new ArtifactId("org.apache.sling.testing",
+                                                        "org.apache.sling.testing.apiregions", 
+                                                        "1.0.0",
+                                                        null,
+                                                        null));
+        when(feature.getExtensions()).thenReturn(extensions);
+
+        AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
+        when(ctx.getFeature()).thenReturn(feature);
+
+        PackageInfo packageInfo = new PackageInfo("org.osgi.util.function", "1.0", false);
+
+        BundleDescriptor bundleDescriptor = new TestBundleDescriptor();
+        bundleDescriptor.getExportedPackages().add(packageInfo);
+
+        FeatureDescriptor featureDescriptor = new TestFeatureDescriptor();
+        featureDescriptor.getBundleDescriptors().add(bundleDescriptor);
+
+        when(ctx.getFeatureDescriptor()).thenReturn(featureDescriptor);
+
+        List<String> errors = new LinkedList<>();
+        doAnswer(invocation -> {
+            String error = invocation.getArgument(0);
+            errors.add(error);
+            return null;
+        }).when(ctx).reportError(anyString());
+
+        checkApiRegions.execute(ctx);
+
+        return errors;
+    }
+
+    private static final class TestFeatureDescriptor extends FeatureDescriptor {
+
+        @Override
+        public Feature getFeature() {
+            return null;
+        }
+
+    }
+
+    private static final class TestBundleDescriptor extends BundleDescriptor {
+
+        @Override
+        public File getArtifactFile() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Artifact getArtifact() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Manifest getManifest() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public String getBundleVersion() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public String getBundleSymbolicName() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public int getBundleStartLevel() {
+            // do nothing
+            return 0;
+        }
+
+    }
+
+}