1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2018, 2020, Chris Fraire <cfraire@me.com>.
22  */
23 package org.opengrok.indexer.index;
24 
25 import java.io.IOException;
26 import java.io.InvalidClassException;
27 import java.util.HashMap;
28 import java.util.Map;
29 
30 import org.junit.jupiter.api.Test;
31 import org.opengrok.indexer.analysis.AnalyzerGuru;
32 
33 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
34 import static org.junit.jupiter.api.Assertions.assertEquals;
35 import static org.junit.jupiter.api.Assertions.assertNotNull;
36 import static org.junit.jupiter.api.Assertions.assertThrows;
37 import static org.junit.jupiter.api.Assertions.assertTrue;
38 
39 /**
40  * Represents a test container for {@link IndexAnalysisSettingsUpgrader}.
41  */
42 public class IndexAnalysisSettingsUpgraderTest {
43 
44     private static final String PROJECT_NAME = "foo-1-2-3";
45     private static final long ANALYZER_GURU_VERSION = 3;
46     private static final int TABSIZE = 17;
47     private static final Map<String, IndexedSymlink> TEST_MAPPED_SYMLINKS;
48 
49     static {
50         TEST_MAPPED_SYMLINKS = new HashMap<>();
51         IndexedSymlink entry = new IndexedSymlink("/foo", "/private/foo", false);
entry.getCanonical()52         TEST_MAPPED_SYMLINKS.put(entry.getCanonical(), entry);
53         entry = new IndexedSymlink("/foo/bar", "/private/foo/bar", true);
entry.getCanonical()54         TEST_MAPPED_SYMLINKS.put(entry.getCanonical(), entry);
55     }
56 
57     @Test
shouldHandleLatest()58     public void shouldHandleLatest() throws IOException,
59             ClassNotFoundException {
60         IndexAnalysisSettings3 obj = new IndexAnalysisSettings3();
61         obj.setAnalyzerGuruVersion(ANALYZER_GURU_VERSION);
62         Map<String, Long> actAnalyzersVersionNos = AnalyzerGuru.getAnalyzersVersionNos();
63         obj.setAnalyzersVersions(actAnalyzersVersionNos);
64         obj.setProjectName(PROJECT_NAME);
65         obj.setTabSize(TABSIZE);
66         obj.setIndexedSymlinks(TEST_MAPPED_SYMLINKS);
67         byte[] bin = obj.serialize();
68 
69         IndexAnalysisSettingsUpgrader upgrader = new IndexAnalysisSettingsUpgrader();
70         IndexAnalysisSettings3 vLatest = upgrader.upgrade(bin, 3);
71         assertNotNull(vLatest, "should get non-null from upgrader");
72         assertEquals(PROJECT_NAME, vLatest.getProjectName(), "should have same projectName");
73         assertEquals(TABSIZE, (int) vLatest.getTabSize(), "should have same tabSize");
74         assertEquals(ANALYZER_GURU_VERSION, (long) vLatest.getAnalyzerGuruVersion(),
75                 "should have same analyzerGuruVersion");
76         assertEquals(vLatest.getAnalyzersVersions().size(), actAnalyzersVersionNos.size(),
77                 "should have expected analyzer versions");
78 
79         Object[] expectedVersionKeys = actAnalyzersVersionNos.keySet().stream().sorted().toArray();
80         assertArrayEquals(expectedVersionKeys,
81                 vLatest.getAnalyzersVersions().keySet().stream().sorted().toArray(),
82                 "analyzer versions keysets should be equal");
83         assertArrayEquals(getMapValues(actAnalyzersVersionNos, expectedVersionKeys),
84                 getMapValues(vLatest.getAnalyzersVersions(), expectedVersionKeys),
85                 "analyzer versions values should be equal");
86 
87         Object[] expectedSymlinkKeys = TEST_MAPPED_SYMLINKS.keySet().stream().sorted().toArray();
88         assertArrayEquals(expectedSymlinkKeys,
89                 vLatest.getIndexedSymlinks().keySet().stream().sorted().toArray(),
90                 "index symlinks keysets should be equal");
91         assertArrayEquals(getMapValues(TEST_MAPPED_SYMLINKS, expectedSymlinkKeys),
92                 getMapValues(vLatest.getIndexedSymlinks(), expectedSymlinkKeys),
93                 "index symlinks values should be equal");
94     }
95 
96     @Test
shouldUpgradeV2()97     public void shouldUpgradeV2() throws IOException, ClassNotFoundException {
98         IndexAnalysisSettings obj = new IndexAnalysisSettings();
99         obj.setAnalyzerGuruVersion(ANALYZER_GURU_VERSION);
100         Map<String, Long> actAnalyzersVersionNos = AnalyzerGuru.getAnalyzersVersionNos();
101         obj.setAnalyzersVersions(actAnalyzersVersionNos);
102         obj.setProjectName(PROJECT_NAME);
103         obj.setTabSize(TABSIZE);
104         obj.setAnalyzersVersions(actAnalyzersVersionNos);
105         byte[] bin = obj.serialize();
106 
107         IndexAnalysisSettingsUpgrader upgrader = new IndexAnalysisSettingsUpgrader();
108         IndexAnalysisSettings3 v3 = upgrader.upgrade(bin, 2);
109         assertNotNull(v3, "should get non-null from upgrader");
110         assertEquals(PROJECT_NAME, v3.getProjectName(), "should have same projectName");
111         assertEquals(TABSIZE, (int) v3.getTabSize(), "should have same tabSize");
112         assertEquals(ANALYZER_GURU_VERSION, (long) v3.getAnalyzerGuruVersion(), "should have same analyzerGuruVersion");
113         assertEquals(v3.getAnalyzersVersions().size(), actAnalyzersVersionNos.size(),
114                 "should have expected analyzer versions");
115         assertTrue(v3.getIndexedSymlinks().isEmpty(), "should have no indexedSymlinks");
116     }
117 
118     @Test
shouldThrowIfVersionIsMisrepresented()119     public void shouldThrowIfVersionIsMisrepresented() throws IOException, ClassNotFoundException {
120         IndexAnalysisSettings obj = new IndexAnalysisSettings();
121         obj.setAnalyzerGuruVersion(ANALYZER_GURU_VERSION);
122         obj.setProjectName(PROJECT_NAME);
123         obj.setTabSize(TABSIZE);
124         byte[] bin = obj.serialize();
125 
126         IndexAnalysisSettingsUpgrader upgrader = new IndexAnalysisSettingsUpgrader();
127         assertThrows(InvalidClassException.class, () -> upgrader.upgrade(bin, 3),
128                 "should not have produced an instance");
129     }
130 
131     @Test
shouldThrowIfTooOldVersion()132     public void shouldThrowIfTooOldVersion() throws ClassNotFoundException {
133         boolean passed = false;
134 
135         IndexAnalysisSettingsUpgrader upgrader = new IndexAnalysisSettingsUpgrader();
136         try {
137             upgrader.upgrade(new byte[0], 1);
138         } catch (IOException e) {
139             // expected
140             assertTrue(e.getMessage().startsWith("Too old version"));
141             passed = true;
142         }
143         assertTrue(passed, "should have thrown on too-old version");
144     }
145 
getMapValues(Map<K, V> map, Object[] keys)146     private static <K, V> Object[] getMapValues(Map<K, V> map, Object[] keys) {
147         Object[] values = new Object[keys.length];
148         for (int i = 0; i < keys.length; ++i) {
149             //noinspection SuspiciousMethodCalls
150             values[i] = map.get(keys[i]);
151         }
152         return values;
153     }
154 }
155