blob: fb4fa0ce59e0876b42feb0b64c64d7470da9d12f [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.sling.feature.extension.apiregions.api.config.validation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.builder.FeatureProvider;
import org.apache.sling.feature.extension.apiregions.api.config.ConfigurationApi;
import org.apache.sling.feature.extension.apiregions.api.config.ConfigurationDescription;
import org.apache.sling.feature.extension.apiregions.api.config.FactoryConfigurationDescription;
import org.apache.sling.feature.extension.apiregions.api.config.Operation;
import org.apache.sling.feature.extension.apiregions.api.config.PropertyDescription;
import org.apache.sling.feature.extension.apiregions.api.config.Region;
import org.junit.Before;
import org.junit.Test;
public class FeatureValidatorTest {
private static final String PID = "org.apache.sling";
private static final String FACTORY_PID = "org.apache.sling.factory";
private final FeatureValidator validator = new FeatureValidator();
@Before public void setup() {
this.validator.setFeatureProvider(null);
}
private Feature createFeature(final String id) {
final Feature f= new Feature(ArtifactId.parse(id));
final Configuration c = new Configuration(PID);
c.getProperties().put("prop", "a");
f.getConfigurations().add(c);
final Configuration fc = new Configuration(FACTORY_PID.concat("~print"));
fc.getProperties().put("key", "value");
f.getConfigurations().add(fc);
return f;
}
private ConfigurationApi createApi() {
final ConfigurationApi api = new ConfigurationApi();
final ConfigurationDescription cd = new ConfigurationDescription();
cd.getPropertyDescriptions().put("prop", new PropertyDescription());
api.getConfigurationDescriptions().put(PID, cd);
final FactoryConfigurationDescription fd = new FactoryConfigurationDescription();
fd.getPropertyDescriptions().put("key", new PropertyDescription());
api.getFactoryConfigurationDescriptions().put(FACTORY_PID, fd);
return api;
}
@Test public void testGetRegionInfoNoOrigin() {
final Feature f1 = createFeature("g:a:1");
final Configuration cfg = f1.getConfigurations().getConfiguration(PID);
// no api set
FeatureValidator.RegionInfo info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertFalse(info.isUpdate);
// empty region in api
final ConfigurationApi api = createApi();
ConfigurationApi.setConfigurationApi(f1, api);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertFalse(info.isUpdate);
// global region in api
api.setRegion(Region.GLOBAL);
ConfigurationApi.setConfigurationApi(f1, api);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertFalse(info.isUpdate);
// internal region in api
api.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f1, api);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.INTERNAL, info.region);
assertFalse(info.isUpdate);
}
@Test public void testGetRegionInfoSingleOrigin() {
final Feature f1 = createFeature("g:a:1");
final Configuration cfg = f1.getConfigurations().getConfiguration(PID);
final Feature f2 = createFeature("g:b:1");
cfg.setFeatureOrigins(Collections.singletonList(f2.getId()));
// set feature provider to always provide f2
this.validator.setFeatureProvider(id -> f2);
// no api in origin
FeatureValidator.RegionInfo info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertFalse(info.isUpdate);
// no region in api
final ConfigurationApi api2 = new ConfigurationApi();
ConfigurationApi.setConfigurationApi(f2, api2);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertFalse(info.isUpdate);
// global in api
api2.setRegion(Region.GLOBAL);
ConfigurationApi.setConfigurationApi(f2, api2);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertFalse(info.isUpdate);
// internal in api
api2.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f2, api2);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.INTERNAL, info.region);
assertFalse(info.isUpdate);
// unknown id
this.validator.setFeatureProvider(id -> null);
cfg.setFeatureOrigins(Collections.singletonList(ArtifactId.parse("g:xy:1")));
info = validator.getRegionInfo(f1, cfg);
assertNull(info);
}
@Test public void testGetRegionInfoMultipleOrigins() {
final Feature f1 = createFeature("g:a:1");
final Configuration cfg = f1.getConfigurations().getConfiguration(PID);
final Feature f2 = createFeature("g:b:1");
final Feature f3 = createFeature("g:c:1");
cfg.setFeatureOrigins(Arrays.asList(f2.getId(), f3.getId()));
final FeatureProvider provider = new FeatureProvider() {
@Override
public Feature provide(final ArtifactId id) {
if ( f1.getId().equals(id) ) {
return f1;
} else if ( f2.getId().equals(id)) {
return f2;
} else if ( f3.getId().equals(id)) {
return f3;
}
return null;
}
};
this.validator.setFeatureProvider(provider);
// no api in origins
FeatureValidator.RegionInfo info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertTrue(info.isUpdate);
// global-internal
final ConfigurationApi api2 = new ConfigurationApi();
final ConfigurationApi api3 = new ConfigurationApi();
api2.setRegion(Region.GLOBAL);
api3.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f2, api2);
ConfigurationApi.setConfigurationApi(f3, api3);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertTrue(info.isUpdate);
// global-global
api2.setRegion(Region.GLOBAL);
api3.setRegion(Region.GLOBAL);
ConfigurationApi.setConfigurationApi(f2, api2);
ConfigurationApi.setConfigurationApi(f3, api3);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertTrue(info.isUpdate);
// internal-internal
api2.setRegion(Region.INTERNAL);
api3.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f2, api2);
ConfigurationApi.setConfigurationApi(f3, api3);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.INTERNAL, info.region);
assertTrue(info.isUpdate);
// internal-global
api2.setRegion(Region.INTERNAL);
api3.setRegion(Region.GLOBAL);
ConfigurationApi.setConfigurationApi(f2, api2);
ConfigurationApi.setConfigurationApi(f3, api3);
info = validator.getRegionInfo(f1, cfg);
assertEquals(Region.GLOBAL, info.region);
assertTrue(info.isUpdate);
}
@Test public void testSingleValidation() {
final Feature f1 = createFeature("g:a:1");
final ConfigurationApi api = createApi();
ConfigurationApi.setConfigurationApi(f1, api);
FeatureValidationResult result = validator.validate(f1, api);
assertTrue(result.isValid());
// add property
f1.getConfigurations().getConfiguration(PID).getProperties().put("b", "x");
result = validator.validate(f1, api);
assertFalse(result.isValid());
}
@Test public void testInternalConfiguration() {
final Feature f1 = createFeature("g:a:1");
final ConfigurationApi api = new ConfigurationApi();
ConfigurationApi.setConfigurationApi(f1, api);
// global region
FeatureValidationResult result = validator.validate(f1, api);
assertTrue(result.isValid());
// mark configurations as internal
api.getInternalConfigurations().add(PID);
api.getInternalFactoryConfigurations().add(FACTORY_PID);
ConfigurationApi.setConfigurationApi(f1, api);
// global region
result = validator.validate(f1, api);
assertFalse(result.isValid());
assertFalse(result.getConfigurationResults().get(PID).isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~print")).isValid());
// internal region
api.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
}
@Test public void testInternalFactoryNames() {
final Feature f1 = createFeature("g:a:1");
final Configuration fa = new Configuration(FACTORY_PID.concat("~a"));
fa.getProperties().put("key", "value");
f1.getConfigurations().add(fa);
final Configuration fb = new Configuration(FACTORY_PID.concat("~b"));
fb.getProperties().put("key", "value");
f1.getConfigurations().add(fb);
final ConfigurationApi api = createApi();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getInternalNames().add("a");
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getInternalNames().add("b");
ConfigurationApi.setConfigurationApi(f1, api);
FeatureValidationResult result = validator.validate(f1, api);
assertFalse(result.isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~a")).isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~b")).isValid());
assertTrue(result.getConfigurationResults().get(FACTORY_PID.concat("~print")).isValid());
// internal region
api.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
}
@Test public void testFactoryConfigurationOperationsWithCreate() {
final Feature f1 = createFeature("g:a:1");
final ConfigurationApi api = createApi();
// no operation -> fail
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
ConfigurationApi.setConfigurationApi(f1, api);
FeatureValidationResult result = validator.validate(f1, api);
assertFalse(result.isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~print")).isValid());
// only update -> fail
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.UPDATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertFalse(result.isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~print")).isValid());
// only create -> success
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.CREATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
// update, create -> success
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.CREATE);
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.UPDATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
// internal region -> always success
api.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.UPDATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.CREATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
}
@Test public void testFactoryConfigurationOperationsWithUpdate() {
final Feature f1 = createFeature("g:a:1");
final ConfigurationApi api = createApi();
final Configuration cfg = f1.getConfigurations().getConfiguration(FACTORY_PID.concat("~print"));
final Feature f2 = createFeature("g:b:1");
final Feature f3 = createFeature("g:c:1");
cfg.setFeatureOrigins(Arrays.asList(f2.getId(), f3.getId()));
final FeatureProvider provider = new FeatureProvider() {
@Override
public Feature provide(final ArtifactId id) {
if ( f1.getId().equals(id) ) {
return f1;
} else if ( f2.getId().equals(id)) {
return f2;
} else if ( f3.getId().equals(id)) {
return f3;
}
return null;
}
};
this.validator.setFeatureProvider(provider);
// no operation -> fail
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
ConfigurationApi.setConfigurationApi(f1, api);
FeatureValidationResult result = validator.validate(f1, api);
assertFalse(result.isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~print")).isValid());
// only update -> success
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.UPDATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
// only create -> fail
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.CREATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertFalse(result.isValid());
assertFalse(result.getConfigurationResults().get(FACTORY_PID.concat("~print")).isValid());
// update, create -> success
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.CREATE);
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.UPDATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
// internal region -> always success
api.setRegion(Region.INTERNAL);
ConfigurationApi.setConfigurationApi(f1, api);
ConfigurationApi.setConfigurationApi(f2, api);
ConfigurationApi.setConfigurationApi(f3, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.UPDATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().add(Operation.CREATE);
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
api.getFactoryConfigurationDescriptions().get(FACTORY_PID).getOperations().clear();
ConfigurationApi.setConfigurationApi(f1, api);
result = validator.validate(f1, api);
assertTrue(result.isValid());
}
}