1b5840353SAdam Hornáček /* 2b5840353SAdam Hornáček * CDDL HEADER START 3b5840353SAdam Hornáček * 4b5840353SAdam Hornáček * The contents of this file are subject to the terms of the 5b5840353SAdam Hornáček * Common Development and Distribution License (the "License"). 6b5840353SAdam Hornáček * You may not use this file except in compliance with the License. 7b5840353SAdam Hornáček * 8b5840353SAdam Hornáček * See LICENSE.txt included in this distribution for the specific 9b5840353SAdam Hornáček * language governing permissions and limitations under the License. 10b5840353SAdam Hornáček * 11b5840353SAdam Hornáček * When distributing Covered Code, include this CDDL HEADER in each 12b5840353SAdam Hornáček * file and include the License file at LICENSE.txt. 13b5840353SAdam Hornáček * If applicable, add the following below this CDDL HEADER, with the 14b5840353SAdam Hornáček * fields enclosed by brackets "[]" replaced with your own identifying 15b5840353SAdam Hornáček * information: Portions Copyright [yyyy] [name of copyright owner] 16b5840353SAdam Hornáček * 17b5840353SAdam Hornáček * CDDL HEADER END 18b5840353SAdam Hornáček */ 19b5840353SAdam Hornáček 20b5840353SAdam Hornáček /* 21c6f0939bSAdam Hornacek * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. 225d9f3aa0SAdam Hornáček * Portions Copyright (c) 2018, 2019, Chris Fraire <cfraire@me.com>. 23b5840353SAdam Hornáček */ 249805b761SAdam Hornáček package org.opengrok.indexer.search; 25b5840353SAdam Hornáček 26b5840353SAdam Hornáček import java.io.File; 27b5840353SAdam Hornáček import java.util.Collections; 28b5840353SAdam Hornáček import java.util.TreeSet; 2952d10766SAdam Hornacek 3052d10766SAdam Hornacek import org.junit.jupiter.api.AfterAll; 3152d10766SAdam Hornacek import org.junit.jupiter.api.BeforeAll; 3252d10766SAdam Hornacek import org.junit.jupiter.api.Test; 339805b761SAdam Hornáček import org.opengrok.indexer.configuration.RuntimeEnvironment; 349805b761SAdam Hornáček import org.opengrok.indexer.history.HistoryGuru; 359805b761SAdam Hornáček import org.opengrok.indexer.index.Indexer; 369805b761SAdam Hornáček import org.opengrok.indexer.util.TestRepository; 37b5840353SAdam Hornáček 389805b761SAdam Hornáček import org.opengrok.indexer.history.RepositoryFactory; 39b5840353SAdam Hornáček 4052d10766SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertEquals; 4152d10766SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertFalse; 4252d10766SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertNull; 4352d10766SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertTrue; 441161d3e8SAdam Hornacek 45b5840353SAdam Hornáček /** 461161d3e8SAdam Hornacek * Do basic testing of the SearchEngine. 47b5840353SAdam Hornáček * 48b5840353SAdam Hornáček * @author Trond Norbye 49b5840353SAdam Hornáček */ 50b5840353SAdam Hornáček public class SearchEngineTest { 51b5840353SAdam Hornáček 52b5840353SAdam Hornáček static TestRepository repository; 53b5840353SAdam Hornáček static File configFile; 54b5840353SAdam Hornáček 5552d10766SAdam Hornacek @BeforeAll setUpClass()56b5840353SAdam Hornáček public static void setUpClass() throws Exception { 57b5840353SAdam Hornáček repository = new TestRepository(); 58*9a303f19SAdam Hornacek repository.create(HistoryGuru.class.getResource("/repositories")); 59b5840353SAdam Hornáček 60b5840353SAdam Hornáček RuntimeEnvironment env = RuntimeEnvironment.getInstance(); 61b5840353SAdam Hornáček env.setSourceRoot(repository.getSourceRoot()); 62b5840353SAdam Hornáček env.setDataRoot(repository.getDataRoot()); 63b5840353SAdam Hornáček RepositoryFactory.initializeIgnoredNames(env); 64b5840353SAdam Hornáček 65b5840353SAdam Hornáček env.setSourceRoot(repository.getSourceRoot()); 66b5840353SAdam Hornáček env.setDataRoot(repository.getDataRoot()); 67b5840353SAdam Hornáček env.setHistoryEnabled(false); 68b5840353SAdam Hornáček 69369f83fbSVladimir Kotal Indexer.getInstance().prepareIndexer(env, true, true, 70369f83fbSVladimir Kotal false, null, null); 71369f83fbSVladimir Kotal env.setDefaultProjectsFromNames(new TreeSet<>(Collections.singletonList("/c"))); 72369f83fbSVladimir Kotal Indexer.getInstance().doIndexerExecution(true, null, null); 73b5840353SAdam Hornáček 74b5840353SAdam Hornáček configFile = File.createTempFile("configuration", ".xml"); 75b5840353SAdam Hornáček env.writeConfiguration(configFile); 76b5840353SAdam Hornáček RuntimeEnvironment.getInstance().readConfiguration(new File(configFile.getAbsolutePath())); 77b5840353SAdam Hornáček } 78b5840353SAdam Hornáček 7952d10766SAdam Hornacek @AfterAll tearDownClass()80b5840353SAdam Hornáček public static void tearDownClass() throws Exception { 81b5840353SAdam Hornáček repository.destroy(); 82b5840353SAdam Hornáček configFile.delete(); 83b5840353SAdam Hornáček } 84b5840353SAdam Hornáček 85b5840353SAdam Hornáček @Test testIsValidQuery()86b5840353SAdam Hornáček public void testIsValidQuery() { 87b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 88b5840353SAdam Hornáček assertFalse(instance.isValidQuery()); 89b5840353SAdam Hornáček instance.setFile("foo"); 90b5840353SAdam Hornáček assertTrue(instance.isValidQuery()); 91b5840353SAdam Hornáček } 92b5840353SAdam Hornáček 93b5840353SAdam Hornáček @Test testDefinition()94b5840353SAdam Hornáček public void testDefinition() { 95b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 96b5840353SAdam Hornáček assertNull(instance.getDefinition()); 97b5840353SAdam Hornáček String defs = "This is a definition"; 98b5840353SAdam Hornáček instance.setDefinition(defs); 99b5840353SAdam Hornáček assertEquals(defs, instance.getDefinition()); 100b5840353SAdam Hornáček } 101b5840353SAdam Hornáček 102b5840353SAdam Hornáček @Test testFile()103b5840353SAdam Hornáček public void testFile() { 104b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 105b5840353SAdam Hornáček assertNull(instance.getFile()); 106b5840353SAdam Hornáček String file = "This is a File"; 107b5840353SAdam Hornáček instance.setFile(file); 108b5840353SAdam Hornáček assertEquals(file, instance.getFile()); 109b5840353SAdam Hornáček } 110b5840353SAdam Hornáček 111b5840353SAdam Hornáček @Test testFreetext()112b5840353SAdam Hornáček public void testFreetext() { 113b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 114b5840353SAdam Hornáček assertNull(instance.getFreetext()); 115b5840353SAdam Hornáček String freetext = "This is just a piece of text"; 116b5840353SAdam Hornáček instance.setFreetext(freetext); 117b5840353SAdam Hornáček assertEquals(freetext, instance.getFreetext()); 118b5840353SAdam Hornáček } 119b5840353SAdam Hornáček 120b5840353SAdam Hornáček @Test testHistory()121b5840353SAdam Hornáček public void testHistory() { 122b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 123b5840353SAdam Hornáček assertNull(instance.getHistory()); 124b5840353SAdam Hornáček String hist = "This is a piece of history"; 125b5840353SAdam Hornáček instance.setHistory(hist); 126b5840353SAdam Hornáček assertEquals(hist, instance.getHistory()); 127b5840353SAdam Hornáček } 128b5840353SAdam Hornáček 129b5840353SAdam Hornáček @Test testSymbol()130b5840353SAdam Hornáček public void testSymbol() { 131b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 132b5840353SAdam Hornáček assertNull(instance.getSymbol()); 133b5840353SAdam Hornáček String sym = "This is a symbol"; 134b5840353SAdam Hornáček instance.setSymbol(sym); 135b5840353SAdam Hornáček assertEquals(sym, instance.getSymbol()); 136b5840353SAdam Hornáček } 137b5840353SAdam Hornáček 138b5840353SAdam Hornáček @Test testGetQuery()139b5840353SAdam Hornáček public void testGetQuery() throws Exception { 140b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 141b5840353SAdam Hornáček instance.setHistory("Once upon a time"); 142b5840353SAdam Hornáček instance.setFile("Makefile"); 143b5840353SAdam Hornáček instance.setDefinition("\"std::string\""); 144b5840353SAdam Hornáček instance.setSymbol("toString"); 145b5840353SAdam Hornáček instance.setFreetext("OpenGrok"); 146b5840353SAdam Hornáček assertTrue(instance.isValidQuery()); 147b5840353SAdam Hornáček assertEquals("+defs:\"std string\" +full:opengrok +hist:once +hist:upon +hist:time +path:makefile +refs:toString", 148b5840353SAdam Hornáček instance.getQuery()); 149b5840353SAdam Hornáček } 150b5840353SAdam Hornáček 1516d5300acSAdam Hornáček /* see https://github.com/oracle/opengrok/issues/2030 152b5840353SAdam Hornáček @Test 153b5840353SAdam Hornáček public void testSearch() { 154b5840353SAdam Hornáček List<Hit> hits = new ArrayList<>(); 155b5840353SAdam Hornáček 156b5840353SAdam Hornáček SearchEngine instance = new SearchEngine(); 157b5840353SAdam Hornáček instance.setHistory("\"Add lint make target and fix lint warnings\""); 158b5840353SAdam Hornáček int noHits = instance.search(); 159b5840353SAdam Hornáček if (noHits > 0) { 160b5840353SAdam Hornáček instance.results(0, noHits, hits); 161b5840353SAdam Hornáček assertEquals(noHits, hits.size()); 162b5840353SAdam Hornáček } 163b5840353SAdam Hornáček instance.destroy(); 164b5840353SAdam Hornáček 165b5840353SAdam Hornáček instance = new SearchEngine(); 166b5840353SAdam Hornáček instance.setSymbol("printf"); 167b5840353SAdam Hornáček instance.setFile("main.c"); 168b5840353SAdam Hornáček noHits = instance.search(); 169b5840353SAdam Hornáček assertEquals(8, noHits); 170b5840353SAdam Hornáček hits.clear(); 171b5840353SAdam Hornáček instance.results(0, noHits, hits); 172b5840353SAdam Hornáček for (Hit hit : hits) { 173b5840353SAdam Hornáček assertEquals("main.c", hit.getFilename()); 174b5840353SAdam Hornáček assertEquals(1, 1); 175b5840353SAdam Hornáček } 176b5840353SAdam Hornáček instance.setFile("main.c OR Makefile"); 177b5840353SAdam Hornáček noHits = instance.search(); 178b5840353SAdam Hornáček assertEquals(8, noHits); 179b5840353SAdam Hornáček instance.destroy(); 180b5840353SAdam Hornáček 181b5840353SAdam Hornáček instance = new SearchEngine(); 182b5840353SAdam Hornáček instance.setFreetext("arguments"); 183b5840353SAdam Hornáček instance.setFile("main.c"); 184b5840353SAdam Hornáček noHits = instance.search(); 185b5840353SAdam Hornáček hits.clear(); 186b5840353SAdam Hornáček instance.results(0, noHits, hits); 187b5840353SAdam Hornáček for (Hit hit : hits) { 188b5840353SAdam Hornáček assertEquals("main.c", hit.getFilename()); 189b5840353SAdam Hornáček if (!hit.getLine().contains("arguments")) { 190b5840353SAdam Hornáček fail("got an incorrect match: " + hit.getLine()); 191b5840353SAdam Hornáček } 192b5840353SAdam Hornáček } 193b5840353SAdam Hornáček assertEquals(8, noHits); 194b5840353SAdam Hornáček instance.destroy(); 195b5840353SAdam Hornáček 196b5840353SAdam Hornáček instance = new SearchEngine(); 197b5840353SAdam Hornáček instance.setDefinition("main"); 198b5840353SAdam Hornáček instance.setFile("main.c"); 199b5840353SAdam Hornáček noHits = instance.search(); 200b5840353SAdam Hornáček hits.clear(); 201b5840353SAdam Hornáček instance.results(0, noHits, hits); 202b5840353SAdam Hornáček for (Hit hit : hits) { 203b5840353SAdam Hornáček assertEquals("main.c", hit.getFilename()); 204b5840353SAdam Hornáček if (!hit.getLine().contains("main")) { 205b5840353SAdam Hornáček fail("got an incorrect match: " + hit.getLine()); 206b5840353SAdam Hornáček } 207b5840353SAdam Hornáček } 208b5840353SAdam Hornáček assertEquals(8, noHits); 209b5840353SAdam Hornáček instance.destroy(); 210b5840353SAdam Hornáček 211b5840353SAdam Hornáček // negative symbol test (comments should be ignored) 212b5840353SAdam Hornáček instance = new SearchEngine(); 213b5840353SAdam Hornáček instance.setSymbol("Ordinary"); 214b5840353SAdam Hornáček instance.setFile("\"Main.java\""); 215b5840353SAdam Hornáček instance.search(); 216b5840353SAdam Hornáček assertEquals("+path:\"main . java\" +refs:Ordinary", 217b5840353SAdam Hornáček instance.getQuery()); 218b5840353SAdam Hornáček assertEquals(0, instance.search()); 219b5840353SAdam Hornáček instance.destroy(); 220b5840353SAdam Hornáček 221b5840353SAdam Hornáček // wildcards and case sensitivity of definition search 222b5840353SAdam Hornáček instance = new SearchEngine(); 223b5840353SAdam Hornáček instance.setDefinition("Mai*"); // definition is case sensitive 224b5840353SAdam Hornáček instance.setFile("\"Main.java\" OR \"main.c\""); 225b5840353SAdam Hornáček instance.search(); 226b5840353SAdam Hornáček assertEquals("+defs:Mai* +(path:\"main . java\" path:\"main . c\")", 227b5840353SAdam Hornáček instance.getQuery()); 228b5840353SAdam Hornáček assertEquals(2, instance.search()); 229b5840353SAdam Hornáček instance.setDefinition("MaI*"); // should not match Main 230b5840353SAdam Hornáček instance.search(); 231b5840353SAdam Hornáček assertEquals(0, instance.search()); 232b5840353SAdam Hornáček instance.destroy(); 233b5840353SAdam Hornáček 234b5840353SAdam Hornáček // wildcards and case sensitivity of symbol search 235b5840353SAdam Hornáček instance = new SearchEngine(); 236b5840353SAdam Hornáček instance.setSymbol("Mai*"); // symbol is case sensitive 237b5840353SAdam Hornáček instance.setFile("\"Main.java\" OR \"main.c\""); 238b5840353SAdam Hornáček instance.search(); 239b5840353SAdam Hornáček assertEquals(2, instance.search()); 240b5840353SAdam Hornáček instance.setSymbol("MaI*"); // should not match Main 241b5840353SAdam Hornáček instance.search(); 242b5840353SAdam Hornáček assertEquals(0, instance.search()); 243b5840353SAdam Hornáček instance.destroy(); 244b5840353SAdam Hornáček 245b5840353SAdam Hornáček // wildcards and case insensitivity of freetext search 246b5840353SAdam Hornáček instance = new SearchEngine(); 247b5840353SAdam Hornáček instance.setFreetext("MaI*"); // should match both Main and main 248b5840353SAdam Hornáček instance.setFile("\"Main.java\" OR \"main.c\""); 249b5840353SAdam Hornáček assertEquals(10, instance.search()); 250b5840353SAdam Hornáček instance.destroy(); 251b5840353SAdam Hornáček 252b5840353SAdam Hornáček // file name search is case insensitive 253b5840353SAdam Hornáček instance = new SearchEngine(); 254b5840353SAdam Hornáček instance.setFile("JaVa"); // should match java 255b5840353SAdam Hornáček int count=instance.search(); 256b5840353SAdam Hornáček if (count > 0) { 257b5840353SAdam Hornáček instance.results(0, count, hits); 258b5840353SAdam Hornáček } 259b5840353SAdam Hornáček assertEquals(8, count); // path is now case sensitive ... but only in SearchEngine ! 260b5840353SAdam Hornáček instance.destroy(); 261b5840353SAdam Hornáček 262b5840353SAdam Hornáček //test eol and eof 263b5840353SAdam Hornáček instance = new SearchEngine(); 264b5840353SAdam Hornáček instance.setFreetext("makeW"); 265b5840353SAdam Hornáček assertEquals(1, instance.search()); 266b5840353SAdam Hornáček instance.destroy(); 267b5840353SAdam Hornáček 268b5840353SAdam Hornáček instance = new SearchEngine(); 269b5840353SAdam Hornáček instance.setFreetext("WeirdEOL"); 270b5840353SAdam Hornáček assertEquals(1, instance.search()); 271b5840353SAdam Hornáček instance.destroy(); 272b5840353SAdam Hornáček 273b5840353SAdam Hornáček //test bcel jar parser 274b5840353SAdam Hornáček instance = new SearchEngine(); 275b5840353SAdam Hornáček instance.setFreetext("InstConstraintVisitor"); 276b5840353SAdam Hornáček assertEquals(1, instance.search()); 277b5840353SAdam Hornáček instance.destroy(); 278b5840353SAdam Hornáček } 2796d5300acSAdam Hornáček */ 280b5840353SAdam Hornáček } 281