]> source.dussan.org Git - sonarqube.git/blob
3db9bfce88ddf397a8eeeb59898866136cfacea0
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.ce.task.projectexport.file;
21
22 import com.sonarsource.governance.projectdump.protobuf.ProjectDump;
23 import java.util.List;
24 import org.junit.After;
25 import org.junit.Before;
26 import org.junit.Rule;
27 import org.junit.Test;
28 import org.mockito.ArgumentCaptor;
29 import org.slf4j.event.Level;
30 import org.sonar.api.testfixtures.log.LogTester;
31 import org.sonar.api.utils.System2;
32 import org.sonar.ce.task.projectexport.component.ComponentRepositoryImpl;
33 import org.sonar.ce.task.projectexport.component.MutableComponentRepository;
34 import org.sonar.ce.task.projectexport.steps.DumpElement;
35 import org.sonar.ce.task.projectexport.steps.FakeDumpWriter;
36 import org.sonar.ce.task.step.TestComputationStepContext;
37 import org.sonar.core.util.Uuids;
38 import org.sonar.db.DbClient;
39 import org.sonar.db.DbSession;
40 import org.sonar.db.DbTester;
41 import org.sonar.db.MyBatis;
42 import org.sonar.db.source.FileSourceDto;
43
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.mockito.ArgumentMatchers.any;
46 import static org.mockito.Mockito.doCallRealMethod;
47 import static org.mockito.Mockito.spy;
48 import static org.mockito.Mockito.verifyNoInteractions;
49 import static org.mockito.Mockito.when;
50
51 public class ExportLineHashesStepIT {
52   private static final String PROJECT_MASTER_UUID = "project uuid";
53   private static final String PROJECT_BRANCH_UUID = "branch-uuid";
54   private static final String FILE_UUID = "file uuid";
55   private static final String FILE_UUID_2 = "file-2-uuid";
56
57   @Rule
58   public DbTester dbTester = DbTester.create(System2.INSTANCE);
59   @Rule
60   public LogTester logTester = new LogTester();
61
62   private final DbClient dbClient = dbTester.getDbClient();
63   private final DbSession dbSession = dbClient.openSession(false);
64   private final FakeDumpWriter dumpWriter = new FakeDumpWriter();
65   private final MutableComponentRepository componentRepository = new ComponentRepositoryImpl();
66   private final ExportLineHashesStep underTest = new ExportLineHashesStep(dbClient, dumpWriter, componentRepository);
67
68   @Before
69   public void before() {
70     logTester.setLevel(Level.DEBUG);
71   }
72
73   @After
74   public void tearDown() {
75     dbSession.close();
76   }
77
78   @Test
79   public void getDescription_is_set() {
80     assertThat(underTest.getDescription()).isEqualTo("Export line hashes");
81   }
82
83   @Test
84   public void execute_does_not_create_a_session_when_there_is_no_file_in_ComponentRepository() {
85     DbClient spy = spy(dbClient);
86     new ExportLineHashesStep(spy, dumpWriter, componentRepository)
87       .execute(new TestComputationStepContext());
88
89     verifyNoInteractions(spy);
90
91     assertThat(dumpWriter.getWrittenMessagesOf(DumpElement.LINES_HASHES)).isEmpty();
92   }
93
94   @Test
95   public void execute_relies_only_on_file_uuid_and_does_not_check_project_uuid() {
96     componentRepository.register(1, FILE_UUID, true);
97
98     insertFileSource(createDto(FILE_UUID, "blabla", "A"));
99     insertFileSource(createDto(FILE_UUID_2, "blabla", "B"));
100
101     underTest.execute(new TestComputationStepContext());
102
103     assertThat(dumpWriter.getWrittenMessagesOf(DumpElement.LINES_HASHES)).hasSize(1);
104   }
105
106   @Test
107   public void execute_maps_ref_of_component_and_hashes_from_fileSources() {
108     int fileRef = 984615;
109     componentRepository.register(fileRef, FILE_UUID, true);
110     FileSourceDto dto = createDto(FILE_UUID, PROJECT_MASTER_UUID, "B");
111     insertFileSource(dto);
112
113     underTest.execute(new TestComputationStepContext());
114
115     List<ProjectDump.LineHashes> messages = dumpWriter.getWrittenMessagesOf(DumpElement.LINES_HASHES);
116     assertThat(messages).hasSize(1);
117     ProjectDump.LineHashes lineHashes = messages.iterator().next();
118     assertThat(lineHashes.getHashes()).isEqualTo(dto.getRawLineHashes());
119     assertThat(lineHashes.getComponentRef()).isEqualTo(fileRef);
120   }
121
122   @Test
123   public void execute_does_one_SQL_request_by_1000_items_per_IN_clause() {
124     for (int i = 0; i < 2500; i++) {
125       componentRepository.register(i, "uuid_" + i, true);
126     }
127
128     DbClient spyDbClient = spy(dbClient);
129     MyBatis spyMyBatis = spy(dbClient.getMyBatis());
130     when(spyDbClient.getMyBatis()).thenReturn(spyMyBatis);
131     ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
132     doCallRealMethod().when(spyMyBatis).newScrollingSelectStatement(any(DbSession.class), stringCaptor.capture());
133
134     new ExportLineHashesStep(spyDbClient, dumpWriter, componentRepository)
135       .execute(new TestComputationStepContext());
136
137     List<String> statements = stringCaptor.getAllValues();
138     assertThat(statements).hasSize(3);
139
140     assertThat(statements.get(0).split("\\?")).hasSize(1001);
141     assertThat(statements.get(1).split("\\?")).hasSize(1001);
142     assertThat(statements.get(2).split("\\?")).hasSize(501);
143   }
144
145   @Test
146   public void execute_exports_lines_hashes_of_file_sources() {
147     componentRepository.register(1, FILE_UUID, true);
148     insertFileSource(FILE_UUID, "A");
149
150     underTest.execute(new TestComputationStepContext());
151
152     assertThat(dumpWriter.getWrittenMessagesOf(DumpElement.LINES_HASHES))
153       .extracting(ProjectDump.LineHashes::getHashes)
154       .containsOnly("A");
155   }
156
157   @Test
158   public void execute_logs_number_of_filesource_exported_and_export_by_order_of_id() {
159     componentRepository.register(1, FILE_UUID, true);
160     componentRepository.register(2, "file-2", true);
161     componentRepository.register(3, "file-3", true);
162     componentRepository.register(4, "file-4", true);
163
164     insertFileSource(createDto(FILE_UUID, PROJECT_MASTER_UUID, "A"));
165     insertFileSource(createDto("file-2", PROJECT_MASTER_UUID, "C"));
166     insertFileSource(createDto("file-3", PROJECT_MASTER_UUID, "D"));
167     insertFileSource(createDto("file-4", PROJECT_BRANCH_UUID, "E"));
168
169     underTest.execute(new TestComputationStepContext());
170
171     assertThat(dumpWriter.getWrittenMessagesOf(DumpElement.LINES_HASHES))
172       .extracting(ProjectDump.LineHashes::getHashes)
173       .containsExactly("A", "C", "D", "E");
174
175     assertThat(logTester.logs(Level.DEBUG)).contains("Lines hashes of 4 files exported");
176   }
177
178   private FileSourceDto insertFileSource(String fileUuid, String hashes) {
179     FileSourceDto dto = createDto(fileUuid, PROJECT_MASTER_UUID, hashes);
180     return insertFileSource(dto);
181   }
182
183   private FileSourceDto insertFileSource(FileSourceDto dto) {
184     dbClient.fileSourceDao().insert(dbSession, dto);
185     dbSession.commit();
186     return dto;
187   }
188
189   private FileSourceDto createDto(String fileUuid, String componentUuid, String hashes) {
190     FileSourceDto fileSourceDto = new FileSourceDto()
191       .setUuid(Uuids.createFast())
192       .setFileUuid(fileUuid)
193       .setProjectUuid(componentUuid);
194     fileSourceDto.setRawLineHashes(hashes);
195     return fileSourceDto;
196   }
197 }