]> source.dussan.org Git - sonarqube.git/commitdiff
Fix some quality flaws
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 15 Jan 2015 15:43:07 +0000 (16:43 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 15 Jan 2015 16:35:25 +0000 (17:35 +0100)
15 files changed:
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssueHelper.java
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/package-info.java [new file with mode: 0644]
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/ReportHelper.java
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/package-info.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java
sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java
sonar-batch/src/main/java/org/sonar/batch/phases/DefaultPhaseExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorValidator.java
sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/CoverageConstants.java
sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/package-info.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/components/TimeMachineConfigurationTest.java
sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java

index d8b211eacde53a1f33cd19805e64b5e2227cf32d..576cb9105a326f60d1b872d7bd6542b06ac44b22 100644 (file)
@@ -30,6 +30,7 @@ import java.io.IOException;
 import java.io.Reader;
 import java.io.Writer;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 public class PreviousIssueHelper {
 
@@ -47,7 +48,6 @@ public class PreviousIssueHelper {
   }
 
   public <G> void streamIssues(Writer out, Iterable<G> issues, Function<G, PreviousIssue> converter) {
-    Gson gson = GsonHelper.create();
     try {
       JsonWriter writer = new JsonWriter(out);
       writer.setIndent("  ");
@@ -101,6 +101,13 @@ public class PreviousIssueHelper {
 
     @Override
     public PreviousIssue next() {
+      try {
+        if (!jsonreader.hasNext()) {
+          throw new NoSuchElementException();
+        }
+      } catch (IOException e) {
+        throw new IllegalStateException("Unable to iterate over JSON file ", e);
+      }
       return gson.fromJson(jsonreader, PreviousIssue.class);
     }
 
diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/package-info.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/package-info.java
new file mode 100644 (file)
index 0000000..b2ea9bf
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.protocol.input.issues;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
index f407a4a3f01cff29c6fc5dcaa48b127fb6df8320..3bb134df2a0491711be5beb6b7592393568e4503 100644 (file)
  */
 package org.sonar.batch.protocol.output;
 
-import org.sonar.batch.protocol.output.component.ReportComponents;
-
 import com.google.gson.Gson;
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonWriter;
+import org.apache.commons.io.Charsets;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.sonar.batch.protocol.GsonHelper;
+import org.sonar.batch.protocol.output.component.ReportComponents;
 import org.sonar.batch.protocol.output.issue.ReportIssue;
 
 import java.io.BufferedInputStream;
@@ -39,6 +39,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 public class ReportHelper {
 
@@ -71,7 +72,6 @@ public class ReportHelper {
   }
 
   public void saveIssues(long componentBatchId, Iterable<ReportIssue> issues) {
-    Gson gson = GsonHelper.create();
     File issuesFile = getIssuesFile(componentBatchId);
     try (OutputStreamWriter out = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(issuesFile)), "UTF-8")) {
 
@@ -127,7 +127,7 @@ public class ReportHelper {
 
     public ReportIssueIterator(File issuesFile) {
       try {
-        reader = new JsonReader(new InputStreamReader(new BufferedInputStream(new FileInputStream(issuesFile))));
+        reader = new JsonReader(new InputStreamReader(new BufferedInputStream(new FileInputStream(issuesFile)), Charsets.UTF_8));
         reader.beginArray();
       } catch (IOException e) {
         throw new IllegalStateException("Unable to read " + issuesFile, e);
@@ -151,6 +151,13 @@ public class ReportHelper {
 
     @Override
     public ReportIssue next() {
+      try {
+        if (!reader.hasNext()) {
+          throw new NoSuchElementException();
+        }
+      } catch (IOException e) {
+        throw new IllegalStateException("Unable to iterate over JSON file ", e);
+      }
       return gson.fromJson(reader, ReportIssue.class);
     }
 
diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/package-info.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/package-info.java
new file mode 100644 (file)
index 0000000..a976368
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.protocol.output;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
index 6baa999b22f756673bb64bf08cf118df75e32bea..09968ee9426bb98aec52a040f0efd57d0f9f6e73 100644 (file)
@@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchExtension;
 import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Qualifiers;
 
 import javax.annotation.CheckForNull;
@@ -39,15 +38,13 @@ public class TimeMachineConfiguration implements BatchExtension {
   private static final Logger LOG = LoggerFactory.getLogger(TimeMachineConfiguration.class);
 
   private final DatabaseSession session;
-  private Project project;
   private final PeriodsDefinition periodsDefinition;
 
   private List<Period> periods;
   private List<PastSnapshot> modulePastSnapshots;
 
-  public TimeMachineConfiguration(DatabaseSession session, Project project, PeriodsDefinition periodsDefinition) {
+  public TimeMachineConfiguration(DatabaseSession session, PeriodsDefinition periodsDefinition) {
     this.session = session;
-    this.project = project;
     this.periodsDefinition = periodsDefinition;
     initModulePastSnapshots();
   }
index 4ed133f21a36e939deaaead85cb62a752d212ea7..bcfe06d3516743562b1ee5ea87bf0fbfebd21e05 100644 (file)
@@ -93,10 +93,14 @@ public class ResourcePersister implements ScanPersister {
       return;
     }
     BatchResource parentBatchResource = batchResource.parent();
+    Snapshot s;
     if (parentBatchResource != null) {
       persist(parentBatchResource);
+      s = persist(findModule(parentBatchResource), batchResource.resource(), parentBatchResource.resource());
+    } else {
+      // Root project
+      s = persistProject((Project) batchResource.resource(), null);
     }
-    Snapshot s = persist(findParentModule(batchResource), batchResource.resource(), parentBatchResource != null ? parentBatchResource.resource() : null);
     batchResource.setSnapshot(s);
     if (ResourceUtils.isPersistable(batchResource.resource())) {
       graph.addComponent(batchResource.resource(), batchResource.snapshotId());
@@ -104,15 +108,12 @@ public class ResourcePersister implements ScanPersister {
   }
 
   @CheckForNull
-  private Project findParentModule(BatchResource batchResource) {
-    if (batchResource != null && batchResource.parent() != null) {
-      if (batchResource.parent().resource() instanceof Project) {
-        return (Project) batchResource.parent().resource();
-      } else {
-        return findParentModule(batchResource.parent());
-      }
+  private Project findModule(BatchResource batchResource) {
+    if (batchResource.resource() instanceof Project) {
+      return (Project) batchResource.resource();
+    } else {
+      return findModule(batchResource.parent());
     }
-    return null;
   }
 
   private Snapshot persistProject(Project project, @Nullable Project parent) {
@@ -158,10 +159,6 @@ public class ResourcePersister implements ScanPersister {
     if (resource instanceof Project) {
       // should not occur, please use the method saveProject()
       snapshot = persistProject((Project) resource, (Project) parent);
-
-    } else if (resource instanceof Library) {
-      snapshot = persistLibrary(project.getAnalysisDate(), (Library) resource);
-
     } else {
       snapshot = persistFileOrDirectory(project, resource, parent);
     }
@@ -169,7 +166,7 @@ public class ResourcePersister implements ScanPersister {
     return snapshot;
   }
 
-  private Snapshot persistLibrary(Date analysisDate, Library library) {
+  Snapshot persistLibrary(Date analysisDate, Library library) {
     ResourceModel model = findOrCreateModel(library, null);
     model = session.save(model);
     // TODO to be removed
index a9a45a592e706f5c641012a1c4d546c3d87e7e1d..f57d09158cd83790cac57d5aef3552bd3635ab7b 100644 (file)
@@ -46,7 +46,7 @@ import java.util.List;
 
 public final class DefaultPhaseExecutor implements PhaseExecutor {
 
-  public static final Logger LOGGER = LoggerFactory.getLogger(DefaultPhaseExecutor.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPhaseExecutor.class);
 
   private final EventBus eventBus;
   private final Phases phases;
index 1e8dde4fc8bb3098482bd05df885af6d608ce555..c3fec8e89c3fbb9f6aa60500ef5adf2dfb52eb96 100644 (file)
@@ -23,7 +23,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.resources.Project;
-import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.events.BatchStepEvent;
 import org.sonar.batch.events.EventBus;
 import org.sonar.batch.index.DefaultIndex;
@@ -36,7 +35,7 @@ import org.sonar.batch.scan.report.JsonReport;
 
 public final class PreviewPhaseExecutor implements PhaseExecutor {
 
-  public static final Logger LOGGER = LoggerFactory.getLogger(PreviewPhaseExecutor.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(PreviewPhaseExecutor.class);
 
   private final EventBus eventBus;
   private final Phases phases;
@@ -50,7 +49,6 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
   private final DefaultModuleFileSystem fs;
   private final QProfileVerifier profileVerifier;
   private final IssueExclusionsLoader issueExclusionsLoader;
-  private final AnalysisMode analysisMode;
   private final JsonReport jsonReport;
 
   public PreviewPhaseExecutor(Phases phases,
@@ -58,7 +56,7 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
     SensorsExecutor sensorsExecutor,
     SensorContext sensorContext, DefaultIndex index,
     EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, JsonReport jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
-    IssueExclusionsLoader issueExclusionsLoader, AnalysisMode analysisMode) {
+    IssueExclusionsLoader issueExclusionsLoader) {
     this.phases = phases;
     this.mavenPluginsConfigurator = mavenPluginsConfigurator;
     this.initializersExecutor = initializersExecutor;
@@ -72,7 +70,6 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
     this.fs = fs;
     this.profileVerifier = profileVerifier;
     this.issueExclusionsLoader = issueExclusionsLoader;
-    this.analysisMode = analysisMode;
   }
 
   /**
index 75faa1d074b4cbf98476f76bc2b00892253aa809..d92dc698bea189cf872cffa937fb48dabdaea9ae 100644 (file)
@@ -76,12 +76,10 @@ public class ProjectReactorValidator {
   }
 
   private void preventAutomaticProjectCreationIfNeeded(ProjectReactor reactor) {
-    if (resourceDao != null) {
-      if (settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) {
-        String projectKey = reactor.getRoot().getKeyWithBranch();
-        if (resourceDao.findByKey(projectKey) == null) {
-          throw new SonarException(String.format("Unable to scan non-existing project \"%s\"", projectKey));
-        }
+    if (resourceDao != null && settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) {
+      String projectKey = reactor.getRoot().getKeyWithBranch();
+      if (resourceDao.findByKey(projectKey) == null) {
+        throw new SonarException(String.format("Unable to scan non-existing project \"%s\"", projectKey));
       }
     }
   }
index 7fc54122dc9d7e38a4c396d21b304dcb91c7d67c..8bb5a91081f5f987343394eb169edd14f4cabd09 100644 (file)
@@ -37,7 +37,7 @@ class MeasureValueCoder implements ValueCoder {
   private final MetricFinder metricFinder;
   private final TechnicalDebtModel techDebtModel;
 
-  public MeasureValueCoder(MetricFinder metricFinder, TechnicalDebtModel techDebtModel) {
+  public MeasureValueCoder(MetricFinder metricFinder, @Nullable TechnicalDebtModel techDebtModel) {
     this.metricFinder = metricFinder;
     this.techDebtModel = techDebtModel;
   }
index c1c3e2ba38422256e2b2f9068d89a54f8d080a6d..30639a31553eb19d7f24d0169c6eb666373dc756 100644 (file)
@@ -95,14 +95,15 @@ public class DefaultSensorStorage implements SensorStorage {
     org.sonar.api.measures.Measure measureToSave = new org.sonar.api.measures.Measure(m);
     setValueAccordingToMetricType(newMeasure, m, measureToSave);
     measureToSave.setFromCore(measure.isFromCore());
-    if (newMeasure.inputFile() != null) {
+    InputFile inputFile = newMeasure.inputFile();
+    if (inputFile != null) {
       Formula formula = newMeasure.metric() instanceof org.sonar.api.measures.Metric ?
         ((org.sonar.api.measures.Metric) newMeasure.metric()).getFormula() : null;
       if (formula instanceof SumChildDistributionFormula
         && !Scopes.isHigherThanOrEquals(Scopes.FILE, ((SumChildDistributionFormula) formula).getMinimumScopeToPersist())) {
         measureToSave.setPersistenceMode(PersistenceMode.MEMORY);
       }
-      File sonarFile = getFile(newMeasure.inputFile());
+      File sonarFile = getFile(inputFile);
       if (coverageExclusions.accept(sonarFile, measureToSave)) {
         sonarIndex.addMeasure(sonarFile, measureToSave);
       }
index 46aa7173716e3b39395342d778827d7c71f2801a..02d5d049f7c1910e48350e91152f157d7f49e4d6 100644 (file)
@@ -27,6 +27,9 @@ import java.util.Collection;
 
 public class CoverageConstants {
 
+  private CoverageConstants() {
+  }
+
   public static final Collection<Metric> COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER,
     CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS,
     CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/package-info.java
new file mode 100644 (file)
index 0000000..6017283
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.sensor.coverage;
index 13fba27e2ea0f513df58030aab2fb3519a94e01c..023690acdbdab82be52316c9c19938e4924ca4d1 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.batch.components;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
 
 import java.util.Date;
@@ -51,7 +50,7 @@ public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase {
 
     when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot));
 
-    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), (Project) new Project("my:project"), periodsDefinition);
+    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition);
     assertThat(timeMachineConfiguration.periods()).hasSize(1);
     assertThat(timeMachineConfiguration.periods().get(0).getDate()).isNotNull();
     assertThat(timeMachineConfiguration.getProjectPastSnapshots()).hasSize(1);
@@ -67,7 +66,7 @@ public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase {
 
     when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot));
 
-    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), (Project) new Project("my:module"), periodsDefinition);
+    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition);
     assertThat(timeMachineConfiguration.periods()).hasSize(1);
     assertThat(timeMachineConfiguration.periods().get(0).getDate()).isNotNull();
     assertThat(timeMachineConfiguration.getProjectPastSnapshots()).hasSize(1);
@@ -86,7 +85,7 @@ public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase {
 
     when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot));
 
-    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), (Project) new Project("my:project").setId(1), periodsDefinition);
+    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition);
     assertThat(timeMachineConfiguration.getProjectPastSnapshots()).hasSize(1);
     assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getProjectSnapshot().getId()).isEqualTo(1010);
     assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getIndex()).isEqualTo(1);
@@ -103,7 +102,7 @@ public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase {
 
     when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot));
 
-    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), new Project("my:project"), periodsDefinition);
+    TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition);
     assertThat(timeMachineConfiguration.periods()).hasSize(1);
     assertThat(timeMachineConfiguration.periods().get(0).getDate()).isNull();
   }
index f64ff958846b4297eb3b0548e467b79314a4da61..6ec57439787bbf5f5b477f672e7befb01461a63f 100644 (file)
@@ -322,10 +322,12 @@ public class ResourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
 
     persister.persist(null, singleProject, null);
-    persister.persist(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"), null);
-    persister.persist(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"), null);// do nothing, already
-                                                                                                               // saved
-    persister.persist(singleProject, new Library("junit:junit", "3.2").setEffectiveKey("junit:junit"), null);
+    persister.persistLibrary(singleProject.getAnalysisDate(), (Library) new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));
+    persister.persistLibrary(singleProject.getAnalysisDate(), (Library) new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));// do
+    // nothing,
+    // already
+    // saved
+    persister.persistLibrary(singleProject.getAnalysisDate(), (Library) new Library("junit:junit", "3.2").setEffectiveKey("junit:junit"));
 
     checkTables("shouldSaveNewLibrary", new String[] {"build_date", "created_at", "authorization_updated_at", "uuid", "project_uuid", "module_uuid", "module_uuid_path"},
       "projects", "snapshots");