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) 2012, 2021, Oracle and/or its affiliates. All rights reserved. 22 * Portions Copyright (c) 2018, 2020, Chris Fraire <cfraire@me.com>. 23 */ 24 package org.opengrok.indexer.web; 25 26 import java.util.Collections; 27 import java.util.SortedSet; 28 import java.util.TreeSet; 29 30 import org.junit.jupiter.api.AfterEach; 31 import org.junit.jupiter.api.BeforeEach; 32 import org.junit.jupiter.api.Test; 33 import org.opengrok.indexer.configuration.Project; 34 import org.opengrok.indexer.configuration.RuntimeEnvironment; 35 import org.opengrok.indexer.index.Indexer; 36 import org.opengrok.indexer.index.IndexerTest; 37 import org.opengrok.indexer.search.QueryBuilder; 38 import org.opengrok.indexer.util.TestRepository; 39 40 import static org.junit.jupiter.api.Assertions.assertEquals; 41 import static org.junit.jupiter.api.Assertions.assertFalse; 42 import static org.junit.jupiter.api.Assertions.assertNotNull; 43 import static org.junit.jupiter.api.Assertions.assertNotSame; 44 import static org.junit.jupiter.api.Assertions.assertNull; 45 import static org.junit.jupiter.api.Assertions.assertTrue; 46 47 /** 48 * Unit tests for the {@code SearchHelper} class. 49 */ 50 class SearchHelperTest { 51 52 TestRepository repository; 53 RuntimeEnvironment env; 54 55 @BeforeEach setUp()56 public void setUp() throws Exception { 57 repository = new TestRepository(); 58 repository.create(IndexerTest.class.getClassLoader().getResource("sources")); 59 60 env = RuntimeEnvironment.getInstance(); 61 env.setSourceRoot(repository.getSourceRoot()); 62 env.setDataRoot(repository.getDataRoot()); 63 env.setHistoryEnabled(false); 64 } 65 66 @AfterEach tearDown()67 public void tearDown() { 68 repository.destroy(); 69 } 70 reindex()71 private void reindex() throws Exception { 72 System.out.println("Generating index by using the class methods"); 73 74 Indexer.getInstance().prepareIndexer(env, true, true, 75 false, null, null); 76 env.setDefaultProjectsFromNames(new TreeSet<>(Collections.singletonList("/c"))); 77 Indexer.getInstance().doIndexerExecution(true, null, null); 78 } 79 getSearchHelper(String searchTerm)80 private SearchHelper getSearchHelper(String searchTerm) { 81 SearchHelper sh = new SearchHelper(0, SortOrder.RELEVANCY, 82 env.getDataRootFile(), env.getSourceRootFile(), 83 env.getHitsPerPage(), null, 84 new QueryBuilder().setFreetext(searchTerm), false, 85 env.getUrlPrefix(), false, false); 86 87 assertNotSame(0, sh.getBuilder().getSize()); 88 return sh; 89 } 90 getSearchHelperPath(String searchTerm)91 private SearchHelper getSearchHelperPath(String searchTerm) { 92 SearchHelper sh = new SearchHelper(0, SortOrder.RELEVANCY, 93 env.getDataRootFile(), env.getSourceRootFile(), 94 env.getHitsPerPage(), null, 95 new QueryBuilder().setPath(searchTerm), false, 96 env.getUrlPrefix(), false, false); 97 98 assertNotSame(0, sh.getBuilder().getSize()); 99 return sh; 100 } 101 102 @Test testSearchAfterReindex()103 void testSearchAfterReindex() throws Exception { 104 SortedSet<String> projectNames = new TreeSet<>(); 105 106 env.setProjectsEnabled(true); 107 108 reindex(); 109 110 // Search for existing term in single project. 111 projectNames.add("c"); 112 SearchHelper searchHelper = this.getSearchHelper("foobar") 113 .prepareExec(projectNames).executeQuery().prepareSummary(); 114 assertNull(searchHelper.getErrorMsg()); 115 System.out.println("single project search returned " + searchHelper.getTotalHits() + " hits"); 116 assertEquals(4, searchHelper.getTotalHits()); 117 searchHelper.destroy(); 118 119 // Search for existing term in multiple projects. 120 projectNames.add("document"); 121 searchHelper = this.getSearchHelper("foobar") 122 .prepareExec(projectNames).executeQuery().prepareSummary(); 123 assertNull(searchHelper.getErrorMsg()); 124 System.out.println("multi-project search returned " + searchHelper.getTotalHits() + " hits"); 125 assertEquals(5, searchHelper.getTotalHits()); 126 searchHelper.destroy(); 127 128 // Search for non-existing term. 129 searchHelper = this.getSearchHelper("CannotExistAnywhereForSure") 130 .prepareExec(projectNames).executeQuery().prepareSummary(); 131 assertNull(searchHelper.getErrorMsg()); 132 long totalHits = searchHelper.getTotalHits(); 133 System.out.println("multi-project search for non-existing term returned " + totalHits + " hits"); 134 assertEquals(0, totalHits); 135 searchHelper.destroy(); 136 137 // Add a change to the repository, reindex, try to reopen the indexes 138 // and repeat the search. 139 repository.addDummyFile("c", "foobar"); 140 141 reindex(); 142 143 env.maybeRefreshIndexSearchers(); 144 searchHelper = this.getSearchHelper("foobar") 145 .prepareExec(projectNames).executeQuery().prepareSummary(); 146 assertNull(searchHelper.getErrorMsg()); 147 totalHits = searchHelper.getTotalHits(); 148 System.out.println("multi-project search after reindex returned " + totalHits + " hits"); 149 assertEquals(6, totalHits); 150 searchHelper.destroy(); 151 repository.removeDummyFile("c"); 152 153 // Search for case insensitive path. 154 projectNames.add("java"); 155 searchHelper = this.getSearchHelperPath("JaVa") 156 .prepareExec(projectNames).executeQuery().prepareSummary(); 157 assertNull(searchHelper.getErrorMsg()); 158 totalHits = searchHelper.getTotalHits(); 159 System.out.println("multi-project search for non-existing term returned " + totalHits + " hits"); 160 assertEquals(5, totalHits); 161 searchHelper.destroy(); 162 } 163 164 @Test testPrepareExecInvalidInput()165 void testPrepareExecInvalidInput() { 166 SortedSet<String> projectNames = new TreeSet<>(); 167 SearchHelper searchHelper; 168 169 env.setProjectsEnabled(true); 170 171 // Fake project addition to avoid reindex. 172 Project project = new Project("c", "/c"); 173 env.getProjects().put("c", project); 174 project = new Project("java", "/java"); 175 project.setIndexed(true); 176 env.getProjects().put("java", project); 177 178 // Try to prepare search for project that is not yet indexed. 179 projectNames.add("c"); 180 projectNames.add("java"); 181 searchHelper = this.getSearchHelper("foobar") 182 .prepareExec(projectNames); 183 assertNotNull(searchHelper.getErrorMsg()); 184 assertTrue(searchHelper.getErrorMsg().contains("not indexed")); 185 assertFalse(searchHelper.getErrorMsg().contains("java")); 186 187 // Try to prepare search for list that contains non-existing project. 188 projectNames.add("totally_nonexistent_project"); 189 searchHelper = this.getSearchHelper("foobar") 190 .prepareExec(projectNames); 191 assertNotNull(searchHelper.getErrorMsg()); 192 assertTrue(searchHelper.getErrorMsg().contains("invalid projects")); 193 } 194 } 195