You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by si...@apache.org on 2018/11/06 15:26:18 UTC
[sling-org-apache-sling-feature-analyser] 01/01: SLING-8078 - New
Analyser task which is able to detect Export-Package dependencies between
regions
This is an automated email from the ASF dual-hosted git repository.
simonetripodi pushed a commit to branch SLING-8078
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-analyser.git
commit a26609ddd4e6d5104b89399fad439d4559707384
Author: Simo Tripodi <st...@adobe.com>
AuthorDate: Tue Nov 6 16:25:53 2018 +0100
SLING-8078 - New Analyser task which is able to detect Export-Package
dependencies between regions
---
.../task/impl/AbstractApiRegionsAnalyserTask.java | 68 +++++++++
.../feature/analyser/task/impl/ApiRegions.java | 133 +++++++++++++++++
.../analyser/task/impl/CheckApiRegions.java | 158 +--------------------
.../task/impl/CheckApiRegionsDependencies.java | 71 +++++++++
.../apache/sling/feature/scanner/PackageInfo.java | 13 ++
.../feature/scanner/impl/BundleDescriptorImpl.java | 17 ++-
...ava => AbstractApiRegionsAnalyserTaskTest.java} | 46 +++---
.../task/impl/CheckApiRegionsDependenciesTest.java | 49 +++++++
.../analyser/task/impl/CheckApiRegionsTest.java | 141 +-----------------
9 files changed, 380 insertions(+), 316 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/analyser/task/impl/AbstractApiRegionsAnalyserTask.java b/src/main/java/org/apache/sling/feature/analyser/task/impl/AbstractApiRegionsAnalyserTask.java
new file mode 100644
index 0000000..d6b1d80
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/analyser/task/impl/AbstractApiRegionsAnalyserTask.java
@@ -0,0 +1,68 @@
+/*
+ * 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 javax.json.stream.JsonParsingException;
+
+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;
+
+public abstract class AbstractApiRegionsAnalyserTask implements AnalyserTask {
+
+ protected static final String API_REGIONS_KEY = "api-regions";
+
+ @Override
+ public final void execute(AnalyserTaskContext ctx) throws Exception {
+ Feature feature = ctx.getFeature();
+
+ // extract and check the api-regions
+
+ Extensions extensions = feature.getExtensions();
+ Extension apiRegionsExtension = extensions.getByName(API_REGIONS_KEY);
+ if (apiRegionsExtension == null) {
+ // no need to be analyzed
+ return;
+ }
+
+ String jsonRepresentation = apiRegionsExtension.getJSON();
+ if (jsonRepresentation == null || jsonRepresentation.isEmpty()) {
+ // no need to be analyzed
+ return;
+ }
+
+ // read the api-regions and create a Sieve data structure for checks
+
+ ApiRegions apiRegions;
+ try {
+ apiRegions = ApiRegions.fromJson(jsonRepresentation);
+ } catch (JsonParsingException e) {
+ ctx.reportError("API Regions '"
+ + jsonRepresentation
+ + "' does not represent a valid JSON 'api-regions': "
+ + e.getMessage());
+ return;
+ }
+
+ execute(apiRegions, ctx);
+ }
+
+ protected abstract void execute(ApiRegions apiRegions, AnalyserTaskContext ctx) throws Exception;
+
+}
diff --git a/src/main/java/org/apache/sling/feature/analyser/task/impl/ApiRegions.java b/src/main/java/org/apache/sling/feature/analyser/task/impl/ApiRegions.java
new file mode 100644
index 0000000..68f2570
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/analyser/task/impl/ApiRegions.java
@@ -0,0 +1,133 @@
+/*
+ * 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 java.io.StringReader;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.json.Json;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParser.Event;
+
+/**
+ * A "Sieve" data structure to check exported packages
+ */
+final class ApiRegions {
+
+ private static final String NAME_KEY = "name";
+
+ private static final String EXPORTS_KEY = "exports";
+
+ public static ApiRegions fromJson(String jsonRepresentation) {
+ ApiRegions apiRegions = new ApiRegions();
+
+ // pointers
+ Event event;
+ String region = null;
+ Collection<String> apis = null;
+
+ JsonParser parser = Json.createParser(new StringReader(jsonRepresentation));
+ while (parser.hasNext()) {
+ event = parser.next();
+ if (Event.KEY_NAME == event) {
+ switch (parser.getString()) {
+ case NAME_KEY:
+ parser.next();
+ region = parser.getString();
+ break;
+
+ case EXPORTS_KEY:
+ apis = new LinkedList<>();
+
+ // start array
+ parser.next();
+
+ while (parser.hasNext() && Event.VALUE_STRING == parser.next()) {
+ String api = parser.getString();
+ // skip comments
+ if ('#' != api.charAt(0)) {
+ apis.add(api);
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ } else if (Event.END_OBJECT == event) {
+ if (region != null && apis != null) {
+ apiRegions.add(region, apis);
+ }
+
+ region = null;
+ apis = null;
+ }
+ }
+
+ return apiRegions;
+ }
+
+ // class members
+
+ private final Map<String, Set<String>> apis = new TreeMap<>();
+
+ // ctor
+
+ protected ApiRegions() {
+ // it should not be directly instantiated outside this package
+ }
+
+ // methods
+
+ public void add(String region, Collection<String> exportedApis) {
+ apis.computeIfAbsent(region, k -> new TreeSet<>()).addAll(exportedApis);
+ }
+
+ public Iterable<String> getRegions() {
+ return apis.keySet();
+ }
+
+ public Set<String> getApis(String region) {
+ return apis.computeIfAbsent(region, k -> Collections.emptySet());
+ }
+
+ public void remove(String packageName) {
+ apis.values().forEach(apis -> apis.remove(packageName));
+ }
+
+ public boolean isEmpty() {
+ for (Set<String> packages : apis.values()) {
+ if (!packages.isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return apis.toString().replace(',', '\n');
+ }
+
+}
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 cb0502f..6ea7f82 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
@@ -16,37 +16,16 @@
*/
package org.apache.sling.feature.analyser.task.impl;
-import java.io.StringReader;
import java.util.Collection;
-import java.util.Collections;
import java.util.Formatter;
-import java.util.LinkedList;
-import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
-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;
-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;
-public class CheckApiRegions implements AnalyserTask {
-
- private static final String API_REGIONS_KEY = "api-regions";
-
- private static final String NAME_KEY = "name";
-
- private static final String EXPORTS_KEY = "exports";
+public class CheckApiRegions extends AbstractApiRegionsAnalyserTask {
@Override
public String getId() {
@@ -59,38 +38,8 @@ public class CheckApiRegions implements AnalyserTask {
}
@Override
- public void execute(AnalyserTaskContext ctx) throws Exception {
- Feature feature = ctx.getFeature();
-
- // extract and check the api-regions
-
- Extensions extensions = feature.getExtensions();
- Extension apiRegionsExtension = extensions.getByName(API_REGIONS_KEY);
- if (apiRegionsExtension == null) {
- // no need to be analyzed
- return;
- }
-
- String jsonRepresentation = apiRegionsExtension.getJSON();
- if (jsonRepresentation == null || jsonRepresentation.isEmpty()) {
- // no need to be analyzed
- return;
- }
-
- // read the api-regions and create a Sieve data structure for checks
-
- 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
+ protected void execute(ApiRegions apiRegions, AnalyserTaskContext ctx) throws Exception {
+ // for each bundle, get the Export-Package and process the packages
FeatureDescriptor featureDescriptor = ctx.getFeatureDescriptor();
for (BundleDescriptor bundleDescriptor : featureDescriptor.getBundleDescriptors()) {
@@ -110,7 +59,7 @@ public class CheckApiRegions implements AnalyserTask {
Formatter formatter = new Formatter();
formatter.format("Region '%s' defined in feature '%s' declares %s package%s which %s not exported by any bundle:%n",
region,
- feature.getId(),
+ ctx.getFeature().getId(),
apis.size(),
getExtension(apis, "", "s"),
getExtension(apis, "is", "are"));
@@ -130,103 +79,4 @@ public class CheckApiRegions implements AnalyserTask {
return collection.size() > 1 ? plural : singular;
}
- private static ApiRegions fromJson(String jsonRepresentation) {
- ApiRegions apiRegions = new ApiRegions();
-
- // pointers
- Event event;
- String region = null;
- Collection<String> apis = null;
-
- JsonParser parser = Json.createParser(new StringReader(jsonRepresentation));
- while (parser.hasNext()) {
- event = parser.next();
- if (Event.KEY_NAME == event) {
- switch (parser.getString()) {
- case NAME_KEY:
- parser.next();
- region = parser.getString();
- break;
-
- case EXPORTS_KEY:
- apis = new LinkedList<>();
-
- // start array
- parser.next();
-
- while (parser.hasNext() && Event.VALUE_STRING == parser.next()) {
- String api = parser.getString();
- // skip comments
- if ('#' != api.charAt(0)) {
- apis.add(api);
- }
- }
-
- break;
-
- default:
- break;
- }
- } else if (Event.END_OBJECT == event) {
- if (region != null && apis != null) {
- apiRegions.add(region, apis);
- }
-
- region = null;
- apis = null;
- }
- }
-
- return apiRegions;
- }
-
- // the Sieve data structure to check exported packages
-
- private static final class ApiRegions {
-
- // class members
-
- private final Map<String, Set<String>> apis = new TreeMap<>();
-
- // ctor
-
- protected ApiRegions() {
- // it should not be directly instantiated outside this package
- }
-
- // methods
-
- public void add(String region, Collection<String> exportedApis) {
- apis.computeIfAbsent(region, k -> new TreeSet<>()).addAll(exportedApis);
- }
-
- public Iterable<String> getRegions() {
- return apis.keySet();
- }
-
- public Set<String> getApis(String region) {
- return apis.computeIfAbsent(region, k -> Collections.emptySet());
- }
-
- public void remove(String packageName) {
- apis.values().forEach(apis -> apis.remove(packageName));
- }
-
- public boolean isEmpty() {
- for (Set<String> packages : apis.values()) {
- if (!packages.isEmpty()) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- return apis.toString().replace(',', '\n');
- }
-
- }
-
-
}
diff --git a/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsDependencies.java b/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsDependencies.java
new file mode 100644
index 0000000..93dfb7c
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsDependencies.java
@@ -0,0 +1,71 @@
+/*
+ * 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 java.util.Set;
+
+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.osgi.framework.Constants;
+
+public class CheckApiRegionsDependencies extends AbstractApiRegionsAnalyserTask {
+
+ private static final String GLOBAL_REGION_NAME = "global";
+
+ private static final String DEPRECATED_REGION_NAME = "deprecated";
+
+ @Override
+ public String getId() {
+ return API_REGIONS_KEY + "-dependencies";
+ }
+
+ @Override
+ public String getName() {
+ return "Api Regions dependecies analyser task";
+ }
+
+ @Override
+ protected void execute(ApiRegions apiRegions, AnalyserTaskContext ctx) throws Exception {
+ Set<String> globalApis = apiRegions.getApis(GLOBAL_REGION_NAME);
+ Set<String> deprectaedApis = apiRegions.getApis(DEPRECATED_REGION_NAME);
+
+ FeatureDescriptor featureDescriptor = ctx.getFeatureDescriptor();
+ for (BundleDescriptor bundleDescriptor : featureDescriptor.getBundleDescriptors()) {
+ for (PackageInfo packageInfo : bundleDescriptor.getExportedPackages()) {
+ String exportedPackage = packageInfo.getName();
+
+ if (globalApis.contains(exportedPackage)) {
+ for (String uses : packageInfo.getUses()) {
+ if (deprectaedApis.contains(uses)) {
+ String errorMessage = String.format(
+ "Bundle '%s', defined in feature '%s', declares '%s' in the '%s' header which requires '%s' package that is in the 'deprecated' region",
+ bundleDescriptor.getArtifact().getId(),
+ ctx.getFeature().getId(),
+ exportedPackage,
+ Constants.EXPORT_PACKAGE,
+ uses);
+ ctx.reportError(errorMessage);
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java b/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
index bb7081b..9979aab 100644
--- a/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
+++ b/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
@@ -16,6 +16,9 @@
*/
package org.apache.sling.feature.scanner;
+import java.util.Collections;
+import java.util.Set;
+
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
@@ -24,11 +27,17 @@ public class PackageInfo implements Comparable<PackageInfo> {
private final boolean optional;
private final String name;
private final String version;
+ private final Set<String> uses;
public PackageInfo(final String name, final String version, final boolean optional) {
+ this(name, version, optional, Collections.emptySet());
+ }
+
+ public PackageInfo(final String name, final String version, final boolean optional, Set<String> uses) {
this.name = name;
this.version = version;
this.optional = optional;
+ this.uses = uses;
}
public String getName() {
@@ -57,6 +66,10 @@ public class PackageInfo implements Comparable<PackageInfo> {
return new VersionRange(this.version);
}
+ public Set<String> getUses() {
+ return uses;
+ }
+
@Override
public String toString() {
return "Package " + name
diff --git a/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java b/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
index d933060..f8d3fe7 100644
--- a/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
+++ b/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
@@ -20,7 +20,10 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
@@ -169,9 +172,21 @@ public class BundleDescriptorImpl
final String resolution = entry.getDirective("resolution");
optional = "optional".equalsIgnoreCase(resolution);
}
+
+ Set<String> uses = new HashSet<>();
+ String usesAttribute = entry.getDirective("uses");
+ if (usesAttribute != null && !usesAttribute.isEmpty()) {
+ StringTokenizer tokenizer = new StringTokenizer(usesAttribute, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String usePackage = tokenizer.nextToken();
+ uses.add(usePackage);
+ }
+ }
+
final PackageInfo pck = new PackageInfo(entry.getName(),
version,
- optional);
+ optional,
+ uses);
pcks.add(pck);
}
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/AbstractApiRegionsAnalyserTaskTest.java
similarity index 82%
copy from src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsTest.java
copy to src/test/java/org/apache/sling/feature/analyser/task/impl/AbstractApiRegionsAnalyserTaskTest.java
index bfbf446..fdb1ba8 100644
--- a/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsTest.java
+++ b/src/test/java/org/apache/sling/feature/analyser/task/impl/AbstractApiRegionsAnalyserTaskTest.java
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.Manifest;
@@ -38,11 +39,25 @@ 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.After;
+import org.junit.Before;
import org.junit.Test;
-public class CheckApiRegionsTest {
+public abstract class AbstractApiRegionsAnalyserTaskTest<T extends AbstractApiRegionsAnalyserTask> {
- private AnalyserTask checkApiRegions = new CheckApiRegions();
+ protected abstract T newTask();
+
+ private AnalyserTask analyserTask;
+
+ @Before
+ public void setUp() {
+ analyserTask = newTask();
+ }
+
+ @After
+ public void tearDown() {
+ analyserTask = null;
+ }
@Test
public void testNoApiRegionsExtension() throws Exception {
@@ -70,30 +85,14 @@ public class CheckApiRegionsTest {
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 {
+ protected final 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 {
+ protected final List<String> execute(Extension extension) throws Exception {
Extensions extensions = mock(Extensions.class);
when(extensions.getByName("api-regions")).thenReturn(extension);
@@ -108,7 +107,7 @@ public class CheckApiRegionsTest {
AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
when(ctx.getFeature()).thenReturn(feature);
- PackageInfo packageInfo = new PackageInfo("org.osgi.util.function", "1.0", false);
+ PackageInfo packageInfo = new PackageInfo("org.osgi.util.function", "1.0", false, Collections.singleton("org.objectweb.asm"));
BundleDescriptor bundleDescriptor = new TestBundleDescriptor();
bundleDescriptor.getExportedPackages().add(packageInfo);
@@ -125,7 +124,7 @@ public class CheckApiRegionsTest {
return null;
}).when(ctx).reportError(anyString());
- checkApiRegions.execute(ctx);
+ analyserTask.execute(ctx);
return errors;
}
@@ -149,8 +148,7 @@ public class CheckApiRegionsTest {
@Override
public Artifact getArtifact() {
- // do nothing
- return null;
+ return new Artifact(ArtifactId.fromMvnId("org.osgi:org.osgi.util.function:1.0.0"));
}
@Override
diff --git a/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsDependenciesTest.java b/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsDependenciesTest.java
new file mode 100644
index 0000000..09eed5a
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckApiRegionsDependenciesTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 java.util.List;
+
+import org.junit.Test;
+
+public class CheckApiRegionsDependenciesTest extends AbstractApiRegionsAnalyserTaskTest<CheckApiRegionsDependencies> {
+
+ @Override
+ protected CheckApiRegionsDependencies newTask() {
+ return new CheckApiRegionsDependencies();
+ }
+
+ @Test
+ public void testNotValidApiRegionJson() throws Exception {
+ List<String> errors = execute("[{\"name\": \"global\",\"exports\": [\"org.osgi.util.function\"]},{\"name\": \"deprecated\",\"exports\": [\"org.objectweb.asm\"]}]");
+
+ assertFalse(errors.isEmpty());
+ assertTrue(errors.iterator()
+ .next()
+ .startsWith("Bundle 'org.osgi:org.osgi.util.function:1.0.0', defined in feature 'org.apache.sling.testing:org.apache.sling.testing.apiregions:1.0.0', declares 'org.osgi.util.function' in the 'Export-Package' header which requires 'org.objectweb.asm' package that is in the 'deprecated' region"));
+ }
+
+ @Test
+ public void testValidApiRegionJson() throws Exception {
+ List<String> errors = execute("[{\"name\": \"global\",\"exports\": [\"org.osgi.util.function\"]}]");
+ assertTrue(errors.isEmpty());
+ }
+
+}
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
index bfbf446..ab73570 100644
--- 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
@@ -18,56 +18,16 @@ 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 {
+public class CheckApiRegionsTest extends AbstractApiRegionsAnalyserTaskTest<CheckApiRegions> {
- 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'"));
+ @Override
+ protected CheckApiRegions newTask() {
+ return new CheckApiRegions();
}
@Test
@@ -86,97 +46,4 @@ public class CheckApiRegionsTest {
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;
- }
-
- }
-
}