You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dp...@apache.org on 2018/10/12 17:10:20 UTC
[ignite-teamcity-bot] branch master updated: IGNITE-9869: Bug fix
for Running builds not uploaded into prefetched builds collection: fixed
JAXB 2 roots problem - Fixes #37.
This is an automated email from the ASF dual-hosted git repository.
dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push:
new 84bbae6 IGNITE-9869: Bug fix for Running builds not uploaded into prefetched builds collection: fixed JAXB 2 roots problem - Fixes #37.
84bbae6 is described below
commit 84bbae684d55b191e7ee66ee19a2832e81408dac
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Fri Oct 12 20:10:13 2018 +0300
IGNITE-9869: Bug fix for Running builds not uploaded into prefetched builds collection: fixed JAXB 2 roots problem - Fixes #37.
Signed-off-by: Dmitriy Pavlov <dp...@apache.org>
---
.../Builds.java => di/scheduler/NoOpSheduler.java} | 34 ++--
.../apache/ignite/ci/tcmodel/hist/BuildRef.java | 3 +-
.../org/apache/ignite/ci/tcmodel/hist/Builds.java | 15 ++
.../ci/teamcity/ignited/BuildRefCompacted.java | 7 +
.../ignite/ci/teamcity/ignited/BuildRefDao.java | 42 +++--
.../ci/teamcity/ignited/TeamcityIgnitedImpl.java | 45 +++---
.../java/org/apache/ignite/ci/util/XmlUtil.java | 31 ++--
.../org/apache/ignite/ci/web/model/Version.java | 2 +-
.../ignited/IgnitedTcInMemoryIntegrationTest.java | 175 +++++++++++++++++----
.../ci/teamcity/pure/BuildHistoryEmulator.java | 108 +++++++++++++
10 files changed, 368 insertions(+), 94 deletions(-)
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/scheduler/NoOpSheduler.java
similarity index 52%
copy from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java
copy to ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/scheduler/NoOpSheduler.java
index 82a76a5..c4cae20 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/scheduler/NoOpSheduler.java
@@ -14,32 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.ignite.ci.di.scheduler;
-package org.apache.ignite.ci.tcmodel.hist;
+import java.util.concurrent.TimeUnit;
-import java.util.Collections;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
+/**
+ * Sheduler which never waits
+ */
+public class NoOpSheduler implements IScheduler {
+ /** {@inheritDoc} */
+ @Override public void invokeLater(Runnable cmd, long delay, TimeUnit unit) {
-/** List of builds from build history */
-@XmlRootElement(name = "builds")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class Builds {
- @XmlAttribute
- private String nextHref;
+ }
- @XmlElement(name = "build")
- private List<BuildRef> builds;
+ /** {@inheritDoc} */
+ @Override public void sheduleNamed(String fullName, Runnable cmd, long queitPeriod, TimeUnit unit) {
- public List<BuildRef> getBuildsNonNull() {
- return builds == null ? Collections.emptyList() : builds;
}
- public String nextHref() {
- return nextHref;
+ /** {@inheritDoc} */
+ @Override public void stop() {
+
}
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/BuildRef.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/BuildRef.java
index 10d312d..4ce62f7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/BuildRef.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/BuildRef.java
@@ -18,11 +18,10 @@
package org.apache.ignite.ci.tcmodel.hist;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
-
-import com.google.common.base.Objects;
import org.apache.ignite.ci.tcmodel.result.AbstractRef;
/**
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java
index 82a76a5..0de40d5 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/hist/Builds.java
@@ -32,6 +32,9 @@ public class Builds {
@XmlAttribute
private String nextHref;
+ @XmlAttribute
+ private Integer count;
+
@XmlElement(name = "build")
private List<BuildRef> builds;
@@ -42,4 +45,16 @@ public class Builds {
public String nextHref() {
return nextHref;
}
+
+ public void count(int count) {
+ this.count = count;
+ }
+
+ public void nextHref(String nextHref) {
+ this.nextHref = nextHref;
+ }
+
+ public void builds(List<BuildRef> list) {
+ this.builds = list;
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
index 6494e56..a983e77 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
@@ -77,4 +77,11 @@ public class BuildRefCompacted {
@Override public int hashCode() {
return Objects.hashCode(id, buildTypeId, branchName, status, state);
}
+
+ /**
+ *
+ */
+ public int id() {
+ return id;
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefDao.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefDao.java
index cfcd3bd..2b68806 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefDao.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefDao.java
@@ -33,6 +33,7 @@ import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.ci.db.TcHelperDb;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.internal.util.GridIntList;
import org.jetbrains.annotations.NotNull;
public class BuildRefDao {
@@ -53,16 +54,16 @@ public class BuildRefDao {
buildsCache = ignite.getOrCreateCache(TcHelperDb.getCacheV2Config(TEAMCITY_BUILD_CACHE_NAME));
}
- @NotNull protected Stream<BuildRefCompacted> compactedBuildsForServer(long srvIdMaskHigh) {
+ @NotNull protected Stream<BuildRefCompacted> compactedBuildsForServer(long srvId) {
return StreamSupport.stream(buildsCache.spliterator(), false)
- .filter(entry -> entry.getKey() >> 32 == srvIdMaskHigh)
+ .filter(entry -> entry.getKey() >> 32 == srvId)
.map(javax.cache.Cache.Entry::getValue);
}
- public int saveChunk(long srvIdMaskHigh, List<BuildRef> ghData) {
+ public int saveChunk(long srvId, List<BuildRef> ghData) {
Set<Long> ids = ghData.stream().map(BuildRef::getId)
.filter(Objects::nonNull)
- .map(buildId -> buildIdToCacheKey(srvIdMaskHigh, buildId))
+ .map(buildId -> buildIdToCacheKey(srvId, buildId))
.collect(Collectors.toSet());
Map<Long, BuildRefCompacted> existingEntries = buildsCache.getAll(ids);
@@ -73,7 +74,7 @@ public class BuildRefDao {
.collect(Collectors.toList());
for (BuildRefCompacted next : collect) {
- long cacheKey = buildIdToCacheKey(srvIdMaskHigh, next.id);
+ long cacheKey = buildIdToCacheKey(srvId, next.id);
BuildRefCompacted buildPersisted = existingEntries.get(cacheKey);
if (buildPersisted == null || !buildPersisted.equals(next))
@@ -87,19 +88,19 @@ public class BuildRefDao {
}
/**
- * @param srvIdMaskHigh Server id mask high.
+ * @param srvId Server id mask high.
* @param buildId Build id.
*/
- private long buildIdToCacheKey(long srvIdMaskHigh, int buildId) {
- return (long)buildId | srvIdMaskHigh << 32;
+ private long buildIdToCacheKey(long srvId, int buildId) {
+ return (long)buildId | srvId << 32;
}
/**
- * @param srvIdMaskHigh Server id mask high.
+ * @param srvId Server id mask high.
* @param buildTypeId Build type id.
* @param bracnhNameQry Bracnh name query.
*/
- @NotNull public List<BuildRef> findBuildsInHistory(long srvIdMaskHigh,
+ @NotNull public List<BuildRef> findBuildsInHistory(long srvId,
@Nullable String buildTypeId,
String bracnhNameQry) {
@@ -111,10 +112,29 @@ public class BuildRefDao {
if (bracnhNameQryId == null)
return Collections.emptyList();
- return compactedBuildsForServer(srvIdMaskHigh)
+ return compactedBuildsForServer(srvId)
.filter(e -> e.buildTypeId == (int)buildTypeIdId)
.filter(e -> e.branchName == (int)bracnhNameQryId)
.map(compacted -> compacted.toBuildRef(compactor))
.collect(Collectors.toList());
}
+
+ /**
+ * @param srvId Server id.
+ */
+ public List<BuildRefCompacted> getQueuedAndRunning(long srvId) {
+ GridIntList list = new GridIntList(2);
+ Integer stateQueuedId = compactor.getStringIdIfPresent(BuildRef.STATE_QUEUED);
+ if (stateQueuedId != null)
+ list.add(stateQueuedId);
+
+ Integer stateRunningId = compactor.getStringIdIfPresent(BuildRef.STATE_RUNNING);
+ if (stateRunningId != null)
+ list.add(stateRunningId);
+
+
+ return compactedBuildsForServer(srvId)
+ .filter(e -> list.contains(e.state) )
+ .collect(Collectors.toList());
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
index 746ef38..5e598ec 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
@@ -16,11 +16,16 @@
*/
package org.apache.ignite.ci.teamcity.ignited;
+
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.inject.Inject;
+import com.google.common.collect.Sets;
import org.apache.ignite.ci.ITeamcity;
import org.apache.ignite.ci.di.AutoProfiling;
import org.apache.ignite.ci.di.MonitoredTask;
@@ -81,7 +86,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
Build build = conn.triggerBuild(buildTypeId, branchName, cleanRebuild, queueAtTop);
//todo may add additional parameter: load builds into DB in sync/async fashion
- runAсtualizeBuilds(srvId, false, build.getId());
+ runActualizeBuilds(srvId, false, Sets.newHashSet(build.getId()));
return build;
}
@@ -89,8 +94,12 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
/**
*
*/
- private void actualizeRecentBuilds() {
- runAсtualizeBuilds(srvId, false, null);
+ void actualizeRecentBuilds() {
+ List<BuildRefCompacted> running = buildRefDao.getQueuedAndRunning(srvIdMaskHigh);
+
+ Set<Integer> collect = running.stream().map(BuildRefCompacted::id).collect(Collectors.toSet());
+
+ runActualizeBuilds(srvId, false, collect);
// schedule full resync later
scheduler.invokeLater(this::sheduleResync, 60, TimeUnit.SECONDS);
@@ -107,27 +116,27 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
/**
*
*/
- private void fullReindex() {
- runAсtualizeBuilds(srvId, true, null);
+ void fullReindex() {
+ runActualizeBuilds(srvId, true, null);
}
/**
- * @param srvId Server id.
- * @param fullReindex Reindex all builds from TC history. Ignored if particular ID provided.
- * @param buildIdCanFinish Build ID can be used as end of syncing.
+ * @param srvId Server id. todo to be added as composite name extend
+ * @param fullReindex Reindex all builds from TC history.
+ * @param mandatoryToReload Build ID can be used as end of syncing. Ignored if fullReindex mode.
*/
@MonitoredTask(name = "Actualize BuildRefs, full resync", nameExtArgIndex = 1)
@AutoProfiling
- protected String runAсtualizeBuilds(String srvId, boolean fullReindex,
- @Nullable Integer buildIdCanFinish) {
+ protected String runActualizeBuilds(String srvId, boolean fullReindex,
+ @Nullable Set<Integer> mandatoryToReload) {
AtomicReference<String> outLinkNext = new AtomicReference<>();
List<BuildRef> tcDataFirstPage = conn.getBuildRefs(null, outLinkNext);
int cntSaved = buildRefDao.saveChunk(srvIdMaskHigh, tcDataFirstPage);
int totalChecked = tcDataFirstPage.size();
- boolean noRequiredBuild = buildIdCanFinish == null;
- boolean requiredBuildFound = false;
+ final Set<Integer> stillNeedToFind =
+ mandatoryToReload == null ? Collections.emptySet() : Sets.newHashSet(mandatoryToReload);
while (outLinkNext.get() != null) {
String nextPageUrl = outLinkNext.get();
@@ -138,13 +147,13 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
cntSaved += savedCurChunk;
totalChecked += tcDataNextPage.size();
- if (buildIdCanFinish != null) {
- if (tcDataNextPage.stream().map(BuildRef::getId).anyMatch(buildIdCanFinish::equals))
- requiredBuildFound = true; // Syncing till specific build ID.
- }
+ if (!fullReindex) {
+ if (!stillNeedToFind.isEmpty())
+ tcDataNextPage.stream().map(BuildRef::getId).forEach(stillNeedToFind::remove);
- if (savedCurChunk == 0 && ((requiredBuildFound) || (noRequiredBuild && !fullReindex)))
- break; // There are no modification at current page, hopefully no modifications at all
+ if (savedCurChunk == 0 && stillNeedToFind.isEmpty())
+ break; // There are no modification at current page, hopefully no modifications at all
+ }
}
return "Entries saved " + cntSaved + " Builds checked " + totalChecked;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java
index 5eb1510..958edeb 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java
@@ -18,9 +18,11 @@
package org.apache.ignite.ci.util;
import java.io.Reader;
+import java.io.StringWriter;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
/**
@@ -31,7 +33,26 @@ public class XmlUtil {
private static ConcurrentHashMap<Class, JAXBContext> cachedCtx = new ConcurrentHashMap<>();
public static <T> T load(Class<T> tCls, Reader reader) throws JAXBException {
- final JAXBContext ctx = cachedCtx.computeIfAbsent(tCls, c -> {
+ Unmarshaller unmarshaller = getContext(tCls).createUnmarshaller();
+ T unmarshal = (T)unmarshaller.unmarshal(reader);
+
+ ObjectInterner.internFields(unmarshal);
+
+ return unmarshal;
+ }
+
+ public static String save(Object obj) throws JAXBException {
+ Marshaller marshaller = getContext(obj.getClass()).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(obj, writer);
+
+ return writer.toString();
+ }
+
+ private static <T> JAXBContext getContext(Class<T> tCls) {
+ return cachedCtx.computeIfAbsent(tCls, c -> {
try {
return JAXBContext.newInstance(tCls);
}
@@ -39,14 +60,6 @@ public class XmlUtil {
throw new RuntimeException(e);
}
});
- Unmarshaller unmarshaller = ctx.createUnmarshaller();
- T unmarshal = (T)unmarshaller.unmarshal(reader);
-
- int interned = ObjectInterner.internFields(unmarshal);
- // if (interned > 0)
- // System.out.println("Strings saved: " + interned);
-
- return unmarshal;
}
/**
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
index 0b3e902..d5b8765 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
@@ -23,7 +23,7 @@ package org.apache.ignite.ci.web.model;
public static final String GITHUB_REF = "https://github.com/apache/ignite-teamcity-bot";
/** TC Bot Version. */
- public static final String VERSION = "20181011";
+ public static final String VERSION = "20181012";
/** TC Bot Version. */
public String version = VERSION;
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
index f66abd5..ea7e0a9 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
@@ -21,14 +21,22 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.apache.ignite.ci.di.scheduler.DirectExecNoWaitSheduler;
import org.apache.ignite.ci.di.scheduler.IScheduler;
+import org.apache.ignite.ci.di.scheduler.NoOpSheduler;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.teamcity.pure.BuildHistoryEmulator;
import org.apache.ignite.ci.teamcity.pure.ITeamcityHttpConnection;
import org.apache.ignite.ci.user.ICredentialsProv;
+import org.jetbrains.annotations.NotNull;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
@@ -38,18 +46,37 @@ import static org.apache.ignite.ci.teamcity.ignited.IgniteStringCompactor.STRING
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
+/**
+ * Test for ignite persistence
+ */
public class IgnitedTcInMemoryIntegrationTest {
-
+ /** Server Name for test. */
public static final String APACHE = "apache";
+ /** Ignite. */
+ private static Ignite ignite;
+
+ /**
+ *
+ */
+ @BeforeClass
+ public static void startIgnite() {
+ ignite = Ignition.start();
+ }
+
+ /**
+ *
+ */
+ @AfterClass
+ public static void stopIgnite() {
+ ignite.close();
+ }
@Test
public void saveAndLoadBuildReference() throws IOException {
- Ignite ignite = Ignition.start();
-
ITeamcityHttpConnection http = Mockito.mock(ITeamcityHttpConnection.class);
when(http.sendGet(anyString(), anyString())).thenAnswer(
- (invocationOnMock)->{
+ (invocationOnMock) -> {
String url = invocationOnMock.getArgument(1);
if (url.contains("/app/rest/latest/builds?locator=defaultFilter:false,count:1000,start:1000"))
@@ -62,46 +89,128 @@ public class IgnitedTcInMemoryIntegrationTest {
}
);
- try {
- TeamcityIgnitedModule module = new TeamcityIgnitedModule();
+ TeamcityIgnitedModule module = new TeamcityIgnitedModule();
- module.overrideHttp(http);
+ module.overrideHttp(http);
- Injector injector = Guice.createInjector(module, new AbstractModule() {
- @Override protected void configure() {
- bind(Ignite.class).toInstance(ignite);
- bind(IScheduler.class).to(DirectExecNoWaitSheduler.class);
- }
- });
+ Injector injector = Guice.createInjector(module, new AbstractModule() {
+ @Override protected void configure() {
+ bind(Ignite.class).toInstance(ignite);
+ bind(IScheduler.class).to(DirectExecNoWaitSheduler.class);
+ }
+ });
+
+ ITeamcityIgnited srv = injector.getInstance(ITeamcityIgnitedProvider.class).server(APACHE, creds());
- ICredentialsProv mock = Mockito.mock(ICredentialsProv.class);
- when(mock.hasAccess(anyString())).thenReturn(true);
- when(mock.getUser(anyString())).thenReturn("mtcga");
- when(mock.getPassword(anyString())).thenReturn("123");
- ITeamcityIgnited srv = injector.getInstance(ITeamcityIgnitedProvider.class).server(APACHE, mock);
+ String buildTypeId = "IgniteTests24Java8_RunAll";
+ String branchName = "<default>";
+ List<BuildRef> hist = srv.getBuildHistory(buildTypeId, branchName);
+ //todo mult branches including pull/4926/head
- String buildTypeId = "IgniteTests24Java8_RunAll";
- String branchName = "<default>";
- List<BuildRef> hist = srv.getBuildHistory(buildTypeId, branchName);
+ assertTrue(!hist.isEmpty());
- assertTrue(!hist.isEmpty());
+ for (BuildRef h : hist) {
+ System.out.println(h);
- for (BuildRef h : hist) {
- System.out.println(h);
+ assertEquals(buildTypeId, h.suiteId());
- assertEquals(buildTypeId, h.suiteId());
+ assertEquals("refs/heads/master", h.branchName());
+ }
- assertEquals("refs/heads/master", h.branchName());
+ ignite.cache(STRINGS_CACHE).forEach(
+ (e) -> {
+ System.out.println(e.getValue());
}
+ );
+ }
- ignite.cache(STRINGS_CACHE).forEach(
- (e) -> {
- System.out.println(e.getValue());
- }
- );
+ @Test
+ public void incrementalActualizationOfBuildsContainsQueued() throws IOException {
+ ITeamcityHttpConnection http = Mockito.mock(ITeamcityHttpConnection.class);
+
+ int queuedBuildIdx = 500;
+ ArrayList<BuildRef> tcBuilds = new ArrayList<>();
+ for (int i = 0; i < 1000; i++) {
+ BuildRef e = new BuildRef();
+ e.state = i >= queuedBuildIdx ?
+ (Math.random() * 2 > 1 ? BuildRef.STATE_QUEUED : BuildRef.STATE_RUNNING)
+ : BuildRef.STATE_FINISHED;
+ e.status = BuildRef.STATUS_SUCCESS;
+ e.buildTypeId = "IgniteTests24Java8_RunAll";
+ e.branchName = "refs/heads/master";
+ e.setId(i + 50000);
+ tcBuilds.add(e);
}
- finally {
- ignite.close();
+
+ BuildHistoryEmulator emulator = new BuildHistoryEmulator(tcBuilds);
+
+ when(http.sendGet(anyString(), anyString())).thenAnswer(
+ (invocationOnMock) -> {
+ String url = invocationOnMock.getArgument(1);
+
+ InputStream stream = emulator.handleUrl(url);
+
+ if (stream != null)
+ return stream;
+
+ throw new FileNotFoundException(url);
+ }
+ );
+
+ TeamcityIgnitedModule module = new TeamcityIgnitedModule();
+
+ module.overrideHttp(http);
+
+ Injector injector = Guice.createInjector(module, new AbstractModule() {
+ @Override protected void configure() {
+ bind(Ignite.class).toInstance(ignite);
+ bind(IScheduler.class).to(NoOpSheduler.class);
+ }
+ });
+
+ ITeamcityIgnited srv = injector.getInstance(ITeamcityIgnitedProvider.class).server(APACHE, creds());
+
+ TeamcityIgnitedImpl teamcityIgnited = (TeamcityIgnitedImpl)srv;
+ teamcityIgnited.fullReindex();
+ String buildTypeId = "IgniteTests24Java8_RunAll";
+ String branchName = "<default>";
+ List<String> statues = srv.getBuildHistory(buildTypeId, branchName).stream().map(BuildRef::state).distinct().collect(Collectors.toList());
+ System.out.println("Before " + statues);
+
+ for (int i = queuedBuildIdx; i < tcBuilds.size(); i++)
+ tcBuilds.get(i).state = BuildRef.STATE_FINISHED;
+
+ teamcityIgnited.actualizeRecentBuilds();
+
+
+ List<BuildRef> hist = srv.getBuildHistory(buildTypeId, branchName);
+
+ assertTrue(!hist.isEmpty());
+
+ for (BuildRef h : hist) {
+ assertEquals(buildTypeId, h.suiteId());
+
+ assertEquals("refs/heads/master", h.branchName());
+
+ assertTrue("Build " + h + " is expected to be finished" , h.isFinished());
}
+
+ statues = hist.stream().map(BuildRef::state).distinct().collect(Collectors.toList());
+
+ System.out.println("After " + statues);
}
+
+ /**
+ *
+ */
+ @NotNull public ICredentialsProv creds() {
+ ICredentialsProv mock = Mockito.mock(ICredentialsProv.class);
+
+ when(mock.hasAccess(anyString())).thenReturn(true);
+ when(mock.getUser(anyString())).thenReturn("mtcga");
+ when(mock.getPassword(anyString())).thenReturn("123");
+
+ return mock;
+ }
+
}
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/pure/BuildHistoryEmulator.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/pure/BuildHistoryEmulator.java
new file mode 100644
index 0000000..d9d40be
--- /dev/null
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/pure/BuildHistoryEmulator.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.ci.teamcity.pure;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.bind.JAXBException;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.tcmodel.hist.Builds;
+import org.apache.ignite.ci.util.XmlUtil;
+import org.jetbrains.annotations.Nullable;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+public class BuildHistoryEmulator {
+ private ArrayList<BuildRef> sharedState;
+
+ public BuildHistoryEmulator(ArrayList<BuildRef> sharedState) {
+ this.sharedState = sharedState;
+ }
+
+ /**
+ * @param url Url.
+ */
+ @Nullable public InputStream handleUrl(String url) throws JAXBException {
+ if (!url.contains("/app/rest/latest/builds?locator=defaultFilter:false"))
+ return null;
+
+ int cnt = getIntFromLocator(url, "count:", 100);
+ int start = getIntFromLocator(url, "start:", 100);
+
+ int totalBuilds = sharedState.size();
+ int totalRemained = totalBuilds - start;
+ if (totalRemained < 0)
+ totalRemained = 0;
+
+ int returnNow = Math.min(totalRemained, cnt);
+
+ int nextStart = 0;
+ if (totalBuilds > start + returnNow)
+ nextStart = start + returnNow;
+
+ Builds builds = createBuilds(cnt, returnNow, nextStart);
+ List<BuildRef> buildsList = new ArrayList<>();
+
+ for (int i = start; i < start + returnNow; i++)
+ buildsList.add(sharedState.get(i));
+
+ builds.builds(buildsList);
+
+ return new ByteArrayInputStream(XmlUtil.save(builds).getBytes(UTF_8));
+ }
+
+ public Builds createBuilds(int cnt, int returnNow, int nextStart) {
+ Builds builds = new Builds();
+ builds.count(returnNow);
+ if (nextStart > 0) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("/app/rest/latest/builds?locator=defaultFilter:false,count:");
+ buf.append(cnt);
+ buf.append(",start:");
+ buf.append(nextStart);
+
+ builds.nextHref(buf.toString());
+ }
+
+ return builds;
+
+ }
+
+ /**
+ * @param url Url.
+ * @param prefix Prefix.
+ * @param def Def.
+ */
+ public int getIntFromLocator(String url, String prefix, int def) {
+ Pattern compile = Pattern.compile(prefix + "[0-9]*");
+ Matcher m = compile.matcher(url);
+ if (!m.find())
+ return def;
+
+ String cntStr = m.group(0);
+
+ if(cntStr == null)
+ return def;
+
+ return Integer.parseInt(cntStr.substring(prefix.length()));
+
+ }
+}