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 998ccee IGNITE-10071 Fix for case then background upload of a build
and simultaneous bot restart may result in a queued build persisted but
actually build is finished - Fixes #86.
998ccee is described below
commit 998cceeaffd9699b741dcac308bd9ee869ae8ea7
Author: Dmitriy Pavlov <[email protected]>
AuthorDate: Mon Dec 3 18:53:48 2018 +0300
IGNITE-10071 Fix for case then background upload of a build and
simultaneous bot restart may result in a queued build persisted but actually
build is finished - Fixes #86.
Signed-off-by: Dmitriy Pavlov <[email protected]>
---
.../apache/ignite/ci/IgnitePersistentTeamcity.java | 2 +
.../org/apache/ignite/ci/jobs/CheckQueueJob.java | 1 -
.../ignite/ci/teamcity/ignited/BuildRefDao.java | 16 ++-
.../ci/teamcity/ignited/ITeamcityIgnited.java | 5 +-
.../ci/teamcity/ignited/TeamcityIgnitedImpl.java | 12 +--
.../ignited/fatbuild/FatBuildCompacted.java | 4 +-
.../ci/teamcity/ignited/fatbuild/FatBuildDao.java | 8 +-
.../ignited/fatbuild/ProactiveFatBuildSync.java | 78 ++++++++++----
.../ignite/ci/teamcity/pure/ITeamcityConn.java | 2 +-
.../org/apache/ignite/ci/web/model/Version.java | 2 +-
.../ignited/IgnitedTcInMemoryIntegrationTest.java | 113 +++++++++++++++++++++
11 files changed, 200 insertions(+), 43 deletions(-)
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
index 8ebc749..4b256ce 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
@@ -89,6 +89,8 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
* Teamcity
*/
private ITeamcity teamcity;
+
+ @Nullable
private String serverId;
/** cached running builds for branch. */
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
index 5f3a60e..2f689d9 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
@@ -103,7 +103,6 @@ public class CheckQueueJob implements Runnable {
return msg;
}
- //todo support several branches
List<BranchTracked> tracked =
HelperConfig.getTrackedBranches().getBranches();
if (tracked == null || tracked.isEmpty()) {
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 5e4a1cb..de96fdc 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
@@ -55,19 +55,21 @@ public class BuildRefDao {
@Inject private IStringCompactor compactor;
/** */
- public void init() {
+ public BuildRefDao init() {
CacheConfiguration<Long, BuildRefCompacted> cfg =
TcHelperDb.getCacheV2Config(TEAMCITY_BUILD_CACHE_NAME);
cfg.setQueryEntities(Collections.singletonList(new
QueryEntity(Long.class, BuildRefCompacted.class)));
buildRefsCache = igniteProvider.get().getOrCreateCache(cfg);
+
+ return this;
}
/**
* @param srvId Server id.
* @return all builds for a server, full scan.
*/
- @NotNull protected Stream<BuildRefCompacted> compactedBuildsForServer(int
srvId) {
+ @NotNull public Stream<BuildRefCompacted> compactedBuildsForServer(int
srvId) {
return StreamSupport.stream(buildRefsCache.spliterator(), false)
.filter(entry -> isKeyForServer(entry.getKey(), srvId))
.map(javax.cache.Cache.Entry::getValue);
@@ -86,7 +88,7 @@ public class BuildRefDao {
* @param ghData Gh data.
*/
@AutoProfiling
- public Set<Long> saveChunk(long srvId, List<BuildRef> ghData) {
+ public Set<Long> saveChunk(int srvId, List<BuildRef> ghData) {
Set<Long> ids = ghData.stream().map(BuildRef::getId)
.filter(Objects::nonNull)
.map(buildId -> buildIdToCacheKey(srvId, buildId))
@@ -228,12 +230,16 @@ public class BuildRefDao {
public int[] getAllIds(int srvId) {
GridIntList res = new GridIntList(buildRefsCache.size());
- StreamSupport.stream(buildRefsCache.spliterator(), false)
+ getAllBuildRefs(srvId)
.map(Cache.Entry::getKey)
- .filter(entry -> isKeyForServer(entry, srvId))
.map(BuildRefDao::cacheKeyToBuildId)
.forEach(res::add);
return res.array();
}
+
+ @NotNull public Stream<Cache.Entry<Long, BuildRefCompacted>>
getAllBuildRefs(int srvId) {
+ return StreamSupport.stream(buildRefsCache.spliterator(), false)
+ .filter(entry -> isKeyForServer(entry.getKey(), srvId));
+ }
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
index bc3788c..bfd5bc9 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
@@ -84,7 +84,10 @@ public interface ITeamcityIgnited {
* @param srvId Server id.
* @return integer representation of server ID.
*/
- public static int serverIdToInt(String srvId) {
+ public static int serverIdToInt(@Nullable final String srvId) {
+ if (srvId == null)
+ return 0;
+
return Math.abs(srvId.hashCode());
}
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 df11962..1d0b4bc 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
@@ -443,13 +443,8 @@ public class TeamcityIgnitedImpl implements
ITeamcityIgnited {
if (mode == SyncMode.NONE) {
if (existingBuild != null)
return existingBuild;
- else {
- FatBuildCompacted buildCompacted = new FatBuildCompacted();
-
- buildCompacted.setFakeStub(true);
-
- return buildCompacted; // providing fake builds
- }
+ else
+ return new FatBuildCompacted().setFakeStub(true); // providing
fake builds
}
FatBuildCompacted savedVer = buildSync.loadBuild(conn, buildId,
existingBuild, mode);
@@ -458,9 +453,6 @@ public class TeamcityIgnitedImpl implements
ITeamcityIgnited {
if (savedVer == null)
return existingBuild;
- buildRefDao.save(srvIdMaskHigh, new BuildRefCompacted(savedVer));
- runHistSync.saveToHistoryLater(srvNme, savedVer);
-
return savedVer;
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
index fd153e9..1a50a5d 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
@@ -158,8 +158,10 @@ public class FatBuildCompacted extends BuildRefCompacted
implements IVersionedEn
setFakeStub(true);
}
- public void setFakeStub(boolean val) {
+ public FatBuildCompacted setFakeStub(boolean val) {
setFlag(FAKE_BUILD_F, val);
+
+ return this;
}
public void buildTypeName(String btName, IStringCompactor compactor) {
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
index 2c4df80..0e2e4bd 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
@@ -63,8 +63,10 @@ public class FatBuildDao {
/**
*
*/
- public void init() {
+ public FatBuildDao init() {
buildsCache =
igniteProvider.get().getOrCreateCache(TcHelperDb.getCacheV2Config(TEAMCITY_FAT_BUILD_CACHE_NAME));
+
+ return this;
}
/**
@@ -172,7 +174,7 @@ public class FatBuildDao {
return key!=null && key >> 32 == srvId;
}
- public boolean containsKey(int srvIdMaskHigh, int buildRefKey) {
- return buildsCache.containsKey(buildIdToCacheKey(srvIdMaskHigh,
buildRefKey));
+ public boolean containsKey(int srvIdMaskHigh, int buildId) {
+ return buildsCache.containsKey(buildIdToCacheKey(srvIdMaskHigh,
buildId));
}
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
index 6a63289..753a12f 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
@@ -18,6 +18,7 @@ package org.apache.ignite.ci.teamcity.ignited.fatbuild;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
+import java.util.stream.Stream;
import org.apache.ignite.ci.di.AutoProfiling;
import org.apache.ignite.ci.di.MonitoredTask;
import org.apache.ignite.ci.di.scheduler.IScheduler;
@@ -26,11 +27,13 @@ import org.apache.ignite.ci.tcmodel.result.Build;
import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
+import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
import org.apache.ignite.ci.teamcity.ignited.BuildRefDao;
import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
import org.apache.ignite.ci.teamcity.ignited.SyncMode;
import org.apache.ignite.ci.teamcity.ignited.change.ChangeSync;
+import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync;
import org.apache.ignite.ci.teamcity.pure.ITeamcityConn;
import org.apache.ignite.ci.util.ExceptionUtil;
import org.apache.ignite.internal.util.GridConcurrentHashSet;
@@ -65,8 +68,12 @@ public class ProactiveFatBuildSync {
@Inject private IStringCompactor compactor;
+ /** Change sync. */
@Inject private ChangeSync changeSync;
+ /** Run history sync. */
+ @Inject private RunHistSync runHistSync;
+
@GuardedBy("this")
private Map<String, SyncTask> buildToLoad = new HashMap<>();
@@ -93,7 +100,6 @@ public class ProactiveFatBuildSync {
if (buildsToAskFromTc.isEmpty())
return;
-
synchronized (this) {
final SyncTask syncTask = getSyncTask(conn);
@@ -124,28 +130,34 @@ public class ProactiveFatBuildSync {
protected String findMissingBuildsFromBuildRef(String srvId, ITeamcityConn
conn) {
int srvIdMaskHigh = ITeamcityIgnited.serverIdToInt(srvId);
- final int[] buildRefKeys = buildRefDao.getAllIds(srvIdMaskHigh);
+ Stream<BuildRefCompacted> buildRefs =
buildRefDao.compactedBuildsForServer(srvIdMaskHigh);
List<Integer> buildsIdsToLoad = new ArrayList<>();
- int totalAskedToLoad = 0;
+ AtomicInteger totalAskedToLoad = new AtomicInteger();
+
+ buildRefs.forEach(buildRef -> {
+ Integer buildId = buildRef.getId();
+ if (buildId == null)
+ return;
- for (int buildRefKey : buildRefKeys) {
- if (!fatBuildDao.containsKey(srvIdMaskHigh, buildRefKey))
- buildsIdsToLoad.add(buildRefKey);
+ if (buildRef.isRunning(compactor)
+ || buildRef.isQueued(compactor)
+ || !fatBuildDao.containsKey(srvIdMaskHigh, buildId))
+ buildsIdsToLoad.add(buildId);
if (buildsIdsToLoad.size() >= 100) {
- totalAskedToLoad += buildsIdsToLoad.size();
+ totalAskedToLoad.addAndGet(buildsIdsToLoad.size());
scheduleBuildsLoad(conn, buildsIdsToLoad);
buildsIdsToLoad.clear();
}
- }
+ });
if (!buildsIdsToLoad.isEmpty()) {
- totalAskedToLoad += buildsIdsToLoad.size();
+ totalAskedToLoad.addAndGet(buildsIdsToLoad.size());
scheduleBuildsLoad(conn, buildsIdsToLoad);
}
- return "Invoked later load for " + totalAskedToLoad + " builds from "
+ srvId;
+ return "Invoked later load for " + totalAskedToLoad.get() + " builds
from " + srvId;
}
/** */
@@ -224,6 +236,11 @@ public class ProactiveFatBuildSync {
return ProactiveFatBuildSync.class.getSimpleName() +"." + taskName +
"." + srvName;
}
+ /**
+ * Schedule missing builds into Fat builds cache. Sync is based by
BuildRefs cache.
+ * @param srvName Server name.
+ * @param conn Connection.
+ */
public void invokeLaterFindMissingByBuildRef(String srvName, ITeamcityConn
conn) {
scheduler.sheduleNamed(taskName("findMissingBuildsFromBuildRef",
srvName),
() -> findMissingBuildsFromBuildRef(srvName, conn), 360,
TimeUnit.MINUTES);
@@ -239,16 +256,32 @@ public class ProactiveFatBuildSync {
*/
@Nullable
public FatBuildCompacted loadBuild(ITeamcityConn conn, int buildId,
- @Nullable FatBuildCompacted
existingBuild,
- SyncMode mode) {
+ @Nullable FatBuildCompacted existingBuild,
+ SyncMode mode) {
if (existingBuild != null && !existingBuild.isOutdatedEntityVersion())
{
- boolean finished = !existingBuild.isRunning(compactor) &&
!existingBuild.isQueued(compactor);
+ boolean finished =
+ existingBuild.state(compactor) != null // don't count old fake
builds as finished
+ && !existingBuild.isRunning(compactor)
+ && !existingBuild.isQueued(compactor);
if (finished || mode != SyncMode.RELOAD_QUEUED)
return null;
}
- return reloadBuild(conn, buildId, existingBuild);
+ FatBuildCompacted savedVer = reloadBuild(conn, buildId, existingBuild);
+
+ BuildRefCompacted refCompacted = new BuildRefCompacted(savedVer);
+ if (savedVer.isFakeStub())
+ refCompacted.setId(buildId); //to provide possiblity to save the
build
+
+ final String srvName = conn.serverId();
+ final int srvIdMask = ITeamcityIgnited.serverIdToInt(srvName);
+
+ buildRefDao.save(srvIdMask, refCompacted);
+
+ runHistSync.saveToHistoryLater(srvName, savedVer);
+
+ return savedVer;
}
/**
@@ -264,8 +297,8 @@ public class ProactiveFatBuildSync {
// System.err.println(Thread.currentThread().getName()+ ": Build " +
buildId);
//todo some sort of locking to avoid double requests
- final String srvNme = conn.serverId();
- final int srvIdMask = ITeamcityIgnited.serverIdToInt(srvNme);
+ final String srvName = conn.serverId();
+ final int srvIdMask = ITeamcityIgnited.serverIdToInt(srvName);
Build build;
List<TestOccurrencesFull> tests = new ArrayList<>();
@@ -275,6 +308,9 @@ public class ProactiveFatBuildSync {
try {
build = conn.getBuild(buildId);
+ if (build.isFakeStub())
+ build.setCancelled();
+
if(build.testOccurrences != null && !build.isComposite()) { //
don't query tests for compoite
String nextHref = null;
do {
@@ -304,7 +340,7 @@ public class ProactiveFatBuildSync {
}
catch (Exception e) {
if (Throwables.getRootCause(e) instanceof FileNotFoundException) {
- logger.info("Loading build [" + buildId + "] for server [" +
srvNme + "] failed:" + e.getMessage(), e);
+ logger.info("Loading build [" + buildId + "] for server [" +
srvName + "] failed:" + e.getMessage(), e);
if (existingBuild != null) {
build = existingBuild.toBuild(compactor);
@@ -316,11 +352,13 @@ public class ProactiveFatBuildSync {
problems = existingBuild.problems(compactor);
}
- else
+ else {
build = Build.createFakeStub();
- //todo here can be situation we have build ref, but don't have
a build
+
+ build.setCancelled();
+ }
} else {
- logger.error("Loading build [" + buildId + "] for server [" +
srvNme + "] failed:" + e.getMessage(), e);
+ logger.error("Loading build [" + buildId + "] for server [" +
srvName + "] failed:" + e.getMessage(), e);
e.printStackTrace();
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
index c2884ed..5538bce 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
@@ -39,7 +39,7 @@ public interface ITeamcityConn {
/**
* @return Internal server ID as string
*/
- String serverId();
+ @Nullable public String serverId();
/**
* @return Normalized Host address, ends with '/'.
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 54def0f..2b6fae3 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
@@ -25,7 +25,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 = "20181202";
+ public static final String VERSION = "20181203";
/** 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 c472447..923ba18 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
@@ -16,6 +16,7 @@
*/
package org.apache.ignite.ci.teamcity.ignited;
+import com.google.common.collect.Lists;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -32,6 +33,7 @@ import javax.xml.bind.JAXBException;
import com.google.inject.internal.SingletonScope;
import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.ci.ITeamcity;
import org.apache.ignite.ci.analysis.SuiteInBranch;
@@ -54,22 +56,29 @@ import
org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
import org.apache.ignite.ci.teamcity.ignited.buildtype.BuildTypeRefCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildDao;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.ProactiveFatBuildSync;
import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistCompactedDao;
import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync;
import org.apache.ignite.ci.teamcity.pure.BuildHistoryEmulator;
+import org.apache.ignite.ci.teamcity.pure.ITeamcityConn;
import org.apache.ignite.ci.teamcity.pure.ITeamcityHttpConnection;
+import org.apache.ignite.ci.teamcity.restcached.ITcServerFactory;
import org.apache.ignite.ci.user.ICredentialsProv;
import org.apache.ignite.ci.util.XmlUtil;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.jetbrains.annotations.NotNull;
import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
+import static com.google.common.base.Preconditions.checkNotNull;
import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
import static org.apache.ignite.ci.HelperConfig.ensureDirExist;
import static
org.apache.ignite.ci.teamcity.ignited.IgniteStringCompactor.STRINGS_CACHE;
@@ -116,6 +125,25 @@ public class IgnitedTcInMemoryIntegrationTest {
ignite.close();
}
+ /**
+ * Clear relevant ignite caches to avoid tests invluence to each other.
+ */
+ @Before
+ public void clearIgniteCaches() {
+ clearCache(BuildRefDao.TEAMCITY_BUILD_CACHE_NAME);
+ clearCache(FatBuildDao.TEAMCITY_FAT_BUILD_CACHE_NAME);
+ }
+
+ /**
+ * @param cacheName Cache name to clear.
+ */
+ private void clearCache(String cacheName) {
+ IgniteCache<Long, BuildRefCompacted> buildRefCache =
ignite.cache(cacheName);
+
+ if (buildRefCache != null)
+ buildRefCache.clear();
+ }
+
@Test
public void saveAndLoadBuildReference() throws IOException {
ITeamcityHttpConnection http =
Mockito.mock(ITeamcityHttpConnection.class);
@@ -535,6 +563,91 @@ public class IgnitedTcInMemoryIntegrationTest {
assertEquals(0.5, testRunHist.getFailRate(), 0.1);
}
+ @Test
+ public void testQueuedBuildsRemoved() {
+ TeamcityIgnitedModule module = new TeamcityIgnitedModule();
+ module.overrideHttp(new ITeamcityHttpConnection() {
+ @Override public InputStream sendGet(String basicAuthTok, String
url) throws IOException {
+ throw new FileNotFoundException(url);
+ }
+ });
+ Injector injector = Guice.createInjector(module, new
IgniteAndShedulerTestModule());
+
+ IStringCompactor c = injector.getInstance(IStringCompactor.class);
+ BuildRefDao buildRefDao =
injector.getInstance(BuildRefDao.class).init();
+ FatBuildDao fatBuildDao =
injector.getInstance(FatBuildDao.class).init();
+
+ int buildIdQ = 1000042;
+ BuildRef refQ = new BuildRef();
+ refQ.buildTypeId = "Testbuild";
+ refQ.branchName = ITeamcity.REFS_HEADS_MASTER;
+ refQ.state = BuildRef.STATE_QUEUED;
+ refQ.setId(buildIdQ);
+
+ int buildIdR = 1000043;
+ BuildRef refR = new BuildRef();
+ refR.buildTypeId = "Testbuild";
+ refR.branchName = ITeamcity.REFS_HEADS_MASTER;
+ refR.state = BuildRef.STATE_RUNNING;
+ refR.setId(buildIdR);
+
+ String srvId = APACHE;
+ int srvIdInt = ITeamcityIgnited.serverIdToInt(srvId);
+ ITeamcityConn srvConn =
injector.getInstance(ITcServerFactory.class).createServer(srvId);
+
+ buildRefDao.saveChunk(srvIdInt, Lists.newArrayList(refQ, refR));
+
+ List<BuildRefCompacted> running =
buildRefDao.getQueuedAndRunning(srvIdInt);
+ assertFalse(checkNotNull(running).isEmpty());
+
+ System.out.println("Running builds (before sync): " + printRefs(c,
running));
+
+ ProactiveFatBuildSync buildSync =
injector.getInstance(ProactiveFatBuildSync.class);
+ buildSync.invokeLaterFindMissingByBuildRef(srvId, srvConn);
+
+ FatBuildCompacted fatBuild = fatBuildDao.getFatBuild(srvIdInt,
buildIdQ);
+ System.out.println(fatBuild);
+
+ assertNotNull(fatBuild);
+ assertTrue(fatBuild.isFakeStub());
+
+ assertTrue(fatBuild.isCancelled(c));
+
+ List<BuildRefCompacted> running2 =
buildRefDao.getQueuedAndRunning(srvIdInt);
+ System.out.println("Running builds (after sync): " + printRefs(c,
running2));
+ assertTrue(checkNotNull(running2).isEmpty());
+
+ // Now we have 2 fake stubs, retry to actualize
+ buildRefDao.saveChunk(srvIdInt, Lists.newArrayList(refQ, refR));
+
+ List<BuildRefCompacted> running3 =
buildRefDao.getQueuedAndRunning(srvIdInt);
+ System.out.println("Running builds (before with fake builds): " +
printRefs(c, running3));
+ assertFalse(checkNotNull(running3).isEmpty());
+
+ putOldFashionFakeBuild(c, fatBuildDao, buildIdQ, srvIdInt);
+ putOldFashionFakeBuild(c, fatBuildDao, buildIdR, srvIdInt);
+
+ buildSync.invokeLaterFindMissingByBuildRef(srvId, srvConn);
+
+ List<BuildRefCompacted> running4 =
buildRefDao.getQueuedAndRunning(srvIdInt);
+ System.out.println("Running builds (before with fake builds): " +
printRefs(c, running4));
+ assertTrue(checkNotNull(running4).isEmpty());
+ }
+
+ public void putOldFashionFakeBuild(IStringCompactor c, FatBuildDao
fatBuildDao, int buildId, int srvIdInt) {
+ FatBuildCompacted fb = fatBuildDao.getFatBuild(srvIdInt, buildId);
+
+ fb.fillFieldsFromBuildRef(c, new BuildRef());
+
+ fatBuildDao.putFatBuild(srvIdInt, buildId, fb);
+
+ assertNull(fatBuildDao.getFatBuild(srvIdInt, buildId).state(c));
+ }
+
+ @NotNull public List<BuildRef> printRefs(IStringCompactor c,
List<BuildRefCompacted> running2) {
+ return
running2.stream().map(bref->bref.toBuildRef(c)).collect(Collectors.toList());
+ }
+
/**
*
*/