]> source.dussan.org Git - sonarqube.git/blob
812a193354b4966e484effdc3e95e782abec8ff3
[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.server.qualityprofile;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.Reader;
25 import java.io.StringWriter;
26 import java.io.Writer;
27 import java.util.Collection;
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.mockito.ArgumentCaptor;
31 import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
32 import org.sonar.api.profiles.ProfileExporter;
33 import org.sonar.api.profiles.ProfileImporter;
34 import org.sonar.api.profiles.RulesProfile;
35 import org.sonar.api.rules.Rule;
36 import org.sonar.api.rules.RuleFinder;
37 import org.sonar.api.rules.RulePriority;
38 import org.sonar.api.utils.System2;
39 import org.sonar.api.utils.ValidationMessages;
40 import org.sonar.db.DbSession;
41 import org.sonar.db.DbTester;
42 import org.sonar.db.qualityprofile.QProfileDto;
43 import org.sonar.db.rule.RuleDefinitionDto;
44 import org.sonar.server.exceptions.BadRequestException;
45 import org.sonar.server.exceptions.NotFoundException;
46 import org.sonar.server.rule.DefaultRuleFinder;
47 import org.sonar.server.tester.UserSessionRule;
48
49 import static java.nio.charset.StandardCharsets.UTF_8;
50 import static org.apache.commons.io.IOUtils.toInputStream;
51 import static org.assertj.core.api.Assertions.assertThat;
52 import static org.assertj.core.api.Assertions.assertThatThrownBy;
53 import static org.mockito.ArgumentMatchers.any;
54 import static org.mockito.Mockito.mock;
55 import static org.mockito.Mockito.verify;
56 import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto;
57
58 public class QProfileExportersTest {
59
60   @org.junit.Rule
61   public UserSessionRule userSessionRule = UserSessionRule.standalone();
62
63   private final System2 system2 = new AlwaysIncreasingSystem2();
64
65   @org.junit.Rule
66   public DbTester db = DbTester.create(system2);
67
68   private final RuleFinder ruleFinder = new DefaultRuleFinder(db.getDbClient());
69   private final ProfileExporter[] exporters = new ProfileExporter[] {
70     new StandardExporter(), new XooExporter()};
71   private final ProfileImporter[] importers = new ProfileImporter[] {
72     new XooProfileImporter(), new XooProfileImporterWithMessages(), new XooProfileImporterWithError()};
73   private RuleDefinitionDto rule;
74   private final QProfileRules qProfileRules = mock(QProfileRules.class);
75   private final QProfileExporters underTest = new QProfileExporters(db.getDbClient(), ruleFinder, qProfileRules, exporters, importers);
76
77   @Before
78   public void setUp() {
79     rule = db.rules().insert(r -> r.setLanguage("xoo").setRepositoryKey("SonarXoo").setRuleKey("R1"));
80   }
81
82   @Test
83   public void exportersForLanguage() {
84     assertThat(underTest.exportersForLanguage("xoo")).hasSize(2);
85     assertThat(underTest.exportersForLanguage("java")).hasSize(1);
86     assertThat(underTest.exportersForLanguage("java").get(0)).isInstanceOf(StandardExporter.class);
87   }
88
89   @Test
90   public void mimeType() {
91     assertThat(underTest.mimeType("xootool")).isEqualTo("plain/custom");
92
93     // default mime type
94     assertThat(underTest.mimeType("standard")).isEqualTo("text/plain");
95   }
96
97   @Test
98   public void import_xml() {
99     QProfileDto profile = createProfile();
100
101     underTest.importXml(profile, "XooProfileImporter", toInputStream("<xml/>", UTF_8), db.getSession());
102
103     ArgumentCaptor<QProfileDto> profileCapture = ArgumentCaptor.forClass(QProfileDto.class);
104     Class<Collection<RuleActivation>> collectionClass = (Class<Collection<RuleActivation>>) (Class) Collection.class;
105     ArgumentCaptor<Collection<RuleActivation>> activationCapture = ArgumentCaptor.forClass(collectionClass);
106     verify(qProfileRules).activateAndCommit(any(DbSession.class), profileCapture.capture(), activationCapture.capture());
107
108     assertThat(profileCapture.getValue().getKee()).isEqualTo(profile.getKee());
109     Collection<RuleActivation> activations = activationCapture.getValue();
110     assertThat(activations).hasSize(1);
111     RuleActivation activation = activations.iterator().next();
112     assertThat(activation.getRuleUuid()).isEqualTo(rule.getUuid());
113     assertThat(activation.getSeverity()).isEqualTo("CRITICAL");
114   }
115
116   @Test
117   public void import_xml_return_messages() {
118     QProfileDto profile = createProfile();
119
120     QProfileResult result = underTest.importXml(profile, "XooProfileImporterWithMessages", toInputStream("<xml/>", UTF_8), db.getSession());
121
122     assertThat(result.infos()).containsOnly("an info");
123     assertThat(result.warnings()).containsOnly("a warning");
124   }
125
126   @Test
127   public void fail_to_import_xml_when_error_in_importer() {
128     QProfileDto qProfileDto = newQualityProfileDto();
129     InputStream inputStream = toInputStream("<xml/>", UTF_8);
130     DbSession dbSession = db.getSession();
131     assertThatThrownBy(() -> underTest.importXml(
132       qProfileDto, "XooProfileImporterWithError", inputStream, dbSession))
133         .isInstanceOf(BadRequestException.class)
134         .hasMessage("error!");
135   }
136
137   @Test
138   public void fail_to_import_xml_on_unknown_importer() {
139     QProfileDto qProfileDto = newQualityProfileDto();
140     InputStream inputStream = toInputStream("<xml/>", UTF_8);
141     DbSession dbSession = db.getSession();
142     assertThatThrownBy(() -> underTest.importXml(qProfileDto, "Unknown", inputStream, dbSession))
143       .isInstanceOf(BadRequestException.class)
144       .hasMessage("No such importer : Unknown");
145   }
146
147   @Test
148   public void export_empty_profile() {
149     QProfileDto profile = createProfile();
150
151     StringWriter writer = new StringWriter();
152     underTest.export(db.getSession(), profile, "standard", writer);
153     assertThat(writer.toString()).isEqualTo("standard -> " + profile.getName() + " -> 0");
154
155     writer = new StringWriter();
156     underTest.export(db.getSession(), profile, "xootool", writer);
157     assertThat(writer.toString()).isEqualTo("xoo -> " + profile.getName() + " -> 0");
158   }
159
160   @Test
161   public void export_profile() {
162     QProfileDto profile = createProfile();
163     db.qualityProfiles().activateRule(profile, rule);
164
165     StringWriter writer = new StringWriter();
166     underTest.export(db.getSession(), profile, "standard", writer);
167     assertThat(writer.toString()).isEqualTo("standard -> " + profile.getName() + " -> 1");
168
169     writer = new StringWriter();
170     underTest.export(db.getSession(), profile, "xootool", writer);
171     assertThat(writer.toString()).isEqualTo("xoo -> " + profile.getName() + " -> 1");
172   }
173
174   @Test
175   public void export_throws_NotFoundException_if_exporter_does_not_exist() {
176     QProfileDto profile = createProfile();
177
178     assertThatThrownBy(() -> {
179       underTest.export(db.getSession(), profile, "does_not_exist", new StringWriter());
180     })
181       .isInstanceOf(NotFoundException.class)
182       .hasMessage("Unknown quality profile exporter: does_not_exist");
183   }
184
185   private QProfileDto createProfile() {
186     return db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()));
187   }
188
189   public static class XooExporter extends ProfileExporter {
190     public XooExporter() {
191       super("xootool", "Xoo Tool");
192     }
193
194     @Override
195     public String[] getSupportedLanguages() {
196       return new String[] {"xoo"};
197     }
198
199     @Override
200     public String getMimeType() {
201       return "plain/custom";
202     }
203
204     @Override
205     public void exportProfile(RulesProfile profile, Writer writer) {
206       try {
207         writer.write("xoo -> " + profile.getName() + " -> " + profile.getActiveRules().size());
208       } catch (IOException e) {
209         throw new IllegalStateException(e);
210       }
211     }
212   }
213
214   public static class StandardExporter extends ProfileExporter {
215     public StandardExporter() {
216       super("standard", "Standard");
217     }
218
219     @Override
220     public void exportProfile(RulesProfile profile, Writer writer) {
221       try {
222         writer.write("standard -> " + profile.getName() + " -> " + profile.getActiveRules().size());
223       } catch (IOException e) {
224         throw new IllegalStateException(e);
225       }
226     }
227   }
228
229   public class XooProfileImporter extends ProfileImporter {
230     public XooProfileImporter() {
231       super("XooProfileImporter", "Xoo Profile Importer");
232     }
233
234     @Override
235     public String[] getSupportedLanguages() {
236       return new String[] {"xoo"};
237     }
238
239     @Override
240     public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
241       RulesProfile rulesProfile = RulesProfile.create();
242       rulesProfile.activateRule(Rule.create(rule.getRepositoryKey(), rule.getRuleKey()), RulePriority.CRITICAL);
243       return rulesProfile;
244     }
245   }
246
247   public static class XooProfileImporterWithMessages extends ProfileImporter {
248     public XooProfileImporterWithMessages() {
249       super("XooProfileImporterWithMessages", "Xoo Profile Importer With Message");
250     }
251
252     @Override
253     public String[] getSupportedLanguages() {
254       return new String[] {};
255     }
256
257     @Override
258     public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
259       messages.addWarningText("a warning");
260       messages.addInfoText("an info");
261       return RulesProfile.create();
262     }
263   }
264
265   public static class XooProfileImporterWithError extends ProfileImporter {
266     public XooProfileImporterWithError() {
267       super("XooProfileImporterWithError", "Xoo Profile Importer With Error");
268     }
269
270     @Override
271     public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
272       messages.addErrorText("error!");
273       return RulesProfile.create();
274     }
275   }
276
277 }