]> source.dussan.org Git - sonarqube.git/blob
efaca113b357b8989c6379740856e343d9dcaad7
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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.projectanalysis.step;
21
22 import java.text.SimpleDateFormat;
23 import java.util.Date;
24 import java.util.Optional;
25 import java.util.function.Consumer;
26 import java.util.stream.Stream;
27 import org.junit.Before;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.sonar.api.utils.DateUtils;
31 import org.sonar.api.utils.System2;
32 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
33 import org.sonar.ce.task.projectanalysis.analysis.TestBranch;
34 import org.sonar.ce.task.projectanalysis.component.BranchPersister;
35 import org.sonar.ce.task.projectanalysis.component.Component;
36 import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl;
37 import org.sonar.ce.task.projectanalysis.component.FileAttributes;
38 import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder;
39 import org.sonar.ce.task.projectanalysis.component.ProjectPersister;
40 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
41 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
42 import org.sonar.ce.task.step.ComputationStep;
43 import org.sonar.ce.task.step.TestComputationStepContext;
44 import org.sonar.db.DbClient;
45 import org.sonar.db.DbTester;
46 import org.sonar.db.component.ComponentDto;
47 import org.sonar.db.component.ComponentTesting;
48 import org.sonar.server.project.Project;
49
50 import static org.assertj.core.api.Assertions.assertThat;
51 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
52 import static org.mockito.Mockito.mock;
53 import static org.mockito.Mockito.when;
54 import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
55 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
56 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
57 import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
58 import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
59 import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
60 import static org.sonar.db.component.ComponentTesting.newDirectory;
61 import static org.sonar.db.component.ComponentTesting.newModuleDto;
62
63 public class ReportPersistComponentsStepTest extends BaseStepTest {
64
65   private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
66   private static final String PROJECT_KEY = "PROJECT_KEY";
67
68   @Rule
69   public DbTester db = DbTester.create(System2.INSTANCE);
70   @Rule
71   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
72   @Rule
73   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
74
75   private final System2 system2 = mock(System2.class);
76   private final DbClient dbClient = db.getDbClient();
77   private Date now;
78   private final MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);
79   private PersistComponentsStep underTest;
80
81   @Before
82   public void setup() throws Exception {
83     now = DATE_FORMAT.parse("2015-06-02");
84     when(system2.now()).thenReturn(now.getTime());
85
86     BranchPersister branchPersister = mock(BranchPersister.class);
87     ProjectPersister projectPersister = mock(ProjectPersister.class);
88     underTest = new PersistComponentsStep(dbClient, treeRootHolder, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister, projectPersister);
89   }
90
91   @Override
92   protected ComputationStep step() {
93     return underTest;
94   }
95
96   @Test
97   public void persist_components() {
98     ComponentDto projectDto = prepareProject();
99     Component file = builder(FILE, 4).setUuid("DEFG").setKey("PROJECT_KEY:src/main/java/dir/Foo.java")
100       .setName("src/main/java/dir/Foo.java")
101       .setShortName("Foo.java")
102       .setFileAttributes(new FileAttributes(false, "java", 1))
103       .build();
104     Component directory = builder(DIRECTORY, 3).setUuid("CDEF").setKey("PROJECT_KEY:src/main/java/dir")
105       .setName("src/main/java/dir")
106       .setShortName("dir")
107       .addChildren(file)
108       .build();
109     Component treeRoot = asTreeRoot(projectDto)
110       .addChildren(directory)
111       .build();
112     treeRootHolder.setRoot(treeRoot);
113
114     underTest.execute(new TestComputationStepContext());
115
116     assertThat(db.countRowsOfTable("components")).isEqualTo(3);
117
118     ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get();
119     assertThat(directoryDto.name()).isEqualTo("dir");
120     assertThat(directoryDto.longName()).isEqualTo("src/main/java/dir");
121     assertThat(directoryDto.description()).isNull();
122     assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
123     assertThat(directoryDto.uuid()).isEqualTo("CDEF");
124     assertThat(directoryDto.getUuidPath()).isEqualTo(UUID_PATH_SEPARATOR + projectDto.uuid() + UUID_PATH_SEPARATOR);
125     assertThat(directoryDto.moduleUuid()).isEqualTo(projectDto.uuid());
126     assertThat(directoryDto.moduleUuidPath()).isEqualTo(projectDto.moduleUuidPath());
127     assertThat(directoryDto.getMainBranchProjectUuid()).isNull();
128     assertThat(directoryDto.projectUuid()).isEqualTo(projectDto.uuid());
129     assertThat(directoryDto.qualifier()).isEqualTo("DIR");
130     assertThat(directoryDto.scope()).isEqualTo("DIR");
131     assertThat(directoryDto.getRootUuid()).isEqualTo(projectDto.uuid());
132     assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
133
134     ComponentDto fileDto = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get();
135     assertThat(fileDto.name()).isEqualTo("Foo.java");
136     assertThat(fileDto.longName()).isEqualTo("src/main/java/dir/Foo.java");
137     assertThat(fileDto.description()).isNull();
138     assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
139     assertThat(fileDto.language()).isEqualTo("java");
140     assertThat(fileDto.uuid()).isEqualTo("DEFG");
141     assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
142     assertThat(fileDto.moduleUuid()).isEqualTo(projectDto.uuid());
143     assertThat(fileDto.moduleUuidPath()).isEqualTo(projectDto.moduleUuidPath());
144     assertThat(fileDto.getMainBranchProjectUuid()).isNull();
145     assertThat(fileDto.projectUuid()).isEqualTo(projectDto.uuid());
146     assertThat(fileDto.qualifier()).isEqualTo("FIL");
147     assertThat(fileDto.scope()).isEqualTo("FIL");
148     assertThat(fileDto.getRootUuid()).isEqualTo(projectDto.uuid());
149     assertThat(fileDto.getCreatedAt()).isEqualTo(now);
150   }
151
152   @Test
153   public void persist_components_of_existing_branch() {
154     ComponentDto project = prepareBranch("feature/foo");
155     Component file = builder(FILE, 4).setUuid("DEFG").setKey("PROJECT_KEY:src/main/java/dir/Foo.java")
156       .setName("src/main/java/dir/Foo.java")
157       .setShortName("Foo.java")
158       .setFileAttributes(new FileAttributes(false, "java", 1))
159       .build();
160     Component directory = builder(DIRECTORY, 3).setUuid("CDEF")
161       .setKey("PROJECT_KEY:src/main/java/dir")
162       .setName("src/main/java/dir")
163       .setShortName("dir")
164       .addChildren(file)
165       .build();
166     Component treeRoot = asTreeRoot(project)
167       .addChildren(directory)
168       .build();
169     treeRootHolder.setRoot(treeRoot);
170
171     underTest.execute(new TestComputationStepContext());
172
173     assertThat(db.countRowsOfTable("components")).isEqualTo(3);
174
175     ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get();
176     assertThat(directoryDto.name()).isEqualTo("dir");
177     assertThat(directoryDto.longName()).isEqualTo("src/main/java/dir");
178     assertThat(directoryDto.description()).isNull();
179     assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
180     assertThat(directoryDto.uuid()).isEqualTo("CDEF");
181     assertThat(directoryDto.getUuidPath()).isEqualTo(UUID_PATH_SEPARATOR + project.uuid() + UUID_PATH_SEPARATOR);
182     assertThat(directoryDto.moduleUuid()).isEqualTo(project.uuid());
183     assertThat(directoryDto.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
184     assertThat(directoryDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
185     assertThat(directoryDto.projectUuid()).isEqualTo(project.uuid());
186     assertThat(directoryDto.qualifier()).isEqualTo("DIR");
187     assertThat(directoryDto.scope()).isEqualTo("DIR");
188     assertThat(directoryDto.getRootUuid()).isEqualTo(project.uuid());
189     assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
190
191     ComponentDto fileDto = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get();
192     assertThat(fileDto.name()).isEqualTo("Foo.java");
193     assertThat(fileDto.longName()).isEqualTo("src/main/java/dir/Foo.java");
194     assertThat(fileDto.description()).isNull();
195     assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
196     assertThat(fileDto.language()).isEqualTo("java");
197     assertThat(fileDto.uuid()).isEqualTo("DEFG");
198     assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
199     assertThat(fileDto.moduleUuid()).isEqualTo(project.uuid());
200     assertThat(fileDto.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
201     assertThat(fileDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
202     assertThat(fileDto.projectUuid()).isEqualTo(project.uuid());
203     assertThat(fileDto.qualifier()).isEqualTo("FIL");
204     assertThat(fileDto.scope()).isEqualTo("FIL");
205     assertThat(fileDto.getRootUuid()).isEqualTo(project.uuid());
206     assertThat(fileDto.getCreatedAt()).isEqualTo(now);
207   }
208
209   @Test
210   public void persist_file_directly_attached_on_root_directory() {
211     ComponentDto projectDto = prepareProject();
212     treeRootHolder.setRoot(
213       asTreeRoot(projectDto)
214         .addChildren(
215           builder(FILE, 2).setUuid("DEFG").setKey(projectDto.getDbKey() + ":pom.xml")
216             .setName("pom.xml")
217             .build())
218         .build());
219
220     underTest.execute(new TestComputationStepContext());
221
222     assertThat(dbClient.componentDao().selectByKey(db.getSession(), projectDto.getDbKey() + ":/")).isNotPresent();
223
224     ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), projectDto.getDbKey() + ":pom.xml").get();
225     assertThat(file.name()).isEqualTo("pom.xml");
226     assertThat(file.path()).isEqualTo("pom.xml");
227   }
228
229   @Test
230   public void persist_unit_test() {
231     ComponentDto projectDto = prepareProject();
232     treeRootHolder.setRoot(
233       asTreeRoot(projectDto)
234         .addChildren(
235           builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":src/test/java/dir")
236             .setName("src/test/java/dir")
237             .addChildren(
238               builder(FILE, 3).setUuid("DEFG").setKey(PROJECT_KEY + ":src/test/java/dir/FooTest.java")
239                 .setName("src/test/java/dir/FooTest.java")
240                 .setShortName("FooTest.java")
241                 .setFileAttributes(new FileAttributes(true, null, 1))
242                 .build())
243             .build())
244         .build());
245
246     underTest.execute(new TestComputationStepContext());
247
248     ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), PROJECT_KEY + ":src/test/java/dir/FooTest.java").get();
249     assertThat(file.name()).isEqualTo("FooTest.java");
250     assertThat(file.longName()).isEqualTo("src/test/java/dir/FooTest.java");
251     assertThat(file.path()).isEqualTo("src/test/java/dir/FooTest.java");
252     assertThat(file.qualifier()).isEqualTo("UTS");
253     assertThat(file.scope()).isEqualTo("FIL");
254   }
255
256   @Test
257   public void update_file_to_directory_change_scope() {
258     ComponentDto project = prepareProject();
259     ComponentDto directory = ComponentTesting.newDirectory(project, "src").setUuid("CDEF").setDbKey("PROJECT_KEY:src");
260     ComponentDto file = ComponentTesting.newFileDto(project, directory, "DEFG").setPath("src/foo").setName("foo")
261       .setDbKey("PROJECT_KEY:src/foo");
262     dbClient.componentDao().insert(db.getSession(), directory, file);
263     db.getSession().commit();
264
265     assertThat(dbClient.componentDao().selectByKey(db.getSession(), PROJECT_KEY + ":src/foo").get().scope()).isEqualTo("FIL");
266
267     treeRootHolder.setRoot(
268       asTreeRoot(project)
269         .addChildren(
270           builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":src")
271             .setName("src")
272             .addChildren(
273               builder(DIRECTORY, 3).setUuid("DEFG").setKey(PROJECT_KEY + ":src/foo")
274                 .setName("foo")
275                 .addChildren(
276                   builder(FILE, 4).setUuid("HIJK").setKey(PROJECT_KEY + ":src/foo/FooTest.java")
277                     .setName("src/foo/FooTest.java")
278                     .setShortName("FooTest.java")
279                     .setFileAttributes(new FileAttributes(false, null, 1))
280                     .build())
281                 .build())
282             .build())
283         .build());
284
285     underTest.execute(new TestComputationStepContext());
286
287     // commit the functional transaction
288     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
289     db.commit();
290
291     assertThat(dbClient.componentDao().selectByKey(db.getSession(), PROJECT_KEY + ":src/foo").get().scope()).isEqualTo("DIR");
292   }
293
294   @Test
295   public void update_module_to_directory_change_scope() {
296     ComponentDto project = prepareProject();
297     ComponentDto module = ComponentTesting.newModuleDto(project).setUuid("CDEF").setDbKey("MODULE_KEY").setPath("module");
298     dbClient.componentDao().insert(db.getSession(), module);
299     db.getSession().commit();
300
301     assertThat(dbClient.componentDao().selectByUuid(db.getSession(), "CDEF").get().scope()).isEqualTo("PRJ");
302
303     treeRootHolder.setRoot(
304       asTreeRoot(project)
305         .addChildren(
306           builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":module")
307             .setName("module")
308             .addChildren(
309               builder(FILE, 3).setUuid("HIJK").setKey(PROJECT_KEY + ":module/FooTest.java")
310                 .setName("module/FooTest.java")
311                 .setShortName("FooTest.java")
312                 .setFileAttributes(new FileAttributes(false, null, 1))
313                 .build())
314             .build())
315         .build());
316
317     underTest.execute(new TestComputationStepContext());
318
319     // commit the functional transaction
320     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
321     db.commit();
322
323     assertThat(dbClient.componentDao().selectByUuid(db.getSession(), "CDEF").get().scope()).isEqualTo("DIR");
324   }
325
326   @Test
327   public void persist_only_new_components() {
328     // Project and module already exists
329     ComponentDto project = prepareProject();
330     db.getSession().commit();
331
332     treeRootHolder.setRoot(
333       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
334         .setName("Project")
335         .addChildren(
336           builder(DIRECTORY, 3).setUuid("CDEF").setKey("PROJECT_KEY:src/main/java/dir")
337             .setName("src/main/java/dir")
338             .addChildren(
339               builder(FILE, 4).setUuid("DEFG").setKey("PROJECT_KEY:src/main/java/dir/Foo.java")
340                 .setName("src/main/java/dir/Foo.java")
341                 .setShortName("Foo.java")
342                 .build())
343             .build())
344         .build());
345
346     underTest.execute(new TestComputationStepContext());
347
348     assertThat(db.countRowsOfTable("components")).isEqualTo(3);
349
350     ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
351     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
352     assertThat(projectReloaded.getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT);
353     assertThat(projectReloaded.getMainBranchProjectUuid()).isNull();
354
355     ComponentDto directory = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get();
356     assertThat(directory.getUuidPath()).isEqualTo(directory.getUuidPath());
357     assertThat(directory.moduleUuid()).isEqualTo(project.uuid());
358     assertThat(directory.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
359     assertThat(directory.projectUuid()).isEqualTo(project.uuid());
360     assertThat(directory.getRootUuid()).isEqualTo(project.uuid());
361     assertThat(directory.getMainBranchProjectUuid()).isNull();
362
363     ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get();
364     assertThat(file.getUuidPath()).isEqualTo(file.getUuidPath());
365     assertThat(file.moduleUuid()).isEqualTo(project.uuid());
366     assertThat(file.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
367     assertThat(file.projectUuid()).isEqualTo(project.uuid());
368     assertThat(file.getRootUuid()).isEqualTo(project.uuid());
369     assertThat(file.getMainBranchProjectUuid()).isNull();
370   }
371
372   @Test
373   public void nothing_to_persist() {
374     ComponentDto project = prepareProject();
375     ComponentDto directory = ComponentTesting.newDirectory(project, "src/main/java/dir").setUuid("CDEF").setDbKey("PROJECT_KEY:src/main/java/dir");
376     ComponentDto file = ComponentTesting.newFileDto(project, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
377       .setDbKey("PROJECT_KEY:src/main/java/dir/Foo.java");
378     dbClient.componentDao().insert(db.getSession(), directory, file);
379     db.getSession().commit();
380
381     treeRootHolder.setRoot(
382       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
383         .setName("Project")
384         .addChildren(
385           builder(DIRECTORY, 3).setUuid("CDEF").setKey("PROJECT_KEY:src/main/java/dir")
386             .setName("src/main/java/dir")
387             .addChildren(
388               builder(FILE, 4).setUuid("DEFG").setKey("PROJECT_KEY:src/main/java/dir/Foo.java")
389                 .setName("src/main/java/dir/Foo.java")
390                 .build())
391             .build())
392         .build());
393
394     underTest.execute(new TestComputationStepContext());
395
396     assertThat(db.countRowsOfTable("components")).isEqualTo(3);
397     assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().uuid()).isEqualTo(project.uuid());
398     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get().uuid()).isEqualTo(directory.uuid());
399     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get().uuid()).isEqualTo(file.uuid());
400
401     ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
402     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
403     assertThat(projectReloaded.moduleUuid()).isEqualTo(project.moduleUuid());
404     assertThat(projectReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
405     assertThat(projectReloaded.projectUuid()).isEqualTo(project.projectUuid());
406     assertThat(projectReloaded.getRootUuid()).isEqualTo(project.getRootUuid());
407
408     ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get();
409     assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
410     assertThat(directoryReloaded.getUuidPath()).isEqualTo(directory.getUuidPath());
411     assertThat(directoryReloaded.moduleUuid()).isEqualTo(directory.moduleUuid());
412     assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(directory.moduleUuidPath());
413     assertThat(directoryReloaded.projectUuid()).isEqualTo(directory.projectUuid());
414     assertThat(directoryReloaded.getRootUuid()).isEqualTo(directory.getRootUuid());
415     assertThat(directoryReloaded.name()).isEqualTo(directory.name());
416     assertThat(directoryReloaded.path()).isEqualTo(directory.path());
417
418     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get();
419     assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
420     assertThat(fileReloaded.getUuidPath()).isEqualTo(file.getUuidPath());
421     assertThat(fileReloaded.moduleUuid()).isEqualTo(file.moduleUuid());
422     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(file.moduleUuidPath());
423     assertThat(fileReloaded.projectUuid()).isEqualTo(file.projectUuid());
424     assertThat(fileReloaded.getRootUuid()).isEqualTo(file.getRootUuid());
425     assertThat(fileReloaded.name()).isEqualTo(file.name());
426     assertThat(fileReloaded.path()).isEqualTo(file.path());
427   }
428
429   @Test
430   public void update_module_uuid_when_moving_a_module() {
431     ComponentDto project = prepareProject();
432     ComponentDto directory = ComponentTesting.newDirectory(project, "src/main/java/dir").setUuid("CDEF").setDbKey("PROJECT_KEY:src/main/java/dir");
433     ComponentDto file = ComponentTesting.newFileDto(project, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
434       .setDbKey("PROJECT_KEY:src/main/java/dir/Foo.java");
435     dbClient.componentDao().insert(db.getSession(), directory, file);
436     db.getSession().commit();
437
438     treeRootHolder.setRoot(
439       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
440         .setName("Project")
441         .addChildren(
442           builder(DIRECTORY, 4).setUuid("CDEF").setKey("PROJECT_KEY:src/main/java/dir")
443             .setName("src/main/java/dir")
444             .addChildren(
445               builder(FILE, 5).setUuid("DEFG").setKey("PROJECT_KEY:src/main/java/dir/Foo.java")
446                 .setName("src/main/java/dir/Foo.java")
447                 .build())
448             .build())
449         .build());
450
451     underTest.execute(new TestComputationStepContext());
452
453     // commit the functional transaction
454     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
455     db.commit();
456
457     assertThat(db.countRowsOfTable("components")).isEqualTo(3);
458
459     ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get();
460     assertThat(directoryReloaded).isNotNull();
461     assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
462     assertThat(directoryReloaded.getUuidPath()).isEqualTo(directoryReloaded.getUuidPath());
463     assertThat(directoryReloaded.moduleUuid()).isEqualTo(project.uuid());
464     assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
465     assertThat(directoryReloaded.projectUuid()).isEqualTo(project.uuid());
466     assertThat(directoryReloaded.getRootUuid()).isEqualTo(project.uuid());
467
468     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get();
469     assertThat(fileReloaded).isNotNull();
470     assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
471     assertThat(fileReloaded.getUuidPath()).isEqualTo(fileReloaded.getUuidPath());
472     assertThat(fileReloaded.moduleUuid()).isEqualTo(project.uuid());
473     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
474     assertThat(fileReloaded.projectUuid()).isEqualTo(project.uuid());
475     assertThat(fileReloaded.getRootUuid()).isEqualTo(project.uuid());
476   }
477
478   @Test
479   public void do_not_update_created_at_on_existing_component() {
480     Date oldDate = DateUtils.parseDate("2015-01-01");
481     ComponentDto project = prepareProject(p -> p.setCreatedAt(oldDate));
482     db.getSession().commit();
483
484     treeRootHolder.setRoot(
485       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
486         .build());
487
488     underTest.execute(new TestComputationStepContext());
489
490     Optional<ComponentDto> projectReloaded = dbClient.componentDao().selectByUuid(db.getSession(), project.uuid());
491     assertThat(projectReloaded.get().getCreatedAt()).isNotEqualTo(now);
492   }
493
494   @Test
495   public void persist_components_that_were_previously_removed() {
496     ComponentDto project = prepareProject();
497     ComponentDto removedDirectory = ComponentTesting.newDirectory(project, "src/main/java/dir")
498       .setLongName("src/main/java/dir")
499       .setName("dir")
500       .setUuid("CDEF")
501       .setDbKey("PROJECT_KEY:src/main/java/dir")
502       .setEnabled(false);
503     ComponentDto removedFile = ComponentTesting.newFileDto(project, removedDirectory, "DEFG")
504       .setPath("src/main/java/dir/Foo.java")
505       .setLongName("src/main/java/dir/Foo.java")
506       .setName("Foo.java")
507       .setDbKey("PROJECT_KEY:src/main/java/dir/Foo.java")
508       .setEnabled(false);
509     dbClient.componentDao().insert(db.getSession(), removedDirectory, removedFile);
510     db.getSession().commit();
511
512     treeRootHolder.setRoot(
513       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
514         .setName("Project")
515         .addChildren(
516           builder(DIRECTORY, 3).setUuid("CDEF").setKey("PROJECT_KEY:src/main/java/dir")
517             .setName("src/main/java/dir")
518             .setShortName("dir")
519             .addChildren(
520               builder(FILE, 4).setUuid("DEFG").setKey("PROJECT_KEY:src/main/java/dir/Foo.java")
521                 .setName("src/main/java/dir/Foo.java")
522                 .setShortName("Foo.java")
523                 .build())
524             .build())
525         .build());
526
527     underTest.execute(new TestComputationStepContext());
528
529     assertThat(db.countRowsOfTable("components")).isEqualTo(3);
530     assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().uuid()).isEqualTo(project.uuid());
531     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get().uuid()).isEqualTo(removedDirectory.uuid());
532     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get().uuid()).isEqualTo(removedFile.uuid());
533     assertExistButDisabled(removedDirectory.getDbKey(), removedFile.getDbKey());
534
535     // commit the functional transaction
536     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
537
538     ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
539     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
540     assertThat(projectReloaded.getUuidPath()).isEqualTo(project.getUuidPath());
541     assertThat(projectReloaded.moduleUuid()).isEqualTo(project.moduleUuid());
542     assertThat(projectReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
543     assertThat(projectReloaded.projectUuid()).isEqualTo(project.projectUuid());
544     assertThat(projectReloaded.getRootUuid()).isEqualTo(project.getRootUuid());
545     assertThat(projectReloaded.isEnabled()).isTrue();
546
547     ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get();
548     assertThat(directoryReloaded.uuid()).isEqualTo(removedDirectory.uuid());
549     assertThat(directoryReloaded.getUuidPath()).isEqualTo(removedDirectory.getUuidPath());
550     assertThat(directoryReloaded.moduleUuid()).isEqualTo(removedDirectory.moduleUuid());
551     assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(removedDirectory.moduleUuidPath());
552     assertThat(directoryReloaded.projectUuid()).isEqualTo(removedDirectory.projectUuid());
553     assertThat(directoryReloaded.getRootUuid()).isEqualTo(removedDirectory.getRootUuid());
554     assertThat(directoryReloaded.name()).isEqualTo(removedDirectory.name());
555     assertThat(directoryReloaded.longName()).isEqualTo(removedDirectory.longName());
556     assertThat(directoryReloaded.path()).isEqualTo(removedDirectory.path());
557     assertThat(directoryReloaded.isEnabled()).isTrue();
558
559     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get();
560     assertThat(fileReloaded.uuid()).isEqualTo(removedFile.uuid());
561     assertThat(fileReloaded.getUuidPath()).isEqualTo(removedFile.getUuidPath());
562     assertThat(fileReloaded.moduleUuid()).isEqualTo(removedFile.moduleUuid());
563     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(removedFile.moduleUuidPath());
564     assertThat(fileReloaded.projectUuid()).isEqualTo(removedFile.projectUuid());
565     assertThat(fileReloaded.getRootUuid()).isEqualTo(removedFile.getRootUuid());
566     assertThat(fileReloaded.name()).isEqualTo(removedFile.name());
567     assertThat(fileReloaded.path()).isEqualTo(removedFile.path());
568     assertThat(fileReloaded.isEnabled()).isTrue();
569   }
570
571   private void assertExistButDisabled(String... keys) {
572     for (String key : keys) {
573       ComponentDto dto = dbClient.componentDao().selectByKey(db.getSession(), key).get();
574       assertThat(dto.isEnabled()).isFalse();
575     }
576   }
577
578   @Test
579   public void persists_existing_components_with_visibility_of_root_in_db_out_of_functional_transaction() {
580     ComponentDto project = prepareProject(p -> p.setPrivate(true));
581     ComponentDto module = newModuleDto(project).setPrivate(false);
582     db.components().insertComponent(module);
583     ComponentDto dir = db.components().insertComponent(newDirectory(module, "DEFG", "Directory").setDbKey("DIR").setPrivate(true));
584     treeRootHolder.setRoot(createSampleProjectComponentTree(project));
585
586     underTest.execute(new TestComputationStepContext());
587
588     Stream.of(project.uuid(), module.uuid(), dir.uuid())
589       .forEach(uuid -> assertThat(dbClient.componentDao().selectByUuid(db.getSession(), uuid).get().isPrivate())
590         .describedAs("for uuid " + uuid)
591         .isEqualTo(true));
592   }
593
594   private ReportComponent createSampleProjectComponentTree(ComponentDto project) {
595     return createSampleProjectComponentTree(project.uuid(), project.getDbKey());
596   }
597
598   private ReportComponent createSampleProjectComponentTree(String projectUuid, String projectKey) {
599     return builder(PROJECT, 1).setUuid(projectUuid).setKey(projectKey)
600       .setName("Project")
601       .addChildren(
602         builder(Component.Type.DIRECTORY, 3).setUuid("DEFG").setKey("DIR")
603           .setName("Directory")
604           .addChildren(
605             builder(FILE, 4).setUuid("CDEF").setKey("FILE")
606               .setName("file")
607               .build())
608           .build())
609       .build();
610   }
611
612   private ReportComponent.Builder asTreeRoot(ComponentDto project) {
613     return builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey()).setName(project.name());
614   }
615
616   private ComponentDto prepareProject() {
617     return prepareProject(defaults());
618   }
619
620   private ComponentDto prepareProject(Consumer<ComponentDto> populators) {
621     ComponentDto dto = db.components().insertPrivateProject(populators);
622     analysisMetadataHolder.setProject(Project.from(dto));
623     analysisMetadataHolder.setBranch(new DefaultBranchImpl());
624     return dto;
625   }
626
627   private ComponentDto prepareBranch(String branchName) {
628     return prepareBranch(branchName, defaults());
629   }
630
631   private ComponentDto prepareBranch(String branchName, Consumer<ComponentDto> populators) {
632     ComponentDto dto = db.components().insertPrivateProject(populators);
633     analysisMetadataHolder.setProject(Project.from(dto));
634     analysisMetadataHolder.setBranch(new TestBranch(branchName));
635     return dto;
636   }
637
638   private static <T> Consumer<T> defaults() {
639     return t -> {
640     };
641   }
642
643 }