jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From k...@apache.org
Subject svn commit: r1867884 [5/6] - in /jackrabbit/commons/filevault/trunk: ./ .mvn/ parent/ vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ vault-core/src/main/java/org/apache/jackr...
Date Wed, 02 Oct 2019 11:28:26 GMT
Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedFilterValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedFilterValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedFilterValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedFilterValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,381 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.AnyValidationViolationMatcher;
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.ValidationViolation;
+import org.apache.jackrabbit.filevault.validation.spi.FilterValidator;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.packaging.impl.DefaultPackageInfo;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.xml.sax.SAXException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AdvancedFilterValidatorTest {
+
+    private AdvancedFilterValidator validator;
+
+    @Mock
+    private FilterValidator filterValidator1;
+
+    @Mock
+    private FilterValidator filterValidator2;
+
+    @Mock
+    private PackageProperties properties;
+
+    @Mock
+    private WorkspaceFilter filter;
+
+    private Collection<PackageInfo> dependenciesMetaInfo;
+
+    private Collection<String> validRoots;
+
+    @Before
+    public void setUp() {
+        dependenciesMetaInfo = new LinkedList<>();
+        validRoots = new LinkedList<>();
+        validRoots.addAll(AdvancedFilterValidatorFactory.DEFAULT_VALID_ROOTS);
+    }
+
+    @Test
+    public void testValidFilter()
+            throws URISyntaxException, IOException, SAXException, ParserConfigurationException, ConfigurationException {
+        Mockito.when(filterValidator2.validate(Mockito.any()))
+                .thenReturn(Collections.singleton(new ValidationMessage(ValidationMessageSeverity.ERROR, "error1")));
+        Mockito.when(filterValidator1.validate(Mockito.any())).thenReturn(null);
+        try (InputStream input = this.getClass()
+                .getResourceAsStream("/simple-package/META-INF/vault/filter.xml");
+                InputStream input2 = this.getClass()
+                        .getResourceAsStream("/simple-package/META-INF/vault/filter.xml")) {
+
+            DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+            filter.load(input);
+
+            validator = new AdvancedFilterValidator(
+                    ValidationMessageSeverity.WARN,
+                    AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                    ValidationMessageSeverity.ERROR,
+                    dependenciesMetaInfo,
+                    filter, // this is per test
+                    validRoots);
+            Map<String, FilterValidator> validatorsById = new HashMap<>();
+            validatorsById.put("id1", filterValidator1);
+            validatorsById.put("id2", filterValidator2);
+            validatorsById.put("myself", validator);
+            validator.setFilterValidators(validatorsById);
+
+            Collection<ValidationMessage> messages = validator.validateMetaInfData(input2, Paths.get("vault/filter.xml"));
+            ValidationExecutorTest.assertViolation(messages,
+                    new ValidationViolation("id2", ValidationMessageSeverity.ERROR, "error1"));
+            // all contained FilterSets are sealed (due to the call of AdvancedFilterValidator.validate(...) -> FilterSet.getEntries())
+            sealFilterSet(filter.getFilterSets());
+            sealFilterSet(filter.getPropertyFilterSets());
+            Mockito.verify(filterValidator1).validate(filter);
+            Mockito.verify(filterValidator2).validate(filter);
+
+            // as this is a cleanup filter no orphaned entries should be there
+            Assert.assertThat(validator.done(), AnyValidationMessageMatcher.noValidationInCollection());
+        }
+    }
+
+    @Test
+    public void testAllNodesContained() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.WARN,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+        Assert.assertThat(validator.validate("/apps/test/huhu"), AnyValidationViolationMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/apps/test"), AnyValidationViolationMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/apps/test2/valid"), AnyValidationViolationMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/apps/test3/valid"), AnyValidationViolationMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/apps/test4/test/valid"), AnyValidationViolationMatcher.noValidationInCollection());
+    }
+
+    @Test
+    public void testUncontainedNodes() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.WARN,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/notcontained"),
+                new ValidationMessage(ValidationMessageSeverity.WARN,
+                        String.format(AdvancedFilterValidator.MESSAGE_NODE_NOT_CONTAINED, "/apps/notcontained")));
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/test3/invalid"),
+                new ValidationMessage(ValidationMessageSeverity.WARN,
+                        String.format(AdvancedFilterValidator.MESSAGE_NODE_NOT_CONTAINED, "/apps/test3/invalid")));
+    }
+
+    @Test
+    public void testUncoveredAncestorNodesFailure() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.ERROR,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+
+        // default severity INFO
+        ValidationExecutorTest.assertViolation(validator.validate("/apps"), ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.INFO,
+                        String.format(AdvancedFilterValidator.MESSAGE_ANCESTOR_NODE_NOT_COVERED_BUT_VALID_ROOT, "/apps")));
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/test4"), ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.INFO,
+                        String.format(AdvancedFilterValidator.MESSAGE_ANCESTOR_NODE_NOT_COVERED, "/apps/test4")));
+
+        // default severity ERROR
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/test4"), ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(AdvancedFilterValidator.MESSAGE_ANCESTOR_NODE_NOT_COVERED, "/apps/test4")));
+
+        // set valid roots
+        validRoots.add("/someroot");
+        // default severity ERROR
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.WARN,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                Collections.emptyList());
+        ValidationExecutorTest.assertViolation(validator.validate("/apps"), ValidationMessageSeverity.WARN,
+                new ValidationMessage(ValidationMessageSeverity.WARN,
+                        String.format(AdvancedFilterValidator.MESSAGE_ANCESTOR_NODE_NOT_COVERED, "/apps")));
+    }
+
+    @Test
+    public void testRootNodesInFilterPartlyContainedInDependencies() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter dependencyFilter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/dependency1-filter.xml")) {
+            dependencyFilter.load(input);
+        }
+        
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter-with-uncovered-roots.xml")) {
+            filter.load(input);
+        }
+        validRoots.add("/customroot");
+        dependenciesMetaInfo.add(new DefaultPackageInfo(PackageId.fromString("group:dependency1"), dependencyFilter, PackageType.APPLICATION));
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+        Collection<ValidationMessage> messages = validator.validate(filter);
+        ValidationExecutorTest.assertViolation(messages, ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(AdvancedFilterValidator.MESSAGE_FILTER_ROOT_ANCESTOR_UNCOVERED, "/apps/uncovered")),
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(AdvancedFilterValidator.MESSAGE_FILTER_ROOT_ANCESTOR_COVERED_BUT_EXCLUDED, "/apps/covered2/excluded", "group:dependency1")),
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(AdvancedFilterValidator.MESSAGE_FILTER_ROOT_ANCESTOR_UNCOVERED, "/invalidroot")));
+    }
+
+    @Test
+    public void testOrphanedFilterEntries() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.INFO,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+        Collection<ValidationMessage> messages = validator.validate(filter);
+
+        messages = validator.validate("/apps/test3");
+        ValidationExecutorTest.assertViolation(messages, ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.INFO,
+                        String.format(AdvancedFilterValidator.MESSAGE_NODE_BELOW_CLEANUP_FILTER, "/apps/test3")));
+        Assert.assertThat(validator.validate("/apps/test2/something/anothervalid"), AnyValidationMessageMatcher.noValidationInCollection());
+        messages = validator.done();
+        ValidationExecutorTest.assertViolation(messages, ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(AdvancedFilterValidator.MESSAGE_ORPHANED_FILTER_ENTRIES, "entry with root '/apps/test', includes [regex: .*/valid] below root '/apps/test2', entry with root '/apps/test4/test'")));
+    }
+
+    @Test
+    public void testUncoveredRootNodesInFilter() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.INFO,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+        Collection<ValidationMessage> messages = validator.validate(filter);
+        ValidationExecutorTest.assertViolation(messages, ValidationMessageSeverity.INFO,
+                new ValidationMessage(ValidationMessageSeverity.INFO,
+                        String.format(AdvancedFilterValidator.MESSAGE_FILTER_ROOT_ANCESTOR_UNCOVERED, "/apps/test4")));
+    }
+
+    @Test
+    public void testFilterWithInvalidElements()
+            throws URISyntaxException, IOException, SAXException, ParserConfigurationException, ConfigurationException {
+        try (InputStream input = this.getClass()
+                .getResourceAsStream("/invalid-package/META-INF/vault/filter.xml")) {
+            validator = new AdvancedFilterValidator(
+                    ValidationMessageSeverity.WARN,
+                    AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                    ValidationMessageSeverity.ERROR,
+                    dependenciesMetaInfo,
+                    filter,
+                    validRoots);
+            Collection<ValidationMessage> messages = validator.validateMetaInfData(input, Paths.get("vault/filter.xml"));
+            ValidationExecutorTest.assertViolation(messages,
+                    new ValidationMessage(ValidationMessageSeverity.WARN,
+                            "cvc-complex-type.3.2.2: Attribute 'mode' is not allowed to appear in element 'exclude'.", 20, 51, null),
+                    new ValidationMessage(ValidationMessageSeverity.WARN,
+                            "cvc-complex-type.2.4.a: Invalid content was found starting with element 'invalidelement'. One of '{exclude, include}' is expected.",
+                            22, 27, null),
+                    new ValidationMessage(ValidationMessageSeverity.WARN, AdvancedFilterValidator.MESSAGE_INVALID_FILTER_XML)); // because
+                                                                                                                                // of
+                                                                                                                                // invalid
+                                                                                                                                // regex
+        }
+    }
+
+    @Test
+    public void testFilterWithNonMatchingRegex() throws URISyntaxException, IOException, SAXException,
+            ParserConfigurationException, ConfigurationException {
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.WARN,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+        validator.setFilterValidators(Collections.singletonMap("filterid", validator));
+        try (InputStream input = this.getClass()
+                .getResourceAsStream("/invalid-package/META-INF/vault/filter-non-matching-regex.xml")) {
+            Collection<ValidationMessage> messages = validator.validateMetaInfData(input, Paths.get("vault/filter-non-matching-regex.xml"));
+            ValidationExecutorTest.assertViolation(messages,
+                    new ValidationViolation("filterid", ValidationMessageSeverity.WARN,
+                            String.format(AdvancedFilterValidator.MESSAGE_INVALID_PATTERN,
+                                    "/some/other", "/etc/project1")),
+                    new ValidationViolation("filterid", ValidationMessageSeverity.WARN,
+                            String.format(AdvancedFilterValidator.MESSAGE_ROOT_PATH_NOT_ABSOLUTE, "invalidroot")));
+        }
+    }
+
+    @Test
+    public void testIsRegexValidForRootPath() {
+        Assert.assertTrue(AdvancedFilterValidator.isRegexValidForRootPath("/apps/test", "/apps"));
+        Assert.assertTrue(AdvancedFilterValidator.isRegexValidForRootPath(".*/somepath", "/apps"));
+        Assert.assertTrue(AdvancedFilterValidator.isRegexValidForRootPath("^.*/somepath$", "/apps"));
+        Assert.assertFalse(AdvancedFilterValidator.isRegexValidForRootPath("/[aps]{4}", "/apps/test"));
+
+        Assert.assertFalse(AdvancedFilterValidator.isRegexValidForRootPath("/apps", "/apps/test"));
+        Assert.assertFalse(AdvancedFilterValidator.isRegexValidForRootPath("/apps/test", "/apps2/test"));
+        Assert.assertFalse(AdvancedFilterValidator.isRegexValidForRootPath("/[aps]{3}/somepath", "/apps"));
+        Assert.assertTrue(AdvancedFilterValidator.isRegexValidForRootPath("/apps/test", "/apps/test"));
+    }
+
+    private static void sealFilterSet(List<PathFilterSet> pathFilterSets) {
+        for (PathFilterSet pathFilterSet : pathFilterSets) {
+            pathFilterSet.seal();
+        }
+    }
+
+    @Test
+    public void testHasDanglingAncestors() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/test-filter.xml")) {
+            filter.load(input);
+        }
+        validator = new AdvancedFilterValidator(
+                ValidationMessageSeverity.WARN,
+                AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES,
+                ValidationMessageSeverity.ERROR,
+                dependenciesMetaInfo,
+                filter, // this is per test
+                validRoots);
+        Assert.assertNull(validator.getDanglingAncestorNodePath("/var/acs-commons/on-deploy-scripts-status/README.txt", filter));
+        Assert.assertEquals("/var/acs-commons/mcp", validator.getDanglingAncestorNodePath("/var/acs-commons/mcp/rep:policy", filter));
+        // https://issues.apache.org/jira/browse/JCRVLT-378
+        Assert.assertNull(validator.getDanglingAncestorNodePath("/var/acs-commons/on-deploy-scripts-status/rep:policy", filter));
+        // make sure it is returned only once
+        Assert.assertNull(validator.getDanglingAncestorNodePath("/var/acs-commons/mcp/rep:policy/allow", filter));
+    }
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedPropertiesValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedPropertiesValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedPropertiesValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/AdvancedPropertiesValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,96 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.ValidationViolation;
+import org.apache.jackrabbit.filevault.validation.spi.PropertiesValidator;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.impl.DefaultPackageProperties;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.xml.sax.SAXException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AdvancedPropertiesValidatorTest {
+
+    private AdvancedPropertiesValidator validator;
+
+    @Mock
+    private PropertiesValidator propertiesValidator1;
+
+    @Mock
+    private PropertiesValidator propertiesValidator2;
+
+
+    @Before
+    public void setUp() {
+        validator = new AdvancedPropertiesValidator(ValidationMessageSeverity.WARN);
+        Map<String, PropertiesValidator> validatorsById = new HashMap<>();
+        validatorsById.put("id1", propertiesValidator1);
+        validatorsById.put("id2", propertiesValidator2);
+        validator.setPropertiesValidators(validatorsById);
+    }
+
+    @Test
+    public void testProperties()
+            throws URISyntaxException, IOException, SAXException, ParserConfigurationException, ConfigurationException {
+        Mockito.when(propertiesValidator1.validate(Mockito.any())).thenReturn(Collections.singleton(new ValidationMessage(ValidationMessageSeverity.ERROR, "error1")));
+        Mockito.when(propertiesValidator2.validate(Mockito.any())).thenReturn(null);
+        PackageProperties properties;
+        try (InputStream input = this.getClass().getResourceAsStream("/simple-package/META-INF/vault/properties.xml");
+                InputStream input2 = this.getClass().getResourceAsStream("/simple-package/META-INF/vault/properties.xml")) {
+            Collection<ValidationMessage> messages = validator.validateMetaInfData(input, Paths.get("vault/properties.xml"));
+            ValidationExecutorTest.assertViolation(messages,
+                    new ValidationViolation("id1", ValidationMessageSeverity.ERROR, "error1"));
+            properties = DefaultPackageProperties.fromInputStream(input2);
+            Mockito.verify(propertiesValidator1).validate(properties);
+        }
+    }
+
+    @Test
+    public void testPropertiesWithInvalidElement()
+            throws URISyntaxException, IOException, SAXException, ParserConfigurationException, ConfigurationException {
+        try (InputStream input = this.getClass().getResourceAsStream("/invalid-package/META-INF/vault/properties.xml")) {
+            Collection<ValidationMessage> messages = validator.validateMetaInfData(input, Paths.get("vault/properties.xml"));
+            ValidationExecutorTest.assertViolation(messages,
+                    new ValidationMessage(ValidationMessageSeverity.WARN,
+                                   AdvancedPropertiesValidator.MESSAGE_INVALID_PROPERTIES_XML,
+                            new InvalidPropertiesFormatException("org.xml.sax.SAXParseException; lineNumber: 35; columnNumber: 19; Element type \"someinvalidentry\" must be declared.")));
+        }
+    }
+
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/DependencyValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/DependencyValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/DependencyValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/DependencyValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,101 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.packaging.Dependency;
+import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.packaging.impl.DefaultPackageInfo;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.xml.sax.SAXException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DependencyValidatorTest {
+
+    private DependencyValidator validator;
+
+    @Mock
+    private PackageProperties properties;
+
+    private Collection<PackageInfo> resolvedPackageInfos;
+
+    @Before
+    public void setUp() throws ParserConfigurationException, SAXException {
+        Dependency[] dependencies = Dependency.fromString("group1:package1:[0,1)", "group2:package2:(2,3)");
+        Mockito.when(properties.getDependencies()).thenReturn(dependencies);
+        resolvedPackageInfos = new LinkedList<>();
+        validator = new DependencyValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, resolvedPackageInfos);
+    }
+
+    @Test
+    public void testWithResolvedNonOverlappingDependency() {
+        resolvedPackageInfos.add(getPackageInfo("group1:package1:0.1", "/filter.xml", null));
+        resolvedPackageInfos.add(getPackageInfo("group2:package2:2.9", "/simple-package/META-INF/vault/filter.xml", null));
+        
+        Assert.assertThat(validator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+    }
+
+    @Test
+    public void testValidateWithUnresolvedDependencies() {
+        resolvedPackageInfos.add(getPackageInfo("group1:package1:0.1", "/filter.xml", null));
+        Assert.assertThat(validator.validate(properties), 
+                Matchers.contains(new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(String.format(DependencyValidator.MESSAGE_UNRESOLVED_DEPENDENCY, "group2:package2:(2,3)")))));
+    }
+
+    @Test
+    public void testValidateWithDependenciesWithOverlappingFilterRoots() {
+        resolvedPackageInfos.add(getPackageInfo("group1:package1:0.1", "/simple-package/META-INF/vault/filter.xml", null));
+        resolvedPackageInfos.add(getPackageInfo("group2:package2:2.9", "/simple-package/META-INF/vault/filter.xml", null));
+        Assert.assertThat(validator.validate(properties), 
+                Matchers.contains(new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(String.format(String.format(DependencyValidator.MESSAGE_DEPENDENCIES_WITH_OVERLAPPING_FILTERS,
+                        "group2:package2:2.9", "/etc/project1", "group1:package1:0.1"))))));
+    }
+
+    private PackageInfo getPackageInfo(String packageId, String filterResourceName, PackageType packageType) {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream(filterResourceName)) {
+            if (input == null) {
+                throw new IllegalArgumentException("Could not find resource file at " + filterResourceName);
+            }
+            filter.load(input);
+        } catch (IOException | ConfigurationException e) {
+            throw new IllegalArgumentException("Could not load filter file");
+        }
+        return new DefaultPackageInfo(PackageId.fromString(packageId), filter, packageType);
+    }
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/EmptyElementsValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/EmptyElementsValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/EmptyElementsValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/EmptyElementsValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,96 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.util.DocViewNode;
+import org.apache.jackrabbit.vault.util.DocViewProperty;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EmptyElementsValidatorTest {
+
+    private EmptyElementsValidator validator;
+
+    @Before
+    public void setUp() throws IOException, ConfigurationException {
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml"))  {
+            DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+            filter.load(input);
+            validator = new EmptyElementsValidator(ValidationMessageSeverity.ERROR, filter);
+        }
+    }
+
+    @Test
+    public void testWithEmptyElements() {
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("prop1", new DocViewProperty("prop1", new String[] { "value1" } , false, PropertyType.STRING));
+
+        // order node only (no other property)
+        DocViewNode node = new DocViewNode("jcr:root", "jcr:root", null, Collections.emptyMap(), null, null);
+        Assert.assertThat(validator.validate(node, "/apps/test/node1", Paths.get("node1"), false), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        // another order node (to be covered by another file)
+        node = new DocViewNode("jcr:root", "jcr:root", null, Collections.emptyMap(), null, null);
+        Assert.assertThat(validator.validate(node, "/apps/test/node2", Paths.get("node2"), false), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        // another order node only
+        node = new DocViewNode("jcr:root", "jcr:root", null, Collections.emptyMap(), null, null);
+        Assert.assertThat(validator.validate(node, "/apps/test/node3", Paths.get("node3"), false), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        // no order node (due to props)
+        node = new DocViewNode("jcr:root", "jcr:root", null, props, null, null);
+        Assert.assertThat(validator.validate(node, "/apps/test/node4", Paths.get("node4"), false), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        // no order node (due to primary type)
+        node = new DocViewNode("jcr:root", "jcr:root", null, Collections.emptyMap(), null, "nt:unstructed");
+        Assert.assertThat(validator.validate(node, "/apps/test/node5", Paths.get("node45"), false), AnyValidationMessageMatcher.noValidationInCollection());
+        //
+        Assert.assertFalse(validator.shouldValidateJcrData(Paths.get("apps", "test", "node2")));
+        ValidationExecutorTest.assertViolation(validator.done(), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(EmptyElementsValidator.MESSAGE_EMPTY_NODES, "'/apps/test/node1' (in 'node1'), '/apps/test/node3' (in 'node3')")));
+    }
+
+    @Test
+    public void testNoEmptyElements() {
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("prop1", new DocViewProperty("prop1", new String[] { "value1" } , false, PropertyType.STRING));
+
+        // order node only (no other property)
+        DocViewNode node = new DocViewNode("jcr:root", "jcr:root", null, Collections.emptyMap(), null, "nt:unstructured");
+        Assert.assertThat(validator.validate(node, "somepath1", null, false), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        // primary node type set with additional properties
+        node = new DocViewNode("jcr:root", "jcr:root", null, props, null, "nt:unstructured");
+        Assert.assertThat(validator.validate(node, "somepath2", null, false), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertNull(validator.done());
+    }
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/MergeLimitationsValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/MergeLimitationsValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/MergeLimitationsValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/MergeLimitationsValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,74 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.util.DocViewNode;
+import org.apache.jackrabbit.vault.util.DocViewProperty;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MergeLimitationsValidatorTest {
+
+    private MergeLimitationsValidator validator;
+
+    @Before
+    public void setUp() throws IOException, ConfigurationException {
+        try (InputStream input = this.getClass().getResourceAsStream("/filter-with-merge.xml"))  {
+            DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+            filter.load(input);
+            validator = new MergeLimitationsValidator(ValidationMessageSeverity.ERROR, filter);
+        }
+    }
+
+    @Test
+    public void testWithAggregateAtWrongLevel() {
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("prop1", new DocViewProperty("prop1", new String[] { "value1" } , false, PropertyType.STRING));
+
+        DocViewNode node = new DocViewNode("somename", "somename", null, props, null, "nt:unstructured");
+        Collection<ValidationMessage> messages = validator.validate(node, "/apps/test/deep", Paths.get(".content.xml"), false);
+        ValidationExecutorTest.assertViolation(messages,
+                new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(MergeLimitationsValidator.PACKAGE_NON_ROOT_NODE_MERGED, "/apps/test/deep")));
+    }
+
+    @Test
+    public void testWithAggregateAtCorrectLevel() {
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("prop1", new DocViewProperty("prop1", new String[] { "value1" } , false, PropertyType.STRING));
+
+        DocViewNode node = new DocViewNode("somename", "somename", null, props, null, "nt:unstructured");
+        Collection<ValidationMessage> messages = validator.validate(node, "/apps/test/deep", Paths.get(".content.xml"), true);
+        Assert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
+    }
+
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/OakIndexDefinitionValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/OakIndexDefinitionValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/OakIndexDefinitionValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/OakIndexDefinitionValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,115 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.util.DocViewNode;
+import org.apache.jackrabbit.vault.util.DocViewProperty;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+public class OakIndexDefinitionValidatorTest {
+
+    private OakIndexDefinitionValidator validator;
+    private Path rootPackagePath = Paths.get("rootpackage");
+
+    @Before
+    public void setUp() throws ParserConfigurationException, SAXException {
+        validator = new OakIndexDefinitionValidator(rootPackagePath, ValidationMessageSeverity.ERROR);
+    }
+
+    @Test
+    public void test_filter() throws Exception {
+        try (InputStream input = this.getClass().getResourceAsStream("/oak-index/filter.xml")) {
+            DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+            filter.load(input);
+            Collection<ValidationMessage> messages = validator.validate(filter);
+            ValidationExecutorTest.assertViolation(messages,
+                    new ValidationMessage(ValidationMessageSeverity.ERROR,
+                            String.format(OakIndexDefinitionValidator.MESSAGE_POTENTIAL_INDEX_IN_FILTER, rootPackagePath,"/oak:index/ccProfile")),
+                    new ValidationMessage(ValidationMessageSeverity.ERROR, String
+                            .format(OakIndexDefinitionValidator.MESSAGE_POTENTIAL_INDEX_IN_FILTER, rootPackagePath, "/apps/project/oak:index/indexDef")),
+                    new ValidationMessage(ValidationMessageSeverity.ERROR, String
+                            .format(OakIndexDefinitionValidator.MESSAGE_POTENTIAL_INDEX_IN_FILTER, rootPackagePath, "/apps/anotherproject/oak:index")));
+        }
+    }
+
+    @Test
+    public void test_index_at_root() throws Exception {
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("includedPaths", new DocViewProperty("includedPaths", new String[] { "/home]" }, true, PropertyType.STRING));
+        DocViewNode node = new DocViewNode("testindex", "testindex", null, props, null, "oak:QueryIndexDefinition");
+
+        Collection<ValidationMessage> messages = validator.validate(node, "/oak:index/testindex",
+                Paths.get("_oak_index/testindex/.content.xml"), true);
+        ValidationExecutorTest.assertViolation(messages,
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(OakIndexDefinitionValidator.MESSAGE_INDEX_AT_NODE, rootPackagePath, "/oak:index/testindex")));
+    }
+
+    @Test
+    public void test_index_at_deep_path() throws Exception {
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("includedPaths", new DocViewProperty("includedPaths", new String[] { "/home]" }, true, PropertyType.STRING));
+        DocViewNode node = new DocViewNode("indexDef", "indexDef", null, props, null, "oak:QueryIndexDefinition");
+
+        Collection<ValidationMessage> messages = validator.validate(node, "/apps/project/oak:index/indexDef",
+                Paths.get("apps", "project", "_oak_index", "content.xml"), false);
+        ValidationExecutorTest.assertViolation(messages,
+                new ValidationMessage(ValidationMessageSeverity.ERROR,
+                        String.format(OakIndexDefinitionValidator.MESSAGE_INDEX_AT_NODE, rootPackagePath, "/apps/project/oak:index/indexDef")));
+
+    }
+    
+    @Test
+    public void test_index_acl() throws IOException, ConfigurationException {
+        try (InputStream input = this.getClass().getResourceAsStream("/oak-index/filter-with-acl.xml")) {
+            DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+            filter.load(input);
+            Assert.assertThat(validator.validate(filter), AnyValidationMessageMatcher.noValidationInCollection());
+        }
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("rep:policy", new DocViewProperty("rep:policy", new String[] { "/home]" }, true, PropertyType.STRING));
+        DocViewNode node = new DocViewNode("rep:policy", "rep:policy", null, props, null, "rep:ACL");
+
+        Collection<ValidationMessage> messages = validator.validate(node, "/oak:index/rep:policy",
+                Paths.get("_oak_index", "_rep_policy.xml"), true);
+        Assert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
+        node = new DocViewNode("allow", "allow", null, props, null, "rep:GrantACE");
+        messages = validator.validate(node, "/oak:index/rep:policy/allow",
+                Paths.get("_oak_index", "_rep_policy.xml"), false);
+        Assert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
+    }
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PackageTypeValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PackageTypeValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PackageTypeValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PackageTypeValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,224 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationContext;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.packaging.Dependency;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/**
+ * @see <a href="https://issues.apache.org/jira/browse/JCRVLT-170">JCRVLT-170</a>
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class PackageTypeValidatorTest {
+
+    @Mock
+    ValidationContext parentContainerContext;
+
+    @Mock
+    WorkspaceFilter filter;
+    
+    @Mock
+    PackageProperties properties;
+
+    private PackageTypeValidator validator;
+    
+    @Before
+    public void setUp() {
+    }
+
+    @Test
+    public void testNullPackageType() {
+        validator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, null, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, null);
+        Assert.assertThat(validator.validate("/apps/some/node"), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate(filter), AnyValidationMessageMatcher.noValidationInCollection());
+        ValidationExecutorTest.assertViolation(validator.validate(properties), new ValidationMessage(ValidationMessageSeverity.WARN, PackageTypeValidator.MESSAGE_NO_PACKAGE_TYPE_SET));
+        // validate sub packages of type null
+        PackageTypeValidator subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        ValidationExecutorTest.assertViolation(validator.validate(properties), new ValidationMessage(ValidationMessageSeverity.WARN, PackageTypeValidator.MESSAGE_NO_PACKAGE_TYPE_SET));
+        // validate sub packages of type Content
+        subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, null, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTENT);
+        Assert.assertThat(subPackageValidator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+        // validate sub packages of type Application
+        subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.APPLICATION, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.APPLICATION);
+        Assert.assertThat(subPackageValidator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+    }
+
+    @Test
+    public void testMixedPackageType() {
+        validator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.MIXED, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, null);
+        Assert.assertThat(validator.validate("/apps/some/node"), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate(filter), AnyValidationMessageMatcher.noValidationInCollection());
+        ValidationExecutorTest.assertViolation(validator.validate(properties), new ValidationMessage(ValidationMessageSeverity.WARN, PackageTypeValidator.MESSAGE_NO_PACKAGE_TYPE_SET));
+        // test mixed package type
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.MIXED);
+        ValidationExecutorTest.assertViolation(validator.validate(properties), new ValidationMessage(ValidationMessageSeverity.WARN, String.format(PackageTypeValidator.MESSAGE_LEGACY_TYPE, PackageType.MIXED.toString())));
+        
+        // validate sub packages of type Content
+        Mockito.when(parentContainerContext.getPackageType()).thenReturn(PackageType.MIXED);
+        PackageTypeValidator subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTENT);
+        Assert.assertThat(subPackageValidator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+        // validate sub packages of type Application
+        subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.APPLICATION, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.APPLICATION);
+        Assert.assertThat(subPackageValidator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+    }
+
+    @Test
+    public void testIsOsgiBundleOrConfiguration() {
+        validator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, null);
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/install/mybundle-123.jar"));
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/config/mmyconfig-123.cfg.json"));
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/config/mmyconfig-123.cfg"));
+        
+        Assert.assertFalse(validator.isOsgiBundleOrConfiguration("/apps/config/mmyconfig-123.json"));
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/config/mmyconfig-123.config"));
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/level2/config/mybundle-123.jar"));
+        // osgi:configNodes may have arbitrary names with extension .xml
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/level2/config/myconfig-123.xml"));
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/install.runmode1.runmode2/mybundle-123.jar")); // with run modes
+        Assert.assertTrue(validator.isOsgiBundleOrConfiguration("/apps/install.runmode1.runmode2/12/mybundle-123.jar")); // with start level
+        // below level 4
+        Assert.assertFalse(validator.isOsgiBundleOrConfiguration("/apps/level2/level3/level4/l5/install/mybundle-123.jar"));
+        
+    }
+
+    @Test
+    public void testContentPackageType() {
+        validator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, null);
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/some/node"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_APP_CONTENT, PackageType.CONTENT, "/apps/some/node")));
+        ValidationExecutorTest.assertViolation(validator.validate("/apps"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_APP_CONTENT, PackageType.CONTENT, "/apps")));
+        ValidationExecutorTest.assertViolation(validator.validate("/libs/some/node"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_APP_CONTENT, PackageType.CONTENT, "/libs/some/node")));
+        ValidationExecutorTest.assertViolation(validator.validate("/libs"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_APP_CONTENT, PackageType.CONTENT, "/libs")));
+        Assert.assertThat(validator.validate("/content/is/allowed"), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/etc/packages/some/sub/package.zip"), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/install/muybundle-123.jar"), 
+                new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_APP_CONTENT, PackageType.CONTENT, "/apps/install/muybundle-123.jar")),
+                new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_OSGI_BUNDLE_OR_CONFIG, PackageType.CONTENT, "/apps/install/muybundle-123.jar"))
+                );
+        Assert.assertThat(validator.validate(filter), AnyValidationMessageMatcher.noValidationInCollection());
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTENT);
+        Assert.assertThat(validator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+        Mockito.when(parentContainerContext.getPackageType()).thenReturn(PackageType.CONTENT);
+        // validate sub packages of type Content
+        PackageTypeValidator subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Assert.assertThat(subPackageValidator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+        // validate sub packages of type Application
+        subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.APPLICATION, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.APPLICATION);
+        ValidationExecutorTest.assertViolation(subPackageValidator.validate(properties), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_UNSUPPORTED_SUB_PACKAGE_OF_TYPE, PackageType.CONTENT, PackageType.CONTENT, PackageType.APPLICATION)));
+    }
+
+    @Test
+    public void testContainerPackageType() {
+        validator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTAINER, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, null);
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/some/node"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_NO_OSGI_BUNDLE_OR_CONFIG_OR_SUB_PACKAGE, PackageType.CONTAINER, "/apps/some/node")));
+        ValidationExecutorTest.assertViolation(validator.validate("/libs/some/node"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_NO_OSGI_BUNDLE_OR_CONFIG_OR_SUB_PACKAGE, PackageType.CONTAINER, "/libs/some/node")));
+        ValidationExecutorTest.assertViolation(validator.validate("/content/some/node"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_NO_OSGI_BUNDLE_OR_CONFIG_OR_SUB_PACKAGE, PackageType.CONTAINER, "/content/some/node")));
+        
+        Assert.assertThat(validator.validate("/apps/install.runmode/somebundle.jar"), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/etc/packages/some/sub/package.zip"), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate(filter), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTAINER);
+        Assert.assertThat(validator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+        // validate sub packages of type Content
+        Mockito.when(parentContainerContext.getPackageType()).thenReturn(PackageType.CONTAINER);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTENT);
+        PackageTypeValidator subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        ValidationExecutorTest.assertViolation(subPackageValidator.validate(properties), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_UNSUPPORTED_SUB_PACKAGE_OF_TYPE, PackageType.CONTAINER, PackageType.APPLICATION, PackageType.CONTENT)));
+        // validate sub packages of type Application
+        subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.APPLICATION);
+        Assert.assertThat(subPackageValidator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+    
+        // make sure no dependencies
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTAINER);
+        Mockito.when(properties.getDependencies()).thenReturn(new Dependency[] { Dependency.fromString("some/group:artifact:1.0.0") });
+        ValidationExecutorTest.assertViolation(validator.validate(properties), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_DEPENDENCY, PackageType.CONTAINER, "some/group:artifact:1.0.0")));
+    }
+
+    @Test
+    public void testApplicationPackageType() throws IOException, ConfigurationException {
+        validator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.APPLICATION, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, null);
+        Assert.assertThat(validator.validate("/apps/some/script"), AnyValidationMessageMatcher.noValidationInCollection());
+        Assert.assertThat(validator.validate("/libs"), AnyValidationMessageMatcher.noValidationInCollection());
+        
+        ValidationExecutorTest.assertViolation(validator.validate("/content/some/node"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_NO_APP_CONTENT_FOUND, PackageType.APPLICATION, "/content/some/node")));
+        ValidationExecutorTest.assertViolation(validator.validate("/etc/something"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_NO_APP_CONTENT_FOUND, PackageType.APPLICATION, "/etc/something")));
+        ValidationExecutorTest.assertViolation(validator.validate("/conf/something"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_NO_APP_CONTENT_FOUND, PackageType.APPLICATION, "/conf/something")));
+        
+        // no bundles/sub packages
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/install/mybundle.jar"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_OSGI_BUNDLE_OR_CONFIG, PackageType.APPLICATION, "/apps/install/mybundle.jar")));
+        ValidationExecutorTest.assertViolation(validator.validate("/apps/install/config.cfg"), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_OSGI_BUNDLE_OR_CONFIG, PackageType.APPLICATION, "/apps/install/config.cfg")));
+        
+        // no hooks
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.APPLICATION);
+        Assert.assertThat(validator.validate(properties), AnyValidationMessageMatcher.noValidationInCollection());
+        // with hooks
+        Map<String, String> hooks = Collections.singletonMap("key", "com.example.ExtenalHook");
+        Mockito.when(properties.getExternalHooks()).thenReturn(hooks);
+        ValidationExecutorTest.assertViolation(validator.validate(properties), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_PACKAGE_HOOKS, PackageType.APPLICATION, hooks)));
+        
+        // with regular filter
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/simple-filter.xml")) {
+            filter.load(input);
+        }
+        Assert.assertThat(validator.validate(filter), AnyValidationMessageMatcher.noValidationInCollection());
+        // with filters with include/exclude
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        ValidationExecutorTest.assertViolation(validator.validate(filter), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_FILTER_HAS_INCLUDE_EXCLUDES, PackageType.APPLICATION)));
+        
+        // validate sub packages of type Content
+        Mockito.when(parentContainerContext.getPackageType()).thenReturn(PackageType.APPLICATION);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.CONTENT);
+        PackageTypeValidator subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        ValidationExecutorTest.assertViolation(subPackageValidator.validate(properties), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_UNSUPPORTED_SUB_PACKAGE, PackageType.APPLICATION)));
+        // validate sub packages of type Application
+        subPackageValidator = new PackageTypeValidator(ValidationMessageSeverity.ERROR, ValidationMessageSeverity.WARN, PackageType.CONTENT, PackageTypeValidatorFactory.DEFAULT_JCR_INSTALLER_NODE_PATH_REGEX, parentContainerContext);
+        Mockito.when(properties.getPackageType()).thenReturn(PackageType.APPLICATION);
+        Mockito.when(properties.getExternalHooks()).thenReturn(Collections.emptyMap());
+        ValidationExecutorTest.assertViolation(subPackageValidator.validate(properties), new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PackageTypeValidator.MESSAGE_UNSUPPORTED_SUB_PACKAGE, PackageType.APPLICATION)));
+    }
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PrimaryNodeTypeValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PrimaryNodeTypeValidatorTest.java?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PrimaryNodeTypeValidatorTest.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/filevault/validation/spi/impl/PrimaryNodeTypeValidatorTest.java Wed Oct  2 11:28:25 2019
@@ -0,0 +1,70 @@
+/*
+ * 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.jackrabbit.filevault.validation.spi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.filevault.validation.AnyValidationMessageMatcher;
+import org.apache.jackrabbit.filevault.validation.ValidationExecutorTest;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessage;
+import org.apache.jackrabbit.filevault.validation.spi.ValidationMessageSeverity;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.util.DocViewNode;
+import org.apache.jackrabbit.vault.util.DocViewProperty;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class PrimaryNodeTypeValidatorTest {
+
+    private PrimaryNodeTypeValidator validator;
+
+    @Test
+    public void testNodeTypes() throws IOException, ConfigurationException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        try (InputStream input = this.getClass().getResourceAsStream("/filter.xml")) {
+            filter.load(input);
+        }
+        validator = new PrimaryNodeTypeValidator(ValidationMessageSeverity.ERROR, filter);
+        Map<String, DocViewProperty> props = new HashMap<>();
+        props.put("prop1", new DocViewProperty("prop1", new String[] { "value1" } , false, PropertyType.STRING));
+
+        // order node only (no other property)
+        DocViewNode node = new DocViewNode("jcr:root", "jcr:root", null, Collections.emptyMap(), null, null);
+        Assert.assertThat(validator.validate(node, "/apps/test", null, false), AnyValidationMessageMatcher.noValidationInCollection());
+
+        // primary node type set with additional properties
+        node = new DocViewNode("jcr:root", "jcr:root", null, props, null, "nt:unstructured");
+        Assert.assertThat(validator.validate(node, "/apps/test", null, false), AnyValidationMessageMatcher.noValidationInCollection());
+
+        // missing node type but not contained in filter (with properties)
+        node = new DocViewNode("jcr:root", "jcr:root", null, props, null, null);
+        Assert.assertThat(validator.validate(node, "/apps/test2/invalid", null, false), AnyValidationMessageMatcher.noValidationInCollection());
+
+        // missing node type and contained in filter (with properties)
+        ValidationExecutorTest.assertViolation(
+                        validator.validate(node, "/apps/test", null, false),
+                        new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(PrimaryNodeTypeValidator.MESSAGE_MISSING_PRIMARY_TYPE, "/apps/test")));
+    }
+}

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dependency1-filter.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dependency1-filter.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dependency1-filter.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dependency1-filter.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/covered"/>
+    <filter root="/apps/covered2">
+        <exclude pattern="/apps/covered2/excluded"></exclude>
+    </filter>
+</workspaceFilter>
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dummy.txt
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dummy.txt?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dummy.txt (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/dummy.txt Wed Oct  2 11:28:25 2019
@@ -0,0 +1 @@
+some dummy text
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-merge.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-merge.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-merge.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-merge.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test/deep" mode="merge"/>
+    <filter root="/apps/test2">
+    </filter>
+</workspaceFilter>

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-uncovered-roots.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-uncovered-roots.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-uncovered-roots.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter-with-uncovered-roots.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/covered/test"/>
+    <filter root="/customroot/test" />
+    <filter root="/apps/uncovered/test"/>
+    <filter root="/apps/covered2/excluded/test"/>
+    <filter root="/invalidroot/test"/>
+</workspaceFilter>
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/filter.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test"/>
+    <filter root="/apps/test2">
+        <include pattern=".*/valid" />
+        <include pattern=".*/anothervalid" />
+    </filter>
+    <filter root="/apps/test3" type="cleanup">
+        <exclude pattern=".*/invalid" />
+    </filter>
+    <filter root="/apps/test4/test">
+        <exclude pattern=".*/invalid" />
+    </filter>
+</workspaceFilter>

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter-non-matching-regex.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter-non-matching-regex.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter-non-matching-regex.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter-non-matching-regex.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/etc/project1">
+        <exclude pattern="/some/other" />
+    </filter>
+    <filter root="invalidroot">
+    </filter>
+</workspaceFilter>
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/filter.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/etc/project1">
+        <exclude pattern=".*\.gif" mode="merge" />
+        <include pattern="["/> <!-- invalid regex -->
+        <invalidelement />
+    </filter>
+</workspaceFilter>
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/properties.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/properties.xml?rev=1867884&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/properties.xml (added)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/invalid-package/META-INF/vault/properties.xml Wed Oct  2 11:28:25 2019
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--
+  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.
+  -->
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+<comment>FileVault Package Properties</comment>
+<entry key="createdBy">admin</entry>
+<entry key="name">mode_ac_test_a</entry>
+<entry key="lastModified">2011-11-15T09:43:22.972+01:00</entry>
+<entry key="lastModifiedBy">admin</entry>
+<entry key="created">2011-11-15T09:43:22.993+01:00</entry>
+<entry key="buildCount">1</entry>
+<entry key="version"/>
+<entry key="dependencies"/>
+<entry key="packageFormatVersion">2</entry>
+<entry key="description"/>
+<entry key="lastWrapped">2011-11-15T09:43:22.972+01:00</entry>
+<entry key="group"/>
+<entry key="lastWrappedBy">admin</entry>
+<entry key="acHandling">overwrite</entry>
+<someinvalidentry></someinvalidentry>
+</properties>



Mime
View raw message