aboutsummaryrefslogtreecommitdiffstats
path: root/jdisc_core/src/test/java/com/yahoo/jdisc/core/ExportPackagesIT.java
blob: e9aba0893f9675c713226740ae7733b7872c5a90 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.yahoo.jdisc.core;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;

/**
 * Integration tests for {@link ExportPackages}.
 *
 * @author gjoranv
 */
public class ExportPackagesIT {


    private static final File expectedExportPackages = new File("src/test/resources" + ExportPackages.PROPERTIES_FILE);

    private static final String JAR_PATH = "target/dependency/";

    // This list must be kept in sync with the list in the export-packages execution in pom.xml.
    private static final List<String> RE_EXPORTED_BUNDLES = Stream.of(
            "guava.jar",
            "guice-no_aop.jar",
            "slf4j-api.jar",
            "slf4j-jdk14.jar",
            "jcl-over-slf4j.jar",
            "log4j-over-slf4j.jar",
            "annotations.jar",
            "config-lib.jar",
            "defaults.jar",
            "vespajlib.jar",
            "vespalog.jar",
            "jaxb-api.jar",
            "jaxb-core.jar",
            "jaxb-impl.jar",
            "javax.activation.jar"
    ).map(f -> JAR_PATH + f).toList();

    @TempDir
    public static File tempFolder;

    @Test
    void exported_packages_are_not_changed_unintentionally() throws Exception {
        Properties actualProperties = getPropertiesFromFile(createPropertiesFile());
        String actualValue = actualProperties.getProperty(ExportPackages.EXPORT_PACKAGES);
        assertNotNull(actualValue, "Missing exportPackages property in file.");

        Properties expectedProperties = getPropertiesFromFile(expectedExportPackages);
        String expectedValue = expectedProperties.getProperty(ExportPackages.EXPORT_PACKAGES);
        assertNotNull(expectedValue, "Missing exportPackages property in file.");

        Set<String> actualPackages = getPackages(actualValue);
        Set<String> expectedPackages = getPackages(expectedValue);
        if (!actualPackages.equals(expectedPackages)) {
            StringBuilder message = getDiff(actualPackages, expectedPackages);
            message.append("\n\nIf this test fails due to an intentional change in exported packages, run the following command:\n")
                    .append("$ cp jdisc_core/target/classes/exportPackages.properties jdisc_core/src/test/resources/")
                    .append("\n\nNote that removing exported packages usually requires a new major version of Vespa.\n");
            fail(message.toString());
        }
    }

    private static StringBuilder getDiff(Set<String> actual, Set<String> expected) {
        StringBuilder sb = new StringBuilder();
        Set<String> onlyInActual = onlyInSet1(actual, expected);
        if (! onlyInActual.isEmpty()) {
            sb.append("\nexportPackages.properties contained ")
                    .append(onlyInActual.size())
                    .append(" unexpected packages:\n")
                    .append(onlyInActual.stream().collect(Collectors.joining(",\n  ", " [", "]")));
        }

        Set<String> onlyInExpected = onlyInSet1(expected, actual);
        if (! onlyInExpected.isEmpty()) {
            sb.append("\nexportPackages.properties did not contain ")
                    .append(onlyInExpected.size())
                    .append(" expected packages:\n")
                    .append(onlyInExpected.stream().collect(Collectors.joining(",\n  ", " [", "]")));
        }
        return sb;
    }

    // Returns a sorted set for readability.
    private static Set<String> onlyInSet1(Set<String> set1, Set<String> set2) {
        return set1.stream()
                .filter(s -> ! set2.contains(s))
                .collect(Collectors.toCollection(TreeSet::new));
    }

    private static Set<String> getPackages(String propertyValue) {
        return Arrays.stream(propertyValue.split(","))
                .map(String::trim)
                .filter(s -> ! s.isEmpty())
                .collect(Collectors.toSet());
    }

    private static Properties getPropertiesFromFile(File file) throws IOException {
        Properties properties = new Properties();
        try (FileReader reader = new FileReader(file)) {
            properties.load(reader);
        }
        return properties;
    }

    private static File createPropertiesFile() throws IOException {
        File file = Paths.get(tempFolder.toString(), ExportPackages.PROPERTIES_FILE).toFile();
        String[] args = Stream.concat(Stream.of(file.getAbsolutePath()),
                                      RE_EXPORTED_BUNDLES.stream()).toArray(String[]::new);
        ExportPackages.main(args);
        return file;
    }

}