- define index and check the 3 use cases - define batch report format - create file_sources.test_datatags/5.2-RC1
@@ -20,9 +20,8 @@ | |||
package org.sonar.server.activity.index; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.elasticsearch.cluster.metadata.IndexMetaData; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.process.ProcessProperties; | |||
import org.sonar.server.es.EsUtils; | |||
import org.sonar.server.es.IndexDefinition; | |||
import org.sonar.server.es.NewIndex; | |||
@@ -50,16 +49,9 @@ public class ActivityIndexDefinition implements IndexDefinition { | |||
@Override | |||
public void define(IndexDefinitionContext context) { | |||
NewIndex index = context.create(INDEX); | |||
index.getSettings().put("index.refresh_interval", "-1"); | |||
index.getSettings().put("analysis.analyzer.default.type", "keyword"); | |||
// shards | |||
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE); | |||
if (clusterMode) { | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4); | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1); | |||
// else keep defaults (one shard) | |||
} | |||
EsUtils.refreshHandledByIndexer(index); | |||
EsUtils.setShards(index, settings); | |||
// type "activity" | |||
NewIndex.NewIndexType mapping = index.createType(TYPE); |
@@ -28,7 +28,7 @@ public abstract class BaseIndex implements ServerComponent { | |||
this.client = client; | |||
} | |||
public EsClient getClient() { | |||
protected EsClient getClient() { | |||
return client; | |||
} | |||
@@ -21,10 +21,13 @@ package org.sonar.server.es; | |||
import com.google.common.base.Function; | |||
import com.google.common.collect.Lists; | |||
import org.elasticsearch.cluster.metadata.IndexMetaData; | |||
import org.elasticsearch.common.joda.time.format.ISODateTimeFormat; | |||
import org.elasticsearch.search.SearchHit; | |||
import org.elasticsearch.search.SearchHits; | |||
import org.elasticsearch.search.aggregations.bucket.terms.Terms; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.process.ProcessProperties; | |||
import org.sonar.server.search.BaseDoc; | |||
import javax.annotation.CheckForNull; | |||
@@ -79,4 +82,17 @@ public class EsUtils { | |||
} | |||
return null; | |||
} | |||
public static void setShards(NewIndex index, Settings settings) { | |||
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE); | |||
if (clusterMode) { | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4); | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1); | |||
// else keep defaults (one shard) | |||
} | |||
} | |||
public static void refreshHandledByIndexer(NewIndex index) { | |||
index.getSettings().put("index.refresh_interval", "-1"); | |||
} | |||
} |
@@ -27,7 +27,6 @@ import org.elasticsearch.common.settings.ImmutableSettings; | |||
import org.sonar.server.search.IndexField; | |||
import javax.annotation.CheckForNull; | |||
import java.util.Map; | |||
import java.util.SortedMap; | |||
import java.util.TreeMap; | |||
@@ -72,6 +71,10 @@ public class NewIndex { | |||
return new StringFieldBuilder(this, fieldName); | |||
} | |||
public NestedObjectBuilder nestedObjectBuilder(String fieldName, NewIndexType nestedMapping) { | |||
return new NestedObjectBuilder(this, nestedMapping, fieldName); | |||
} | |||
public NewIndexType createBooleanField(String fieldName) { | |||
return setProperty(fieldName, ImmutableMap.of("type", "boolean")); | |||
} | |||
@@ -97,7 +100,7 @@ public class NewIndex { | |||
} | |||
public NewIndexType createDynamicNestedField(String fieldName) { | |||
return setProperty(fieldName, ImmutableMap.of("type", "nested", "dynamic", "true")); | |||
return setProperty(fieldName, ImmutableMap.of("type", "nested", "dynamic", "true", "include_in_parent", "true")); | |||
} | |||
public NewIndexType createShortField(String fieldName) { | |||
@@ -121,6 +124,33 @@ public class NewIndex { | |||
} | |||
} | |||
public static class NestedObjectBuilder { | |||
private final NewIndexType indexType; | |||
private final NewIndexType nestedType; | |||
private final String fieldName; | |||
private boolean dynamic = false; | |||
public NestedObjectBuilder(NewIndexType indexType, NewIndexType nestedType, String fieldName) { | |||
this.indexType = indexType; | |||
this.nestedType = nestedType; | |||
this.fieldName = fieldName; | |||
} | |||
public NestedObjectBuilder dynamic() { | |||
this.dynamic = true; | |||
return this; | |||
} | |||
public void build() { | |||
if (dynamic) { | |||
indexType.setProperty(fieldName, ImmutableMap.of("type", "nested", "dynamic", "true")); | |||
} else { | |||
nestedType.setAttribute("type", "nested"); | |||
indexType.setProperty(fieldName, nestedType.attributes); | |||
} | |||
} | |||
} | |||
/** | |||
* Helper to define a string field in mapping of index type | |||
*/ |
@@ -20,9 +20,8 @@ | |||
package org.sonar.server.issue.index; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.elasticsearch.cluster.metadata.IndexMetaData; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.process.ProcessProperties; | |||
import org.sonar.server.es.EsUtils; | |||
import org.sonar.server.es.IndexDefinition; | |||
import org.sonar.server.es.NewIndex; | |||
@@ -93,16 +92,8 @@ public class IssueIndexDefinition implements IndexDefinition { | |||
public void define(IndexDefinitionContext context) { | |||
NewIndex index = context.create(INDEX); | |||
// refresh is handled by IssueIndexer | |||
index.getSettings().put("index.refresh_interval", "-1"); | |||
// shards | |||
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE); | |||
if (clusterMode) { | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4); | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1); | |||
// else keep defaults (one shard) | |||
} | |||
EsUtils.refreshHandledByIndexer(index); | |||
EsUtils.setShards(index, settings); | |||
// type "authorization" | |||
NewIndex.NewIndexType authorizationMapping = index.createType(TYPE_AUTHORIZATION); |
@@ -20,9 +20,8 @@ | |||
package org.sonar.server.source.index; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.elasticsearch.cluster.metadata.IndexMetaData; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.process.ProcessProperties; | |||
import org.sonar.server.es.EsUtils; | |||
import org.sonar.server.es.IndexDefinition; | |||
import org.sonar.server.es.NewIndex; | |||
@@ -61,16 +60,8 @@ public class SourceLineIndexDefinition implements IndexDefinition { | |||
public void define(IndexDefinitionContext context) { | |||
NewIndex index = context.create(INDEX); | |||
// refresh is always handled by SourceLineIndexer | |||
index.getSettings().put("index.refresh_interval", "-1"); | |||
// shards | |||
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE); | |||
if (clusterMode) { | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4); | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1); | |||
// else keep defaults (one shard) | |||
} | |||
EsUtils.refreshHandledByIndexer(index); | |||
EsUtils.setShards(index, settings); | |||
// type "sourceline" | |||
NewIndex.NewIndexType mapping = index.createType(TYPE); |
@@ -0,0 +1,105 @@ | |||
/* | |||
* 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. | |||
*/ | |||
package org.sonar.server.test.index; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Maps; | |||
import org.sonar.server.search.BaseDoc; | |||
import java.util.List; | |||
import java.util.Map; | |||
import static org.sonar.server.test.index.TestIndexDefinition.*; | |||
public class TestDoc extends BaseDoc { | |||
public TestDoc(Map<String, Object> fields) { | |||
super(fields); | |||
} | |||
@VisibleForTesting | |||
TestDoc() { | |||
super(Maps.<String, Object>newHashMapWithExpectedSize(7)); | |||
} | |||
public String uuid() { | |||
return getField(FIELD_UUID); | |||
} | |||
public TestDoc setUuid(String uuid) { | |||
setField(FIELD_UUID, uuid); | |||
return this; | |||
} | |||
public String name() { | |||
return getField(FIELD_NAME); | |||
} | |||
public TestDoc setName(String name) { | |||
setField(FIELD_NAME, name); | |||
return this; | |||
} | |||
public String status() { | |||
return getField(FIELD_STATUS); | |||
} | |||
public TestDoc setStatus(String status) { | |||
setField(FIELD_STATUS, status); | |||
return this; | |||
} | |||
public String message() { | |||
return getField(FIELD_MESSAGE); | |||
} | |||
public TestDoc setMessage(String message) { | |||
setField(FIELD_MESSAGE, message); | |||
return this; | |||
} | |||
public String stackTrace() { | |||
return getField(FIELD_STACKTRACE); | |||
} | |||
public TestDoc setStackTrace(String stackTrace) { | |||
setField(FIELD_STACKTRACE, stackTrace); | |||
return this; | |||
} | |||
public String type() { | |||
return getField(FIELD_TYPE); | |||
} | |||
public TestDoc setType(String type) { | |||
setField(FIELD_TYPE, type); | |||
return this; | |||
} | |||
// TODO TBE - it should be a CoverageBlockDoc list | |||
public List<Map<String, Object>> coverageBlocks() { | |||
return getField(FIELD_COVERAGE_BLOCKS); | |||
} | |||
public TestDoc setCoverageBlocks(List<Map<String, Object>> coverageBlocks) { | |||
setField(FIELD_COVERAGE_BLOCKS, coverageBlocks); | |||
return this; | |||
} | |||
} |
@@ -0,0 +1,85 @@ | |||
/* | |||
* 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. | |||
*/ | |||
package org.sonar.server.test.index; | |||
import org.elasticsearch.index.query.FilterBuilders; | |||
import org.elasticsearch.index.query.QueryBuilders; | |||
import org.elasticsearch.search.SearchHit; | |||
import org.sonar.server.es.BaseIndex; | |||
import org.sonar.server.es.EsClient; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import static org.sonar.server.test.index.TestIndexDefinition.*; | |||
public class TestIndex extends BaseIndex { | |||
public TestIndex(EsClient client) { | |||
super(client); | |||
} | |||
public List<Map<String, Object>> coveredLines(String testFileUuid, String methodName) { | |||
List<Map<String, Object>> coverageBlocks = new ArrayList<>(); | |||
for (SearchHit hit : getClient().prepareSearch(TestIndexDefinition.INDEX) | |||
.setTypes(TestIndexDefinition.TYPE) | |||
.setSize(1) | |||
.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), FilterBuilders.boolFilter() | |||
.must(FilterBuilders.termFilter(FIELD_UUID, testFileUuid).cache(false)) | |||
.must(FilterBuilders.termFilter(TestIndexDefinition.FIELD_NAME, methodName).cache(false)))) | |||
.get().getHits().getHits()) { | |||
coverageBlocks.addAll(new TestDoc(hit.sourceAsMap()).coverageBlocks()); | |||
} | |||
return coverageBlocks; | |||
} | |||
public List<TestDoc> testMethods(String testFileUuid) { | |||
List<TestDoc> testDocs = new ArrayList<>(); | |||
for (SearchHit hit : getClient().prepareSearch(TestIndexDefinition.INDEX) | |||
.setTypes(TestIndexDefinition.TYPE) | |||
.setSize(10_000) | |||
.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), FilterBuilders.termFilter(FIELD_UUID, testFileUuid))) | |||
.get().getHits().getHits()) { | |||
testDocs.add(new TestDoc(hit.sourceAsMap())); | |||
} | |||
return testDocs; | |||
} | |||
public List<TestDoc> testsCovering(String mainFileUuid, int line) { | |||
List<TestDoc> testDocs = new ArrayList<>(); | |||
for (SearchHit hit : getClient().prepareSearch(TestIndexDefinition.INDEX) | |||
.setTypes(TestIndexDefinition.TYPE) | |||
.setSize(10_000) | |||
.setQuery(QueryBuilders.nestedQuery(FIELD_COVERAGE_BLOCKS, FilterBuilders.boolFilter() | |||
.must(FilterBuilders.termFilter(FIELD_COVERAGE_BLOCKS + "." + FIELD_COVERAGE_BLOCK_UUID, mainFileUuid).cache(false)) | |||
.must(FilterBuilders.termFilter(FIELD_COVERAGE_BLOCKS + "." + FIELD_COVERAGE_BLOCK_LINES, line).cache(false)))) | |||
.get().getHits().getHits()) { | |||
testDocs.add(new TestDoc(hit.sourceAsMap())); | |||
} | |||
return testDocs; | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
/* | |||
* 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. | |||
*/ | |||
package org.sonar.server.test.index; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.server.es.EsUtils; | |||
import org.sonar.server.es.IndexDefinition; | |||
import org.sonar.server.es.NewIndex; | |||
public class TestIndexDefinition implements IndexDefinition { | |||
public static final String INDEX = "tests"; | |||
public static final String TYPE = "test"; | |||
public static final String FIELD_UUID = "uuid"; | |||
public static final String FIELD_NAME = "name"; | |||
public static final String FIELD_STATUS = "status"; | |||
public static final String FIELD_MESSAGE = "message"; | |||
public static final String FIELD_STACKTRACE = "stacktrace"; | |||
public static final String FIELD_TYPE = "type"; | |||
public static final String FIELD_COVERAGE_BLOCKS = "coverageBlocks"; | |||
public static final String FIELD_COVERAGE_BLOCK_UUID = "uuid"; | |||
public static final String FIELD_COVERAGE_BLOCK_KEY = "key"; | |||
public static final String FIELD_COVERAGE_BLOCK_LINES = "lines"; | |||
public static final String FIELD_COVERAGE_BLOCK_COVERED_LINES = "coveredLines"; | |||
private final Settings settings; | |||
public TestIndexDefinition(Settings settings) { | |||
this.settings = settings; | |||
} | |||
@Override | |||
public void define(IndexDefinitionContext context) { | |||
NewIndex index = context.create(INDEX); | |||
EsUtils.refreshHandledByIndexer(index); | |||
EsUtils.setShards(index, settings); | |||
NewIndex.NewIndexType nestedMapping = index.createType(TYPE); | |||
nestedMapping.stringFieldBuilder(FIELD_COVERAGE_BLOCK_KEY).build(); | |||
nestedMapping.stringFieldBuilder(FIELD_COVERAGE_BLOCK_UUID).build(); | |||
nestedMapping.createIntegerField(FIELD_COVERAGE_BLOCK_LINES); | |||
nestedMapping.createIntegerField(FIELD_COVERAGE_BLOCK_COVERED_LINES); | |||
NewIndex.NewIndexType mapping = index.createType(TYPE); | |||
mapping.stringFieldBuilder(FIELD_UUID).build(); | |||
mapping.stringFieldBuilder(FIELD_NAME).build(); | |||
mapping.stringFieldBuilder(FIELD_STATUS).disableSearch().build(); | |||
mapping.stringFieldBuilder(FIELD_MESSAGE).disableSearch().build(); | |||
mapping.stringFieldBuilder(FIELD_STACKTRACE).disableSearch().build(); | |||
mapping.stringFieldBuilder(FIELD_TYPE).disableSearch().build(); | |||
mapping.nestedObjectBuilder(FIELD_COVERAGE_BLOCKS, nestedMapping).build(); | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
/* | |||
* 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.server.test.index; | |||
import javax.annotation.ParametersAreNonnullByDefault; | |||
@@ -20,9 +20,8 @@ | |||
package org.sonar.server.user.index; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.elasticsearch.cluster.metadata.IndexMetaData; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.process.ProcessProperties; | |||
import org.sonar.server.es.EsUtils; | |||
import org.sonar.server.es.IndexDefinition; | |||
import org.sonar.server.es.NewIndex; | |||
@@ -53,13 +52,7 @@ public class UserIndexDefinition implements IndexDefinition { | |||
public void define(IndexDefinitionContext context) { | |||
NewIndex index = context.create(INDEX); | |||
// shards | |||
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE); | |||
if (clusterMode) { | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4); | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1); | |||
// else keep defaults (one shard) | |||
} | |||
EsUtils.setShards(index, settings); | |||
// type "user" | |||
NewIndex.NewIndexType mapping = index.createType(TYPE_USER); |
@@ -21,9 +21,8 @@ | |||
package org.sonar.server.view.index; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.elasticsearch.cluster.metadata.IndexMetaData; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.process.ProcessProperties; | |||
import org.sonar.server.es.EsUtils; | |||
import org.sonar.server.es.IndexDefinition; | |||
import org.sonar.server.es.NewIndex; | |||
@@ -49,13 +48,7 @@ public class ViewIndexDefinition implements IndexDefinition { | |||
public void define(IndexDefinitionContext context) { | |||
NewIndex index = context.create(INDEX); | |||
// shards | |||
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE); | |||
if (clusterMode) { | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4); | |||
index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1); | |||
// else keep defaults (one shard) | |||
} | |||
EsUtils.setShards(index, settings); | |||
// type "view" | |||
NewIndex.NewIndexType mapping = index.createType(TYPE_VIEW); |
@@ -0,0 +1,104 @@ | |||
/* | |||
* 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. | |||
*/ | |||
package org.sonar.server.test.index; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.server.es.EsTester; | |||
import java.util.*; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class TestIndexTest { | |||
@ClassRule | |||
public static EsTester es = new EsTester().addDefinitions(new TestIndexDefinition(new Settings())); | |||
TestIndex sut = new TestIndex(es.client()); | |||
@Before | |||
public void before() throws Exception { | |||
es.truncateIndices(); | |||
} | |||
@Test | |||
public void lines_covered_a_test_method() throws Exception { | |||
es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, | |||
newTestDoc("1", newCoverageBlock("3"), newCoverageBlock("4"), newCoverageBlock("5")), | |||
newTestDoc("2", newCoverageBlock("5"), newCoverageBlock("6"), newCoverageBlock("7"))); | |||
List<Map<String, Object>> result = sut.coveredLines("uuid-1", "name-1"); | |||
assertThat(result).hasSize(3); | |||
assertThat(result.get(0).get("uuid")).isEqualTo("main-uuid-3"); | |||
assertThat((List<Integer>)result.get(0).get("lines")).containsOnly(25, 33, 82); | |||
} | |||
@Test | |||
public void test_methods() throws Exception { | |||
es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, | |||
newTestDoc("1", newCoverageBlock("3"), newCoverageBlock("4"), newCoverageBlock("5")), | |||
newTestDoc("1", newCoverageBlock("5"), newCoverageBlock("6"), newCoverageBlock("7"))); | |||
List<TestDoc> result = sut.testMethods("uuid-1"); | |||
assertThat(result).hasSize(2); | |||
} | |||
@Test | |||
public void test_covering() throws Exception { | |||
List<Map<String, Object>> coverageBlocks = new ArrayList<>(); | |||
coverageBlocks.add(newCoverageBlock("1")); | |||
coverageBlocks.add(newCoverageBlock("2")); | |||
coverageBlocks.add(newCoverageBlock("3")); | |||
es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, | |||
newTestDoc("1", newCoverageBlock("3"), newCoverageBlock("4"), newCoverageBlock("5")), | |||
newTestDoc("1", newCoverageBlock("5"), newCoverageBlock("6"), newCoverageBlock("7"))); | |||
List<TestDoc> result = sut.testsCovering("main-uuid-5", 82); | |||
assertThat(result).hasSize(2); | |||
assertThat(result.get(0).name()).isEqualTo("name-1"); | |||
assertThat(result.get(0).coverageBlocks().get(0).get("uuid")).isEqualTo("main-uuid-3"); | |||
} | |||
private Map<String, Object> newCoverageBlock(String id) { | |||
Map<String, Object> coverageBlock = new HashMap<>(); | |||
coverageBlock.put("key", "project:file-" + id); | |||
coverageBlock.put("uuid", "main-uuid-" + id); | |||
coverageBlock.put("lines", Arrays.asList(25, 33, 82)); | |||
return coverageBlock; | |||
} | |||
private TestDoc newTestDoc(String id, Map<String, Object>... coverageBlocks) { | |||
return new TestDoc() | |||
.setName("name-" + id) | |||
.setMessage("message-" + id) | |||
.setStackTrace("stacktrace-" + id) | |||
.setStatus("status-" + id) | |||
.setType("type-" + id) | |||
.setUuid("uuid-" + id) | |||
.setCoverageBlocks(Arrays.asList(coverageBlocks)); | |||
} | |||
} |
@@ -21,6 +21,7 @@ | |||
<file_sources id="101" project_uuid="ABCD" file_uuid="EFGHI" | |||
binary_data=",,,,,,,,,,,,,,,unchanged ,,,,,,,,,,,,,,,content " | |||
test_data="[null]" | |||
line_hashes="lineEFGHI" | |||
data_hash="dataEFGHI" | |||
src_hash="srcEFGHI" | |||
@@ -48,6 +49,7 @@ | |||
<file_sources id="102" project_uuid="ABCD" file_uuid="HIJK" | |||
binary_data=",,,,,,,,,,,,,,,unchanged ,,,,,,,,,,,,,,,content " | |||
test_data="[null]" | |||
line_hashes="lineHIJK" | |||
data_hash="dataHIJK" | |||
src_hash="srcHIJK" |
@@ -6,6 +6,7 @@ | |||
--> | |||
<file_sources id="1" file_uuid="FILE_A" project_uuid="PROJECT_A" | |||
binary_data="" | |||
test_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" |
@@ -2,6 +2,7 @@ | |||
<file_sources id="101" project_uuid="ABCD" file_uuid="FILE1_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="1500000000002"/> | |||
</dataset> |
@@ -2,6 +2,7 @@ | |||
<file_sources id="101" project_uuid="ABCD" file_uuid="FILE1_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="0"/> | |||
</dataset> |
@@ -4,6 +4,7 @@ CREATE TABLE "FILE_SOURCES" ( | |||
"PROJECT_UUID" VARCHAR(50) NOT NULL, | |||
"FILE_UUID" VARCHAR(50) NOT NULL, | |||
"BINARY_DATA" BINARY(167772150), | |||
"TEST_DATA" BINARY(167772150), | |||
"DATA_HASH" VARCHAR(50) NOT NULL, | |||
"CREATED_AT" BIGINT NOT NULL, | |||
"UPDATED_AT" BIGINT NOT NULL |
@@ -1,6 +1,6 @@ | |||
<dataset> | |||
<file_sources id="1" project_uuid="P1" file_uuid="F1" created_at="1416238020000" updated_at="1416239042000" | |||
binary_data="" data_hash="" /> | |||
binary_data="" test_data="[null]" data_hash="" /> | |||
</dataset> |
@@ -1,6 +1,6 @@ | |||
<dataset> | |||
<file_sources id="1" project_uuid="PROJECT_UUID" file_uuid="FILE_UUID" created_at="1416238020000" updated_at="1416239042000" | |||
binary_data="" data_hash="DATA_HASH" /> | |||
binary_data="" test_data="[null]" data_hash="DATA_HASH" /> | |||
</dataset> |
@@ -6,6 +6,7 @@ | |||
<file_sources id="101" project_uuid="ABCD" file_uuid="CDEF" | |||
binary_data="" data_hash="hash" | |||
test_data="[null]" | |||
line_hashes="987654" | |||
src_hash="12345" | |||
created_at="1414597442000" updated_at="1414683842000"/> |
@@ -0,0 +1,31 @@ | |||
# | |||
# 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. | |||
# | |||
# | |||
# SonarQube 5.2 | |||
# SONAR-6255 | |||
# | |||
class AddFileSourcesTestData < ActiveRecord::Migration | |||
def self.up | |||
add_column 'file_sources', 'test_data', :binary, :null => true | |||
end | |||
end |
@@ -684,6 +684,188 @@ public final class Constants { | |||
// @@protoc_insertion_point(enum_scope:HighlightingType) | |||
} | |||
/** | |||
* Protobuf enum {@code TestType} | |||
*/ | |||
public enum TestType | |||
implements com.google.protobuf.ProtocolMessageEnum { | |||
/** | |||
* <code>UT = 1;</code> | |||
*/ | |||
UT(0, 1), | |||
/** | |||
* <code>IT = 2;</code> | |||
*/ | |||
IT(1, 2), | |||
; | |||
/** | |||
* <code>UT = 1;</code> | |||
*/ | |||
public static final int UT_VALUE = 1; | |||
/** | |||
* <code>IT = 2;</code> | |||
*/ | |||
public static final int IT_VALUE = 2; | |||
public final int getNumber() { return value; } | |||
public static TestType valueOf(int value) { | |||
switch (value) { | |||
case 1: return UT; | |||
case 2: return IT; | |||
default: return null; | |||
} | |||
} | |||
public static com.google.protobuf.Internal.EnumLiteMap<TestType> | |||
internalGetValueMap() { | |||
return internalValueMap; | |||
} | |||
private static com.google.protobuf.Internal.EnumLiteMap<TestType> | |||
internalValueMap = | |||
new com.google.protobuf.Internal.EnumLiteMap<TestType>() { | |||
public TestType findValueByNumber(int number) { | |||
return TestType.valueOf(number); | |||
} | |||
}; | |||
public final com.google.protobuf.Descriptors.EnumValueDescriptor | |||
getValueDescriptor() { | |||
return getDescriptor().getValues().get(index); | |||
} | |||
public final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptorForType() { | |||
return getDescriptor(); | |||
} | |||
public static final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptor() { | |||
return org.sonar.batch.protocol.Constants.getDescriptor().getEnumTypes().get(6); | |||
} | |||
private static final TestType[] VALUES = values(); | |||
public static TestType valueOf( | |||
com.google.protobuf.Descriptors.EnumValueDescriptor desc) { | |||
if (desc.getType() != getDescriptor()) { | |||
throw new java.lang.IllegalArgumentException( | |||
"EnumValueDescriptor is not for this type."); | |||
} | |||
return VALUES[desc.getIndex()]; | |||
} | |||
private final int index; | |||
private final int value; | |||
private TestType(int index, int value) { | |||
this.index = index; | |||
this.value = value; | |||
} | |||
// @@protoc_insertion_point(enum_scope:TestType) | |||
} | |||
/** | |||
* Protobuf enum {@code TestResultStatus} | |||
*/ | |||
public enum TestResultStatus | |||
implements com.google.protobuf.ProtocolMessageEnum { | |||
/** | |||
* <code>OK = 1;</code> | |||
*/ | |||
OK(0, 1), | |||
/** | |||
* <code>FAILURE = 2;</code> | |||
*/ | |||
FAILURE(1, 2), | |||
/** | |||
* <code>ERROR = 3;</code> | |||
*/ | |||
ERROR(2, 3), | |||
/** | |||
* <code>SKIPPED = 4;</code> | |||
*/ | |||
SKIPPED(3, 4), | |||
; | |||
/** | |||
* <code>OK = 1;</code> | |||
*/ | |||
public static final int OK_VALUE = 1; | |||
/** | |||
* <code>FAILURE = 2;</code> | |||
*/ | |||
public static final int FAILURE_VALUE = 2; | |||
/** | |||
* <code>ERROR = 3;</code> | |||
*/ | |||
public static final int ERROR_VALUE = 3; | |||
/** | |||
* <code>SKIPPED = 4;</code> | |||
*/ | |||
public static final int SKIPPED_VALUE = 4; | |||
public final int getNumber() { return value; } | |||
public static TestResultStatus valueOf(int value) { | |||
switch (value) { | |||
case 1: return OK; | |||
case 2: return FAILURE; | |||
case 3: return ERROR; | |||
case 4: return SKIPPED; | |||
default: return null; | |||
} | |||
} | |||
public static com.google.protobuf.Internal.EnumLiteMap<TestResultStatus> | |||
internalGetValueMap() { | |||
return internalValueMap; | |||
} | |||
private static com.google.protobuf.Internal.EnumLiteMap<TestResultStatus> | |||
internalValueMap = | |||
new com.google.protobuf.Internal.EnumLiteMap<TestResultStatus>() { | |||
public TestResultStatus findValueByNumber(int number) { | |||
return TestResultStatus.valueOf(number); | |||
} | |||
}; | |||
public final com.google.protobuf.Descriptors.EnumValueDescriptor | |||
getValueDescriptor() { | |||
return getDescriptor().getValues().get(index); | |||
} | |||
public final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptorForType() { | |||
return getDescriptor(); | |||
} | |||
public static final com.google.protobuf.Descriptors.EnumDescriptor | |||
getDescriptor() { | |||
return org.sonar.batch.protocol.Constants.getDescriptor().getEnumTypes().get(7); | |||
} | |||
private static final TestResultStatus[] VALUES = values(); | |||
public static TestResultStatus valueOf( | |||
com.google.protobuf.Descriptors.EnumValueDescriptor desc) { | |||
if (desc.getType() != getDescriptor()) { | |||
throw new java.lang.IllegalArgumentException( | |||
"EnumValueDescriptor is not for this type."); | |||
} | |||
return VALUES[desc.getIndex()]; | |||
} | |||
private final int index; | |||
private final int value; | |||
private TestResultStatus(int index, int value) { | |||
this.index = index; | |||
this.value = value; | |||
} | |||
// @@protoc_insertion_point(enum_scope:TestResultStatus) | |||
} | |||
public static com.google.protobuf.Descriptors.FileDescriptor | |||
getDescriptor() { | |||
@@ -706,8 +888,10 @@ public final class Constants { | |||
"ON\020\000\022\014\n\010CONSTANT\020\001\022\013\n\007COMMENT\020\002\022\013\n\007CPP_D" + | |||
"OC\020\003\022\026\n\022STRUCTURED_COMMENT\020\004\022\013\n\007KEYWORD\020" + | |||
"\005\022\027\n\023HIGHLIGHTING_STRING\020\006\022\021\n\rKEYWORD_LI" + | |||
"GHT\020\007\022\030\n\024PREPROCESS_DIRECTIVE\020\010B\034\n\030org.s" + | |||
"onar.batch.protocolH\001" | |||
"GHT\020\007\022\030\n\024PREPROCESS_DIRECTIVE\020\010*\032\n\010TestT" + | |||
"ype\022\006\n\002UT\020\001\022\006\n\002IT\020\002*?\n\020TestResultStatus\022" + | |||
"\006\n\002OK\020\001\022\013\n\007FAILURE\020\002\022\t\n\005ERROR\020\003\022\013\n\007SKIPP" + | |||
"ED\020\004B\034\n\030org.sonar.batch.protocolH\001" | |||
}; | |||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = | |||
new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { |
@@ -23,7 +23,6 @@ import org.sonar.batch.protocol.ProtobufUtil; | |||
import org.sonar.batch.protocol.output.BatchReport.Issues; | |||
import javax.annotation.CheckForNull; | |||
import java.io.File; | |||
import java.util.Collections; | |||
import java.util.List; | |||
@@ -141,6 +140,16 @@ public class BatchReportReader { | |||
return file; | |||
} | |||
@CheckForNull | |||
public File readTestResults(int fileRef) { | |||
File file = fileStructure.fileFor(FileStructure.Domain.TEST_RESULT, fileRef); | |||
if (doesFileExists(file)) { | |||
return file; | |||
} | |||
return null; | |||
} | |||
private boolean doesFileExists(File file) { | |||
return file.exists() && file.isFile(); | |||
} |
@@ -115,6 +115,11 @@ public class BatchReportWriter { | |||
ProtobufUtil.writeMessagesToFile(coverageList, file); | |||
} | |||
public void writeTestResults(int componentRef, Iterable<BatchReport.TestResult> testResults) { | |||
File file = fileStructure.fileFor(FileStructure.Domain.TEST_RESULT, componentRef); | |||
ProtobufUtil.writeMessagesToFile(testResults, file); | |||
} | |||
public File getSourceFile(int componentRef) { | |||
return fileStructure.fileFor(FileStructure.Domain.SOURCE, componentRef); | |||
} |
@@ -36,6 +36,7 @@ public class FileStructure { | |||
SCM("scm-", Domain.PB), | |||
SYMBOLS("symbol-", Domain.PB), | |||
COVERAGE("coverage-", Domain.PB), | |||
TEST_RESULT("test-", Domain.PB), | |||
SOURCE("source-", ".txt"); | |||
private static final String PB = ".pb"; |
@@ -161,7 +161,7 @@ message Scm { | |||
optional int32 component_ref = 1; | |||
repeated Changeset changeset = 2; | |||
// if changesetIndexByLine[3] = 2 then it means that changeset[2] is the last one on line 4 | |||
repeated int32 changesetIndexByLine = 3 [packed=true]; | |||
repeated int32 changesetIndexByLine = 3 [packed = true]; | |||
message Changeset { | |||
optional string revision = 1; | |||
@@ -233,3 +233,17 @@ message SyntaxHighlighting { | |||
optional HighlightingType type = 2; | |||
} | |||
message TestResult { | |||
optional int32 test_file_ref = 1; | |||
optional TestType type = 2; | |||
optional TestResultStatus status = 3; | |||
optional int64 duration_in_ms = 4; | |||
optional string stacktrace = 5; | |||
optional string msg = 6; | |||
repeated CoverageBlock coverage_block = 7; | |||
message CoverageBlock { | |||
optional int32 file_ref = 1; | |||
repeated int32 line = 2; | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
option java_package = "org.sonar.batch.protocol"; | |||
option optimize_for = SPEED; | |||
enum Severity { | |||
@@ -71,3 +72,15 @@ enum HighlightingType { | |||
KEYWORD_LIGHT = 7; | |||
PREPROCESS_DIRECTIVE = 8; | |||
} | |||
enum TestType { | |||
UT = 1; | |||
IT = 2; | |||
} | |||
enum TestResultStatus { | |||
OK = 1; | |||
FAILURE = 2; | |||
ERROR = 3; | |||
SKIPPED = 4; | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
SonarQube, open source software quality management tool. | |||
Copyright (C) 2008-2015 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. | |||
*/ | |||
/* | |||
Notes | |||
- "required" fields are not used as recommended by Google to keep forward-compatibility: | |||
https://developers.google.com/protocol-buffers/docs/proto#simple | |||
- the related Java files are not generated during build. Indeed the existing protoc maven | |||
plugins require protobuf to be installed on boxes. That means that generated Java files | |||
are updated and committed for each change (see src/main/gen-java). | |||
*/ | |||
// structure of db column FILE_SOURCES.TEST_DATA | |||
// Temporarily in sonar-batch-protocol | |||
package org.sonar.server.source.db; | |||
option optimize_for = SPEED; | |||
message Test { | |||
optional string uuid = 1; | |||
optional string key = 2; | |||
optional string method_name = 3; | |||
optional string status = 4; | |||
optional string test_message = 5; | |||
optional string type = 6; | |||
repeated CoverageBlock coverage_block = 7; | |||
message CoverageBlock { | |||
optional string uuid = 1; | |||
//TODO TBE - should the key and long_name specified directly ? | |||
optional string key = 2; | |||
optional string long_name = 3; | |||
repeated int32 lines = 4; | |||
optional int32 nb_covered_lines = 5; | |||
} | |||
} | |||
message Tests { | |||
repeated Test test = 1; | |||
} |
@@ -50,11 +50,8 @@ public class BatchReportReaderTest { | |||
@Test | |||
public void create_dir_if_does_not_exist() throws Exception { | |||
File dir = temp.newFolder(); | |||
initFiles(dir); | |||
sut = new BatchReportReader(dir); | |||
BatchReport.Metadata readMetadata = sut.readMetadata(); | |||
assertThat(readMetadata.getAnalysisDate()).isEqualTo(15000000L); | |||
assertThat(readMetadata.getDeletedComponentsCount()).isEqualTo(1); | |||
@@ -105,7 +102,6 @@ public class BatchReportReaderTest { | |||
@Test | |||
public void read_syntax_highlighting() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
writer.writeMetadata(BatchReport.Metadata.newBuilder() | |||
@@ -123,11 +119,9 @@ public class BatchReportReaderTest { | |||
.build()) | |||
.setType(Constants.HighlightingType.ANNOTATION) | |||
.build() | |||
)); | |||
)); | |||
sut = new BatchReportReader(dir); | |||
try (InputStream inputStream = FileUtils.openInputStream(new BatchReportReader(dir).readComponentSyntaxHighlighting(1))) { | |||
try (InputStream inputStream = FileUtils.openInputStream(sut.readComponentSyntaxHighlighting(1))) { | |||
BatchReport.SyntaxHighlighting syntaxHighlighting = BatchReport.SyntaxHighlighting.PARSER.parseDelimitedFrom(inputStream); | |||
assertThat(syntaxHighlighting.getRange()).isNotNull(); | |||
assertThat(syntaxHighlighting.getRange().getStartLine()).isEqualTo(1); | |||
@@ -171,7 +165,6 @@ public class BatchReportReaderTest { | |||
@Test | |||
public void read_coverage() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
writer.writeMetadata(BatchReport.Metadata.newBuilder() | |||
@@ -235,6 +228,36 @@ public class BatchReportReaderTest { | |||
assertThat(sourceFile).isEqualTo(file); | |||
} | |||
@Test | |||
public void read_tests() throws Exception { | |||
initFiles(dir); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
writer.writeTestResults(1, Arrays.asList( | |||
BatchReport.TestResult.newBuilder() | |||
.setTestFileRef(1) | |||
.setDurationInMs(60_000) | |||
.setStacktrace("stacktrace") | |||
.setMsg("message") | |||
.setStatus(Constants.TestResultStatus.OK) | |||
.setType(Constants.TestType.IT) | |||
.addCoverageBlock(BatchReport.TestResult.CoverageBlock.newBuilder() | |||
.setFileRef(2) | |||
.addAllLine(Arrays.asList(1, 2, 3, 4, 5))) | |||
.build())); | |||
try (InputStream inputStream = FileUtils.openInputStream(sut.readTestResults(1))) { | |||
BatchReport.TestResult testResult = BatchReport.TestResult.PARSER.parseDelimitedFrom(inputStream); | |||
assertThat(testResult.getTestFileRef()).isEqualTo(1); | |||
assertThat(testResult.getDurationInMs()).isEqualTo(60_000); | |||
assertThat(testResult.getStacktrace()).isEqualTo("stacktrace"); | |||
assertThat(testResult.getMsg()).isEqualTo("message"); | |||
assertThat(testResult.getType()).isEqualTo(Constants.TestType.IT); | |||
assertThat(testResult.getStatus()).isEqualTo(Constants.TestResultStatus.OK); | |||
assertThat(testResult.getCoverageBlockList().get(0).getFileRef()).isEqualTo(2); | |||
assertThat(testResult.getCoverageBlockList().get(0).getLineList()).containsOnly(1, 2, 3, 4, 5); | |||
} | |||
} | |||
@Test(expected = IllegalStateException.class) | |||
public void fail_if_missing_metadata_file() throws Exception { | |||
sut.readMetadata(); | |||
@@ -285,14 +308,16 @@ public class BatchReportReaderTest { | |||
assertThat(sut.readComponentCoverage(123)).isNull(); | |||
} | |||
/** | |||
* no file if no issues | |||
*/ | |||
@Test | |||
public void empty_list_if_no_issue_found() throws Exception { | |||
assertThat(sut.readComponentIssues(666)).isEmpty(); | |||
} | |||
@Test | |||
public void null_if_no_test_found() throws Exception { | |||
assertThat(sut.readTestResults(666)).isNull(); | |||
} | |||
private void initFiles(File dir) { | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
@@ -20,6 +20,7 @@ | |||
package org.sonar.batch.protocol.output; | |||
import org.apache.commons.io.FileUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
@@ -36,28 +37,32 @@ public class BatchReportWriterTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
File dir; | |||
BatchReportWriter sut; | |||
@Before | |||
public void setUp() throws Exception { | |||
dir = temp.newFolder(); | |||
sut = new BatchReportWriter(dir); | |||
} | |||
@Test | |||
public void create_dir_if_does_not_exist() throws Exception { | |||
File dir = temp.newFolder(); | |||
FileUtils.deleteQuietly(dir); | |||
new BatchReportWriter(dir); | |||
sut = new BatchReportWriter(dir); | |||
assertThat(dir).isDirectory().exists(); | |||
} | |||
@Test | |||
public void write_metadata() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
BatchReport.Metadata.Builder metadata = BatchReport.Metadata.newBuilder() | |||
.setAnalysisDate(15000000L) | |||
.setProjectKey("PROJECT_A") | |||
.setRootComponentRef(1); | |||
writer.writeMetadata(metadata.build()); | |||
sut.writeMetadata(metadata.build()); | |||
BatchReport.Metadata read = ProtobufUtil.readFile(writer.getFileStructure().metadataFile(), BatchReport.Metadata.PARSER); | |||
BatchReport.Metadata read = ProtobufUtil.readFile(sut.getFileStructure().metadataFile(), BatchReport.Metadata.PARSER); | |||
assertThat(read.getAnalysisDate()).isEqualTo(15000000L); | |||
assertThat(read.getProjectKey()).isEqualTo("PROJECT_A"); | |||
assertThat(read.getRootComponentRef()).isEqualTo(1); | |||
@@ -65,11 +70,8 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_component() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
// no data yet | |||
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isFalse(); | |||
// write data | |||
BatchReport.Component.Builder component = BatchReport.Component.newBuilder() | |||
@@ -81,10 +83,10 @@ public class BatchReportWriterTest { | |||
.setIsTest(false) | |||
.addChildRef(5) | |||
.addChildRef(42); | |||
writer.writeComponent(component.build()); | |||
sut.writeComponent(component.build()); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.COMPONENT, 1); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue(); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.COMPONENT, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Component read = ProtobufUtil.readFile(file, BatchReport.Component.PARSER); | |||
assertThat(read.getRef()).isEqualTo(1); | |||
@@ -96,11 +98,8 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_issues() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
// no data yet | |||
assertThat(writer.hasComponentData(FileStructure.Domain.ISSUES, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.ISSUES, 1)).isFalse(); | |||
// write data | |||
BatchReport.Issue issue = BatchReport.Issue.newBuilder() | |||
@@ -109,10 +108,10 @@ public class BatchReportWriterTest { | |||
.setMsg("the message") | |||
.build(); | |||
writer.writeComponentIssues(1, Arrays.asList(issue)); | |||
sut.writeComponentIssues(1, Arrays.asList(issue)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.ISSUES, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.ISSUES, 1); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.ISSUES, 1)).isTrue(); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.ISSUES, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Issues read = ProtobufUtil.readFile(file, BatchReport.Issues.PARSER); | |||
assertThat(read.getComponentRef()).isEqualTo(1); | |||
@@ -122,11 +121,8 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_issues_of_deleted_component() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
// no data yet | |||
assertThat(writer.hasComponentData(FileStructure.Domain.ISSUES_ON_DELETED, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.ISSUES_ON_DELETED, 1)).isFalse(); | |||
// write data | |||
BatchReport.Issue issue = BatchReport.Issue.newBuilder() | |||
@@ -135,10 +131,10 @@ public class BatchReportWriterTest { | |||
.setMsg("the message") | |||
.build(); | |||
writer.writeDeletedComponentIssues(1, "componentUuid", Arrays.asList(issue)); | |||
sut.writeDeletedComponentIssues(1, "componentUuid", Arrays.asList(issue)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.ISSUES_ON_DELETED, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.ISSUES_ON_DELETED, 1); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.ISSUES_ON_DELETED, 1)).isTrue(); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.ISSUES_ON_DELETED, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Issues read = ProtobufUtil.readFile(file, BatchReport.Issues.PARSER); | |||
assertThat(read.getComponentRef()).isEqualTo(1); | |||
@@ -148,10 +144,7 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_measures() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.MEASURES, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.MEASURES, 1)).isFalse(); | |||
BatchReport.Measure measure = BatchReport.Measure.newBuilder() | |||
.setStringValue("text-value") | |||
@@ -160,10 +153,10 @@ public class BatchReportWriterTest { | |||
.setDescription("description") | |||
.build(); | |||
writer.writeComponentMeasures(1, Arrays.asList(measure)); | |||
sut.writeComponentMeasures(1, Arrays.asList(measure)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.MEASURES, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.MEASURES, 1); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.MEASURES, 1)).isTrue(); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.MEASURES, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Measures measures = ProtobufUtil.readFile(file, BatchReport.Measures.PARSER); | |||
assertThat(measures.getComponentRef()).isEqualTo(1); | |||
@@ -176,10 +169,7 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_scm() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.SCM, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.SCM, 1)).isFalse(); | |||
BatchReport.Scm scm = BatchReport.Scm.newBuilder() | |||
.setComponentRef(1) | |||
@@ -190,10 +180,10 @@ public class BatchReportWriterTest { | |||
.setDate(123_456_789L)) | |||
.build(); | |||
writer.writeComponentScm(scm); | |||
sut.writeComponentScm(scm); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.SCM, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.SCM, 1); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.SCM, 1)).isTrue(); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.SCM, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Scm read = ProtobufUtil.readFile(file, BatchReport.Scm.PARSER); | |||
assertThat(read.getComponentRef()).isEqualTo(1); | |||
@@ -204,10 +194,7 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_duplications() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isFalse(); | |||
BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder() | |||
.setOriginPosition(Range.newBuilder() | |||
@@ -223,10 +210,10 @@ public class BatchReportWriterTest { | |||
.build()) | |||
.build()) | |||
.build(); | |||
writer.writeComponentDuplications(1, Arrays.asList(duplication)); | |||
sut.writeComponentDuplications(1, Arrays.asList(duplication)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.DUPLICATIONS, 1); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isTrue(); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.DUPLICATIONS, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Duplications duplications = ProtobufUtil.readFile(file, BatchReport.Duplications.PARSER); | |||
assertThat(duplications.getComponentRef()).isEqualTo(1); | |||
@@ -237,11 +224,8 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_symbols() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
// no data yet | |||
assertThat(writer.hasComponentData(FileStructure.Domain.SYMBOLS, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.SYMBOLS, 1)).isFalse(); | |||
// write data | |||
BatchReport.Symbols.Symbol symbol = BatchReport.Symbols.Symbol.newBuilder() | |||
@@ -259,11 +243,11 @@ public class BatchReportWriterTest { | |||
.build()) | |||
.build(); | |||
writer.writeComponentSymbols(1, Arrays.asList(symbol)); | |||
sut.writeComponentSymbols(1, Arrays.asList(symbol)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.SYMBOLS, 1)).isTrue(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.SYMBOLS, 1)).isTrue(); | |||
File file = writer.getFileStructure().fileFor(FileStructure.Domain.SYMBOLS, 1); | |||
File file = sut.getFileStructure().fileFor(FileStructure.Domain.SYMBOLS, 1); | |||
assertThat(file).exists().isFile(); | |||
BatchReport.Symbols read = ProtobufUtil.readFile(file, BatchReport.Symbols.PARSER); | |||
assertThat(read.getFileRef()).isEqualTo(1); | |||
@@ -274,13 +258,10 @@ public class BatchReportWriterTest { | |||
@Test | |||
public void write_syntax_highlighting() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
// no data yet | |||
assertThat(writer.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTING, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTING, 1)).isFalse(); | |||
writer.writeComponentSyntaxHighlighting(1, Arrays.asList( | |||
sut.writeComponentSyntaxHighlighting(1, Arrays.asList( | |||
BatchReport.SyntaxHighlighting.newBuilder() | |||
.setRange(BatchReport.Range.newBuilder() | |||
.setStartLine(1) | |||
@@ -288,20 +269,17 @@ public class BatchReportWriterTest { | |||
.build()) | |||
.setType(Constants.HighlightingType.ANNOTATION) | |||
.build() | |||
)); | |||
)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTING, 1)).isTrue(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTING, 1)).isTrue(); | |||
} | |||
@Test | |||
public void write_coverage() throws Exception { | |||
File dir = temp.newFolder(); | |||
BatchReportWriter writer = new BatchReportWriter(dir); | |||
// no data yet | |||
assertThat(writer.hasComponentData(FileStructure.Domain.COVERAGE, 1)).isFalse(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.COVERAGE, 1)).isFalse(); | |||
writer.writeComponentCoverage(1, Arrays.asList( | |||
sut.writeComponentCoverage(1, Arrays.asList( | |||
BatchReport.Coverage.newBuilder() | |||
.setLine(1) | |||
.setConditions(1) | |||
@@ -311,9 +289,22 @@ public class BatchReportWriterTest { | |||
.setItCoveredConditions(1) | |||
.setOverallCoveredConditions(1) | |||
.build() | |||
)); | |||
)); | |||
assertThat(writer.hasComponentData(FileStructure.Domain.COVERAGE, 1)).isTrue(); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.COVERAGE, 1)).isTrue(); | |||
} | |||
@Test | |||
public void write_test() throws Exception { | |||
assertThat(sut.hasComponentData(FileStructure.Domain.TEST_RESULT, 1)).isFalse(); | |||
sut.writeTestResults(1, Arrays.asList( | |||
BatchReport.TestResult.newBuilder() | |||
.setTestFileRef(1) | |||
.build() | |||
)); | |||
assertThat(sut.hasComponentData(FileStructure.Domain.TEST_RESULT, 1)).isTrue(); | |||
} | |||
} |
@@ -1,9 +1,10 @@ | |||
<dataset> | |||
<file_sources id="101" project_uuid="projectUuid" file_uuid="uuidsame" | |||
binary_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="[null]" | |||
created_at="1412952242000" updated_at="1412952242000" /> | |||
<file_sources id="101" project_uuid="projectUuid" file_uuid="uuidsame" | |||
binary_data="[null]" | |||
test_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="[null]" | |||
created_at="1412952242000" updated_at="1412952242000"/> | |||
</dataset> |
@@ -1,9 +1,10 @@ | |||
<dataset> | |||
<file_sources id="1" project_uuid="PROJECT_UUID" file_uuid="FILE_UUID" | |||
binary_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" | |||
created_at="1412952242000" updated_at="1412952242000" /> | |||
binary_data="[null]" | |||
test_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" | |||
created_at="1412952242000" updated_at="1412952242000"/> | |||
</dataset> |
@@ -2,9 +2,10 @@ | |||
<file_sources id="101" project_uuid="projectUuid" file_uuid="uuidsame" | |||
binary_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" | |||
created_at="1412952242000" updated_at="1412952242000" /> | |||
test_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" | |||
created_at="1412952242000" updated_at="1412952242000"/> | |||
</dataset> |
@@ -1,15 +1,17 @@ | |||
<dataset> | |||
<file_sources id="101" project_uuid="projectUuid" file_uuid="uuidsame" | |||
binary_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" | |||
created_at="1412952242000" updated_at="1412952242000" /> | |||
<file_sources id="102" project_uuid="projectUuid" file_uuid="uuidempty" binary_data="[null]" | |||
line_hashes="[null]" | |||
src_hash="abcd" | |||
data_hash="0" created_at="1414597442000" updated_at="1414597442000" /> | |||
<file_sources id="101" project_uuid="projectUuid" file_uuid="uuidsame" | |||
binary_data="[null]" | |||
test_data="[null]" | |||
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" | |||
data_hash="0263047cd758c68c27683625f072f010" | |||
src_hash="123456" | |||
created_at="1412952242000" updated_at="1412952242000"/> | |||
<file_sources id="102" project_uuid="projectUuid" file_uuid="uuidempty" binary_data="[null]" | |||
test_data="[null]" | |||
line_hashes="[null]" | |||
src_hash="abcd" | |||
data_hash="0" created_at="1414597442000" updated_at="1414597442000"/> | |||
</dataset> | |||
@@ -562,6 +562,7 @@ CREATE TABLE "FILE_SOURCES" ( | |||
"FILE_UUID" VARCHAR(50) NOT NULL, | |||
"LINE_HASHES" CLOB(2147483647), | |||
"BINARY_DATA" BLOB(167772150), | |||
"TEST_DATA" BLOB(167772150), | |||
"DATA_HASH" VARCHAR(50) NOT NULL, | |||
"SRC_HASH" VARCHAR(50) NULL, | |||
"CREATED_AT" BIGINT NOT NULL, |
@@ -1,5 +1,5 @@ | |||
<dataset> | |||
<file_sources id="2" project_uuid="ABCD" file_uuid="KLMN" binary_data="[null]" line_hashes="[null]" data_hash="321654988" | |||
<file_sources id="2" project_uuid="ABCD" file_uuid="KLMN" binary_data="[null]" test_data="[null]" line_hashes="[null]" data_hash="321654988" | |||
created_at="123456789" updated_at="123456789" src_hash="123456"/> | |||
</dataset> |
@@ -72,8 +72,8 @@ | |||
depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" | |||
build_date="1228222680000" version="[null]" path="[null]"/> | |||
<file_sources id="1" project_uuid="ABCD" file_uuid="GHIJ" binary_data="[null]" line_hashes="[null]" data_hash="321654987" | |||
<file_sources id="1" project_uuid="ABCD" file_uuid="GHIJ" binary_data="[null]" test_data="[null]" line_hashes="[null]" data_hash="321654987" | |||
created_at="123456789" updated_at="123456789" src_hash="12345"/> | |||
<file_sources id="2" project_uuid="ABCD" file_uuid="KLMN" binary_data="[null]" line_hashes="[null]" data_hash="321654988" | |||
<file_sources id="2" project_uuid="ABCD" file_uuid="KLMN" binary_data="[null]" test_data="[null]" line_hashes="[null]" data_hash="321654988" | |||
created_at="123456789" updated_at="123456789" src_hash="123456"/> | |||
</dataset> |
@@ -79,8 +79,8 @@ | |||
depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" | |||
build_date="1228222680000" version="[null]" path="[null]"/> | |||
<file_sources id="1" project_uuid="ABCD" file_uuid="GHIJ" binary_data="[null]" line_hashes="[null]" data_hash="321654987" | |||
<file_sources id="1" project_uuid="ABCD" file_uuid="GHIJ" binary_data="[null]" test_data="[null]" line_hashes="[null]" data_hash="321654987" | |||
created_at="123456789" updated_at="123456789"/> | |||
<file_sources id="2" project_uuid="ABCD" file_uuid="KLMN" binary_data="[null]" line_hashes="[null]" data_hash="321654988" | |||
<file_sources id="2" project_uuid="ABCD" file_uuid="KLMN" binary_data="[null]" test_data="[null]" line_hashes="[null]" data_hash="321654988" | |||
created_at="123456789" updated_at="123456789"/> | |||
</dataset> |
@@ -103,6 +103,6 @@ | |||
depth="[null]" scope="FIL" qualifier="FIL" created_at="1228222680000" | |||
build_date="1228222680000" | |||
version="[null]" path="[null]"/> | |||
<file_sources id="1" project_uuid="A" file_uuid="D" binary_data="[null]" line_hashes="[null]" data_hash="321654987" | |||
<file_sources id="1" project_uuid="A" file_uuid="D" binary_data="[null]" test_data="[null]" line_hashes="[null]" data_hash="321654987" | |||
created_at="123456789" updated_at="123456789"/> | |||
</dataset> |
@@ -2,6 +2,7 @@ | |||
<file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" | |||
binary_data="abcde" data_hash="hash" | |||
test_data="[null]" | |||
line_hashes="ABC\nDEF\nGHI" | |||
src_hash="FILE_HASH" | |||
created_at="1500000000000" updated_at="1500000000000" /> | |||
@@ -9,6 +10,7 @@ | |||
<file_sources id="102" project_uuid="PRJ_UUID" file_uuid="FILE2_UUID" | |||
binary_data="[ignore]" | |||
test_data="[null]" | |||
data_hash="FILE2_DATA_HASH" | |||
line_hashes="LINE1_HASH\nLINE2_HASH" | |||
src_hash="FILE2_HASH" |
@@ -2,6 +2,7 @@ | |||
<file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" | |||
binary_data="abcde" data_hash="hash" | |||
test_data="[null]" | |||
line_hashes="ABC\nDEF\nGHI" | |||
src_hash="FILE_HASH" | |||
created_at="1500000000000" updated_at="1500000000000" /> |
@@ -2,6 +2,7 @@ | |||
<file_sources id="101" project_uuid="PRJ_UUID" file_uuid="FILE1_UUID" | |||
binary_data="[ignore]" | |||
test_data="[null]" | |||
data_hash="NEW_DATA_HASH" | |||
line_hashes="NEW_LINE_HASHES" | |||
src_hash="NEW_FILE_HASH" |
@@ -3,16 +3,19 @@ | |||
<!-- Updated --> | |||
<file_sources id="101" project_uuid="ABCD" file_uuid="FILE1_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="1500000000002"/> | |||
<!-- Not updated because updated_at is not null --> | |||
<file_sources id="102" project_uuid="ABCD" file_uuid="FILE2_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="1500000000000"/> | |||
<!-- Not updated because on another project --> | |||
<file_sources id="103" project_uuid="BCDE" file_uuid="FILE3_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="0"/> | |||
</dataset> |
@@ -3,14 +3,17 @@ | |||
<!-- Only this source should be updated --> | |||
<file_sources id="101" project_uuid="ABCD" file_uuid="FILE1_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="0"/> | |||
<file_sources id="102" project_uuid="ABCD" file_uuid="FILE2_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="1500000000000"/> | |||
<file_sources id="103" project_uuid="BCDE" file_uuid="FILE3_UUID" | |||
binary_data="abcde" data_hash="hash" line_hashes="ABC\nDEF\nGHI" src_hash="FILE_HASH" | |||
test_data="[null]" | |||
created_at="1500000000000" updated_at="0"/> | |||
</dataset> |