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) 2008, 2022, Oracle and/or its affiliates. All rights reserved. 22 */ 23 package org.opengrok.indexer.history; 24 25 import org.junit.jupiter.api.AfterEach; 26 import org.junit.jupiter.api.BeforeEach; 27 import org.junit.jupiter.api.Test; 28 import org.opengrok.indexer.condition.EnabledForRepository; 29 import org.opengrok.indexer.condition.RepositoryInstalled; 30 import org.opengrok.indexer.util.IOUtils; 31 import org.opengrok.indexer.util.TestRepository; 32 33 import java.io.File; 34 import java.io.IOException; 35 import java.io.InputStream; 36 import java.net.URISyntaxException; 37 import java.util.Date; 38 import java.util.List; 39 import java.util.Map; 40 41 import static org.junit.jupiter.api.Assertions.assertEquals; 42 import static org.junit.jupiter.api.Assertions.assertNotNull; 43 import static org.junit.jupiter.api.Assertions.assertTrue; 44 import static org.opengrok.indexer.history.CVSRepositoryTest.runCvsCommand; 45 46 /** 47 * Test {@code cvs log} output parsing in {@link CVSHistoryParser}. 48 * @author austvik 49 */ 50 class CVSHistoryParserTest { 51 52 CVSHistoryParser instance; 53 54 private TestRepository repository; 55 56 /** 57 * Set up a test repository. Should be called by the tests that need it. The 58 * test repository will be destroyed automatically when the test finishes. 59 */ setUpTestRepository()60 private File setUpTestRepository() throws IOException, URISyntaxException { 61 repository = new TestRepository(); 62 repository.create(getClass().getResource("/repositories")); 63 64 // Checkout cvsrepo anew in order to get the CVS/Root files point to 65 // the temporary directory rather than the OpenGrok workspace directory 66 // it was created from. This is necessary for the 'cvs log' command to work correctly. 67 File root = new File(repository.getSourceRoot(), "cvs_test"); 68 File cvsrepodir = new File(root, "cvsrepo"); 69 IOUtils.removeRecursive(cvsrepodir.toPath()); 70 File cvsroot = new File(root, "cvsroot"); 71 runCvsCommand(root, "-d", cvsroot.getAbsolutePath(), "checkout", "cvsrepo"); 72 return cvsrepodir; 73 } 74 75 @BeforeEach setUp()76 public void setUp() { 77 instance = new CVSHistoryParser(); 78 } 79 80 @AfterEach tearDown()81 public void tearDown() { 82 instance = null; 83 84 if (repository != null) { 85 repository.destroy(); 86 repository = null; 87 } 88 } 89 90 /** 91 * Test of parse method, of class CVSHistoryParser. 92 * @throws Exception exception 93 */ 94 @Test parseEmpty()95 void parseEmpty() throws Exception { 96 History result = instance.parse(""); 97 assertNotNull(result); 98 assertEquals(0, result.getHistoryEntries().size(), "Should not contain any history entries"); 99 } 100 101 /** 102 * Parse something that could come out from the W3C public CVS repository. 103 */ 104 @Test parseALaW3C()105 void parseALaW3C() throws Exception { 106 String revId1 = "1.2"; 107 String revId2 = "1.2.4.5"; 108 String revId3 = "1.134"; 109 String tag1 = "file_tag"; 110 String author1 = "username"; 111 String author2 = "username2"; 112 String date1 = "2005-05-16 21:22:34 +0200"; 113 String date2 = "2007-05-16 22:21:30 +0300"; 114 String output = "\n" + 115 "\n" + 116 " RCS file: /some/file/name.ext,v\n" + 117 "Working file: name.ext\n" + 118 "head: 1.23\n" + 119 "branch:\n" + 120 "locks: strict\n" + 121 "access list:\n" + 122 "symbolic names:\n" + 123 "\t" + tag1 + ": " + revId2 + "\n" + 124 "keyword substitution: kv\n" + 125 "total revisions: 4;\tselected revisions: 3\n" + 126 "description:\n" + 127 "----------------------------\n" + 128 "revision " + revId1 + "\n" + 129 "date: " + date1 + "; author: " + author1 + 130 "; state: Exp; lines: +2 -2;\n" + 131 "a comment\n" + 132 "----------------------------\n" + 133 "revision " + revId2 + "\n" + 134 "date: " + date2 + "; author: " + author2 + 135 "; state: Exp; lines: +2 -4;\n" + 136 "just a short comment\n" + 137 "----------------------------\n" + 138 "revision " + revId3 + "\n" + 139 "date: " + date1 + "; author: " + author1 + 140 "; state: Exp; lines: +6 -2;\n" + 141 "some comment that is\n" + 142 "--------\n" + 143 "spanning multiple lines\n" + 144 "==========================================================" + 145 "===================\n"; 146 History result = instance.parse(output); 147 assertNotNull(result); 148 assertEquals(3, result.getHistoryEntries().size()); 149 HistoryEntry e0 = result.getHistoryEntries().get(0); 150 assertEquals(revId1, e0.getRevision()); 151 assertEquals(author1, e0.getAuthor()); 152 assertEquals(0, e0.getFiles().size()); 153 HistoryEntry e1 = result.getHistoryEntries().get(1); 154 assertEquals(revId2, e1.getRevision()); 155 assertEquals(author2, e1.getAuthor()); 156 assertEquals(0, e1.getFiles().size()); 157 HistoryEntry e2 = result.getHistoryEntries().get(2); 158 assertEquals(revId3, e2.getRevision()); 159 assertEquals(author1, e2.getAuthor()); 160 assertEquals(0, e2.getFiles().size()); 161 assertTrue(e2.getMessage().contains("some"), "Should contain comment of both lines: line 1"); 162 assertTrue(e2.getMessage().contains("multiple"), "Should contain comment of both lines: line 2"); 163 164 assertEquals(Map.of(revId2, tag1), result.getTags()); 165 } 166 167 /** 168 * Check that history can be retrieved for a directory. This is needed for the web application to operate 169 * correctly. Specifically, this tests the state transitions in {@link CVSHistoryParser#processStream(InputStream)}. 170 */ 171 @EnabledForRepository(RepositoryInstalled.Type.CVS) 172 @Test testHistoryForDirectory()173 void testHistoryForDirectory() throws Exception { 174 File repoRoot = setUpTestRepository(); 175 assertTrue(repoRoot.exists()); 176 assertTrue(repoRoot.isDirectory()); 177 CVSRepository repository = (CVSRepository) RepositoryFactory.getRepository(repoRoot); 178 assertNotNull(repository); 179 History history = repository.getHistory(repoRoot); 180 assertNotNull(history); 181 assertNotNull(history.getHistoryEntries()); 182 assertEquals(3, history.getHistoryEntries().size()); 183 184 List<HistoryEntry> entries = List.of( 185 new HistoryEntry("1.1.1.1", new Date(1220544581000L), 186 "austvik", 187 "Add files\n", true), 188 new HistoryEntry("1.2", new Date(1220544684000L), 189 "austvik", 190 "Added a comment\n", true), 191 new HistoryEntry("1.1", new Date(1220544581000L), 192 "austvik", 193 "branches: 1.1.1;\n" + 194 "Initial revision\n", true) 195 ); 196 197 assertEquals(entries.size(), history.getHistoryEntries().size()); 198 History expectedHistory = new History(entries); 199 expectedHistory.setTags(Map.of("1.1.1.1", "start")); 200 assertEquals(expectedHistory, history); 201 } 202 } 203