/*
* Copyright 2017 ThoughtWorks, Inc.
*
* Licensed 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 com.thoughtworks.go.server.persistence;
import com.thoughtworks.go.config.CaseInsensitiveString;
import com.thoughtworks.go.config.PipelineConfig;
import com.thoughtworks.go.config.materials.MaterialConfigs;
import com.thoughtworks.go.config.materials.PackageMaterial;
import com.thoughtworks.go.config.materials.PluggableSCMMaterial;
import com.thoughtworks.go.config.materials.ScmMaterial;
import com.thoughtworks.go.config.materials.dependency.DependencyMaterial;
import com.thoughtworks.go.config.materials.dependency.DependencyMaterialConfig;
import com.thoughtworks.go.config.materials.git.GitMaterial;
import com.thoughtworks.go.config.materials.git.GitMaterialConfig;
import com.thoughtworks.go.config.materials.mercurial.HgMaterial;
import com.thoughtworks.go.config.materials.mercurial.HgMaterialConfig;
import com.thoughtworks.go.config.materials.perforce.P4Material;
import com.thoughtworks.go.config.materials.perforce.P4MaterialConfig;
import com.thoughtworks.go.config.materials.svn.SvnMaterial;
import com.thoughtworks.go.config.materials.svn.SvnMaterialConfig;
import com.thoughtworks.go.domain.*;
import com.thoughtworks.go.domain.buildcause.BuildCause;
import com.thoughtworks.go.domain.config.Configuration;
import com.thoughtworks.go.domain.config.ConfigurationProperty;
import com.thoughtworks.go.domain.materials.*;
import com.thoughtworks.go.domain.materials.packagematerial.PackageMaterialInstance;
import com.thoughtworks.go.domain.materials.scm.PluggableSCMMaterialInstance;
import com.thoughtworks.go.domain.materials.svn.SvnMaterialInstance;
import com.thoughtworks.go.domain.packagerepository.ConfigurationPropertyMother;
import com.thoughtworks.go.domain.packagerepository.PackageDefinitionMother;
import com.thoughtworks.go.domain.packagerepository.PackageRepository;
import com.thoughtworks.go.domain.packagerepository.PackageRepositoryMother;
import com.thoughtworks.go.domain.scm.SCMMother;
import com.thoughtworks.go.helper.*;
import com.thoughtworks.go.server.cache.GoCache;
import com.thoughtworks.go.server.dao.DatabaseAccessHelper;
import com.thoughtworks.go.server.dao.PipelineSqlMapDao;
import com.thoughtworks.go.server.database.DatabaseStrategy;
import com.thoughtworks.go.server.domain.Username;
import com.thoughtworks.go.server.service.InstanceFactory;
import com.thoughtworks.go.server.service.MaterialConfigConverter;
import com.thoughtworks.go.server.service.MaterialExpansionService;
import com.thoughtworks.go.server.service.ScheduleTestUtil;
import com.thoughtworks.go.server.transaction.TransactionSynchronizationManager;
import com.thoughtworks.go.server.transaction.TransactionTemplate;
import com.thoughtworks.go.server.util.Pagination;
import com.thoughtworks.go.util.*;
import com.thoughtworks.go.util.json.JsonHelper;
import com.thoughtworks.go.utils.SerializationTester;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import static com.thoughtworks.go.util.GoConstants.DEFAULT_APPROVED_BY;
import static java.util.Arrays.asList;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.hamcrest.number.OrderingComparison.greaterThan;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:WEB-INF/applicationContext-global.xml",
"classpath:WEB-INF/applicationContext-dataLocalAccess.xml",
"classpath:WEB-INF/applicationContext-acegi-security.xml"
})
public class MaterialRepositoryIntegrationTest {
@Autowired MaterialRepository repo;
@Autowired
GoCache goCache;
@Autowired PipelineSqlMapDao pipelineSqlMapDao;
@Autowired DatabaseAccessHelper dbHelper;
@Autowired SessionFactory sessionFactory;
@Autowired TransactionSynchronizationManager transactionSynchronizationManager;
@Autowired TransactionTemplate transactionTemplate;
@Autowired private InstanceFactory instanceFactory;
@Autowired private MaterialConfigConverter materialConfigConverter;
@Autowired private MaterialExpansionService materialExpansionService;
@Autowired private DatabaseStrategy databaseStrategy;
private HibernateTemplate originalTemplate;
private String md5 = "md5-test";
private ScheduleTestUtil u;
@Before
public void setUp() throws Exception {
originalTemplate = repo.getHibernateTemplate();
dbHelper.onSetUp();
goCache.clear();
u = new ScheduleTestUtil(transactionTemplate, repo, dbHelper, new GoConfigFileHelper());
}
@After
public void tearDown() throws Exception {
goCache.clear();
repo.setHibernateTemplate(originalTemplate);
dbHelper.onTearDown();
}
@Test
public void shouldBeAbleToPersistAMaterial() throws Exception {
MaterialInstance original = new SvnMaterialInstance("url", "username", UUID.randomUUID().toString(), true);
repo.saveOrUpdate(original);
MaterialInstance loaded = repo.find(original.getId());
assertThat(loaded, is(original));
}
@Test
public void shouldBeAbleToPersistADependencyMaterial() {
MaterialInstance materialInstance = new DependencyMaterial(new CaseInsensitiveString("name"), new CaseInsensitiveString("pipeline"), new CaseInsensitiveString("stage"),
"serverAlias").createMaterialInstance();
repo.saveOrUpdate(materialInstance);
MaterialInstance loaded = repo.find(materialInstance.getId());
assertThat(loaded, is(materialInstance));
}
@Test
public void shouldCacheMaterialInstanceOnSaveAndUpdate() {
SvnMaterial originalMaterial = MaterialsMother.svnMaterial();
MaterialInstance materialInstance = originalMaterial.createMaterialInstance();
repo.saveOrUpdate(materialInstance);
assertThat(repo.find(materialInstance.getId()), is(materialInstance));
SvnMaterial changedMaterial = MaterialsMother.svnMaterial();
changedMaterial.setPassword("SomethingElse");
MaterialInstance changedInstance = changedMaterial.createMaterialInstance();
changedInstance.setId(materialInstance.getId());
repo.saveOrUpdate(changedInstance);
assertThat(repo.find(materialInstance.getId()), is(changedInstance));
}
@Test
public void findModificationsFor_shouldCacheModifications() {
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
ArrayList modifications = new ArrayList();
when(mockTemplate.find("FROM Modification WHERE materialId = ? AND id BETWEEN ? AND ? ORDER BY id DESC", new Object[]{10L, -1L, -1L})).thenReturn(modifications);
MaterialInstance materialInstance = material().createMaterialInstance();
materialInstance.setId(10);
when(mockTemplate.findByCriteria(any(DetachedCriteria.class))).thenReturn(asList(materialInstance));
PipelineMaterialRevision pmr = pipelineMaterialRevision();
List<Modification> actual;
actual = repo.findModificationsFor(pmr);
actual = repo.findModificationsFor(pmr);
assertSame(modifications, actual);
verify(mockTemplate, times(1)).find("FROM Modification WHERE materialId = ? AND id BETWEEN ? AND ? ORDER BY id DESC", new Object[]{10L, -1L, -1L});
}
@Test
public void findPipelineMaterialRevisions_shouldCacheResults() {
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
repo.findPipelineMaterialRevisions(2);
repo.findPipelineMaterialRevisions(2);
verify(mockTemplate, times(1)).find("FROM PipelineMaterialRevision WHERE pipelineId = ? ORDER BY id", 2L);
}
@Test
public void findModificationsSince_shouldNotCacheIfTheResultsetLarge() {
SvnMaterial material = MaterialsMother.svnMaterial();
MaterialRevision first = saveOneScmModification(material, "user1", "file1");
MaterialRevision second = saveOneScmModification(material, "user2", "file2");
goCache.clear();
repo = new MaterialRepository(sessionFactory, goCache, 1, transactionSynchronizationManager, materialConfigConverter, materialExpansionService, databaseStrategy);
repo.findModificationsSince(material, first);
assertThat(repo.cachedModifications(repo.findMaterialInstance(material)), is(nullValue()));
repo.findModificationsSince(material, second);
assertThat(repo.cachedModifications(repo.findMaterialInstance(material)), is(notNullValue()));
repo.findModificationsSince(material, first);
assertThat(repo.cachedModifications(repo.findMaterialInstance(material)), is(nullValue()));
}
@Test
public void findModificationsSince_shouldHandleConcurrentModificationToCache() throws InterruptedException {
final SvnMaterial svn = MaterialsMother.svnMaterial();
final MaterialRevision first = saveOneScmModification(svn, "user1", "file1");
final MaterialRevision second = saveOneScmModification(svn, "user2", "file2");
final MaterialRevision third = saveOneScmModification(svn, "user2", "file3");
repo = new MaterialRepository(sessionFactory, goCache = new GoCache(goCache) {
@Override
public Object get(String key) {
Object value = super.get(key);
TestUtils.sleepQuietly(200); // sleep so we can have multiple threads enter the critical section
return value;
}
}, 200, transactionSynchronizationManager, materialConfigConverter, materialExpansionService, databaseStrategy);
Thread thread1 = new Thread(new Runnable() {
public void run() {
repo.findModificationsSince(svn, first);
}
});
thread1.start();
TestUtils.sleepQuietly(50);
Thread thread2 = new Thread(new Runnable() {
public void run() {
repo.findModificationsSince(svn, second);
}
});
thread2.start();
thread1.join();
thread2.join();
assertThat(repo.cachedModifications(repo.findMaterialInstance(svn)).size(), is(3));
}
@Test
public void findModificationsSince_shouldCacheResults() {
SvnMaterial material = MaterialsMother.svnMaterial();
MaterialRevision zero = saveOneScmModification(material, "user1", "file1");
MaterialRevision first = saveOneScmModification(material, "user1", "file1");
MaterialRevision second = saveOneScmModification(material, "user2", "file2");
MaterialRevision third = saveOneScmModification(material, "user2", "file2");
repo.findModificationsSince(material, first);
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
List<Modification> modifications = repo.findModificationsSince(material, first);
assertThat(modifications.size(), is(2));
assertEquals(third.getLatestModification(), modifications.get(0));
assertEquals(second.getLatestModification(), modifications.get(1));
verifyNoMoreInteractions(mockTemplate);
}
@Test
public void findLatestModifications_shouldCacheResults() {
SvnMaterial material = MaterialsMother.svnMaterial();
MaterialInstance materialInstance = material.createMaterialInstance();
repo.saveOrUpdate(materialInstance);
Modification mod = ModificationsMother.oneModifiedFile("file3");
mod.setId(8);
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
when(mockTemplate.execute(any())).thenReturn(mod);
repo.findLatestModification(materialInstance);
Modification modification = repo.findLatestModification(materialInstance);
assertSame(mod, modification);
verify(mockTemplate, times(1)).execute(any());
}
@Test
public void findLatestModifications_shouldQueryIfNotEnoughElementsInCache() {
SvnMaterial material = MaterialsMother.svnMaterial();
MaterialRevision mod = saveOneScmModification(material, "user2", "file3");
goCache.remove(repo.latestMaterialModificationsKey(repo.findMaterialInstance(material)));
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
when(mockTemplate.execute(any(HibernateCallback.class))).thenReturn(mod.getModification(0));
Modification modification = repo.findLatestModification(repo.findMaterialInstance(material));
assertThat(modification, is(mod.getLatestModification()));
verify(mockTemplate).execute(any(HibernateCallback.class));
}
@Test
public void findLatestModifications_shouldQueryIfNotEnoughElementsInCache_Integration() {
SvnMaterial material = MaterialsMother.svnMaterial();
MaterialRevision mod = saveOneScmModification(material, "user2", "file3");
goCache.clear();
Modification modification = repo.findLatestModification(repo.findMaterialInstance(material));
assertEquals(mod.getLatestModification(), modification);
}
@Test
public void shouldFindMaterialInstanceIfExists() throws Exception {
Material svn = MaterialsMother.svnMaterial();
MaterialInstance material1 = repo.findOrCreateFrom(svn);
MaterialInstance material2 = repo.findOrCreateFrom(svn);
assertThat(material1.getId(), is(material2.getId()));
}
@Test
public void materialShouldNotBeSameIfOneFieldIsNull() throws Exception {
Material svn1 = MaterialsMother.svnMaterial("url", null, "username", "password", false, null);
MaterialInstance material1 = repo.findOrCreateFrom(svn1);
Material svn2 = MaterialsMother.svnMaterial("url", null, null, null, false, null);
MaterialInstance material2 = repo.findOrCreateFrom(svn2);
assertThat(material1.getId(), not(is(material2.getId())));
}
@Test
public void findOrCreateFrom_shouldEnsureOnlyOneThreadCanCreateAtATime() throws Exception {
final Material svn = MaterialsMother.svnMaterial("url", null, "username", "password", false, null);
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo = new MaterialRepository(repo.getSessionFactory(), goCache, 200, transactionSynchronizationManager, materialConfigConverter, materialExpansionService, databaseStrategy) {
@Override
public MaterialInstance findMaterialInstance(Material material) {
MaterialInstance result = super.findMaterialInstance(material);
TestUtils.sleepQuietly(20); // force multiple threads to try to create the material
return result;
}
@Override
public void saveOrUpdate(MaterialInstance material) {
material.setId(10);
super.saveOrUpdate(material);
}
};
repo.setHibernateTemplate(mockTemplate);
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new Runnable() {
public void run() {
repo.findOrCreateFrom(svn);
}
}, "thread-" + i);
threads.add(thread);
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
verify(mockTemplate, times(1)).saveOrUpdate(Mockito.<MaterialInstance>any());
}
@Test
public void findOrCreateFrom_shouldCacheMaterialInstanceOnCreate() throws Exception {
Material svn = MaterialsMother.svnMaterial("url", null, "username", "password", false, null);
MaterialInstance instance = repo.findOrCreateFrom(svn);
assertThat(instance, is(notNullValue()));
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
MaterialInstance cachedInstance = repo.findMaterialInstance(svn);
assertSame(instance, cachedInstance);
verifyNoMoreInteractions(mockTemplate);
}
@Test
public void findMaterialInstance_shouldCacheMaterialInstance() throws Exception {
Material svn1 = MaterialsMother.svnMaterial("url", null, "username", "password", false, null);
repo.saveOrUpdate(svn1.createMaterialInstance());
MaterialInstance instance = repo.findMaterialInstance(svn1);
HibernateTemplate mockTemplate = mock(HibernateTemplate.class);
repo.setHibernateTemplate(mockTemplate);
MaterialInstance cachedInstance = repo.findMaterialInstance(svn1);
assertSame(instance, cachedInstance);
verifyNoMoreInteractions(mockTemplate);
}
@Test
public void shouldMaterialCacheKeyShouldReturnTheSameInstance() {
Material svn = MaterialsMother.svnMaterial("url", null, "username", "password", false, null);
assertSame(repo.materialKey(svn), repo.materialKey(svn));
}
@Test
public void shouldBeAbleToPersistAMaterialWithNullBooleans() throws Exception {
P4Material p4Material = new P4Material("serverAndPort", "view");
MaterialInstance original = p4Material.createMaterialInstance();
repo.saveOrUpdate(original);
MaterialInstance loaded = repo.find(original.getId());
Material restored = loaded.toOldMaterial(null, null, null);
assertThat(restored, is(p4Material));
}
@Test
public void shouldPersistModificationsWithMaterials() throws Exception {
MaterialInstance original = new SvnMaterialInstance("url", "username", UUID.randomUUID().toString(), false);
repo.saveOrUpdate(original);
MaterialInstance loaded = repo.find(original.getId());
assertThat(loaded, is(original));
}
@Test
public void shouldPersistModifiedFiles() throws Exception {
MaterialInstance original = new SvnMaterialInstance("url", "username", UUID.randomUUID().toString(), true);
Modification modification = new Modification("user", "comment", "email", new Date(), ModificationsMother.nextRevision());
modification.createModifiedFile("file1", "folder1", ModifiedAction.added);
modification.createModifiedFile("file2", "folder2", ModifiedAction.deleted);
repo.saveOrUpdate(original);
MaterialInstance loaded = repo.find(original.getId());
assertThat(loaded, is(original));
}
@Test
public void shouldBeAbleToFindModificationsSinceAPreviousChange() throws Exception {
SvnMaterial original = MaterialsMother.svnMaterial();
MaterialRevision originalRevision = saveOneScmModification(original, "user1", "file1");
MaterialRevision later = saveOneScmModification(original, "user2", "file2");
List<Modification> modifications = repo.findModificationsSince(original, originalRevision);
assertEquals(later.getLatestModification(), modifications.get(0));
}
@Test
public void shouldFindNoModificationsSinceLatestChange() throws Exception {
SvnMaterial original = MaterialsMother.svnMaterial();
MaterialRevision originalRevision = saveOneScmModification(original, "user", "file1");
List<Modification> modifications = repo.findModificationsSince(original, originalRevision);
assertThat(modifications.size(), is(0));
}
@Test
public void materialsShouldBeSerializable() throws Exception {
SvnMaterial svnMaterial = MaterialsMother.svnMaterial();
Modification modification = new Modification("user", "comment", "email", new Date(), "revision");
modification.createModifiedFile("file1", "folder1", ModifiedAction.added);
modification.createModifiedFile("file2", "folder2", ModifiedAction.deleted);
final MaterialRevision materialRevision = new MaterialRevision(svnMaterial, modification);
MaterialInstance materialInstance = (MaterialInstance) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return repo.saveMaterialRevision(materialRevision);
}
});
List<Modification> mods = repo.findMaterialRevisionsForMaterial(materialInstance.getId());
List<Modification> deserialized = (List<Modification>) SerializationTester.serializeAndDeserialize(mods);
assertThat(deserialized, is(mods));
}
@Test
public void hasPipelineEverRunWith() {
HgMaterial hgMaterial = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision materialRevision = saveOneScmModification(hgMaterial, "user", "file");
PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(hgMaterial.config()), "dev");
MaterialRevisions materialRevisions = new MaterialRevisions(materialRevision);
Pipeline pipeline = instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(materialRevisions, Username.ANONYMOUS),
new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider());
pipelineSqlMapDao.save(pipeline);
MaterialRevisions revisions = new MaterialRevisions(new MaterialRevision(hgMaterial, materialRevision.getLatestModification()));
assertThat(repo.hasPipelineEverRunWith("mingle", revisions), is(true));
}
@Test
public void hasPipelineEverRunWithIsFalseWhenThereAreNewerModificationsThatHaveNotBeenBuilt() {
HgMaterial hgMaterial = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision materialRevision = saveOneScmModification(hgMaterial, "user", "file");
PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(hgMaterial.config()), "dev");
MaterialRevisions materialRevisions = new MaterialRevisions(materialRevision);
Pipeline pipeline = instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(materialRevisions, Username.ANONYMOUS),
new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider());
pipelineSqlMapDao.save(pipeline);
MaterialRevision notBuiltRevision = saveOneScmModification(hgMaterial, "user", "file2");
MaterialRevisions revisions = new MaterialRevisions(new MaterialRevision(hgMaterial, notBuiltRevision.getLatestModification()));
assertThat(repo.hasPipelineEverRunWith("mingle", revisions), is(false));
}
@Test
public void hasPipelineEverRunWithMultipleMaterials() {
HgMaterial hgMaterial = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision hgMaterialRevision = saveOneScmModification(hgMaterial, "user", "file");
DependencyMaterial depMaterial = new DependencyMaterial(new CaseInsensitiveString("blahPipeline"), new CaseInsensitiveString("blahStage"));
MaterialRevision depMaterialRevision = saveOneDependencyModification(depMaterial, "blahPipeline/1/blahStage/1");
PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(hgMaterial.config(), depMaterial.config()), "dev");
MaterialRevisions materialRevisions = new MaterialRevisions(hgMaterialRevision, depMaterialRevision);
Pipeline pipeline = instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(materialRevisions, Username.ANONYMOUS), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider());
pipelineSqlMapDao.save(pipeline);
MaterialRevisions revisions = new MaterialRevisions(new MaterialRevision(depMaterial, depMaterialRevision.getLatestModification()),
new MaterialRevision(hgMaterial, hgMaterialRevision.getLatestModification()));
assertThat(repo.hasPipelineEverRunWith("mingle", revisions), is(true));
}
@Test
public void hasPipelineEverRunWithMultipleMaterialsAndMultipleRuns() {
HgMaterial hgMaterial1 = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision hgMaterialRevision1 = saveOneScmModification(hgMaterial1, "user", "file");
DependencyMaterial depMaterial1 = new DependencyMaterial(new CaseInsensitiveString("blahPipeline"), new CaseInsensitiveString("blahStage"));
MaterialRevision depMaterialRevision1 = saveOneDependencyModification(depMaterial1, "blahPipeline/1/blahStage/1");
PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(hgMaterial1.config(), depMaterial1.config()), "dev");
MaterialRevisions materialRevisions1 = new MaterialRevisions(hgMaterialRevision1, depMaterialRevision1);
pipelineSqlMapDao.save(instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(materialRevisions1, Username.ANONYMOUS), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider()));
HgMaterial hgMaterial2 = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision hgMaterialRevision2 = saveOneScmModification(hgMaterial2, "user", "file");
DependencyMaterial depMaterial2 = new DependencyMaterial(new CaseInsensitiveString("blahPipeline"), new CaseInsensitiveString("blahStage"));
MaterialRevision depMaterialRevision2 = saveOneDependencyModification(depMaterial2, "blahPipeline/2/blahStage/1");
PipelineConfig pipelineConfig2 = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(hgMaterial2.config(), depMaterial2.config()), "dev");
MaterialRevisions materialRevisions2 = new MaterialRevisions(hgMaterialRevision2, depMaterialRevision2);
savePipeline(instanceFactory.createPipelineInstance(pipelineConfig2, BuildCause.createManualForced(materialRevisions2, Username.ANONYMOUS), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider()));
MaterialRevisions revisions = new MaterialRevisions(new MaterialRevision(depMaterial1, depMaterialRevision1.getLatestModification()),
new MaterialRevision(hgMaterial2, hgMaterialRevision2.getLatestModification()));
assertThat(repo.hasPipelineEverRunWith("mingle", revisions), is(true));
}
private Pipeline savePipeline(Pipeline pipeline) {
Integer lastCount = pipelineSqlMapDao.getCounterForPipeline(pipeline.getName());
pipeline.updateCounter(lastCount);
pipelineSqlMapDao.insertOrUpdatePipelineCounter(pipeline, lastCount, pipeline.getCounter());
return pipelineSqlMapDao.save(pipeline);
}
@Test
public void hasPipelineEverRunWithMultipleMaterialsAndNewChanges() {
HgMaterial material = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision hgMaterialRevision = saveOneScmModification(material, "user", "file");
DependencyMaterial depMaterial = new DependencyMaterial(new CaseInsensitiveString("blahPipeline"), new CaseInsensitiveString("blahStage"));
MaterialRevision depMaterialRevision = saveOneDependencyModification(depMaterial, "blahPipeline/1/blahStage/1");
PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(material.config(), depMaterial.config()), "dev");
MaterialRevisions revisions = new MaterialRevisions(hgMaterialRevision, depMaterialRevision);
pipelineSqlMapDao.save(instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(revisions, Username.ANONYMOUS), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider()));
MaterialRevision laterRevision = saveOneScmModification(material, "user", "file");
MaterialRevisions newRevisions = new MaterialRevisions(depMaterialRevision, laterRevision);
assertThat(repo.hasPipelineEverRunWith("mingle", newRevisions), is(false));
}
@Test
public void hasPipelineEverRunWithMultipleMaterialsInPeggedRevisionsCase() {
HgMaterial firstMaterial = MaterialsMother.hgMaterial("first", "dest");
MaterialRevision first1 = saveOneScmModification("first1", firstMaterial, "user", "file", "comment");
MaterialRevision first2 = saveOneScmModification("first2", firstMaterial, "user", "file", "comment");
HgMaterial secondMaterial = MaterialsMother.hgMaterial("second", "dest");
MaterialRevision second1 = saveOneScmModification("second1", secondMaterial, "user", "file", "comment");
MaterialRevision second2 = saveOneScmModification("second2", secondMaterial, "user", "file", "comment");
MaterialRevisions firstRun = new MaterialRevisions(first1, second2);
MaterialRevisions secondRun = new MaterialRevisions(first2, second1);
PipelineConfig config = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(firstMaterial.config(), secondMaterial.config()), "dev");
savePipeline(instanceFactory.createPipelineInstance(config, BuildCause.createWithModifications(firstRun, "Pavan"), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5, new TimeProvider()));
savePipeline(instanceFactory.createPipelineInstance(config, BuildCause.createWithModifications(secondRun, "Shilpa-who-gets-along-well-with-her"), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider()));
assertThat(repo.hasPipelineEverRunWith("mingle", new MaterialRevisions(first2, second2)), is(true));
}
@Test
public void hasPipelineEverRunWith_shouldCacheResultsForPipelineNameMaterialIdAndModificationId() {
HgMaterial hgMaterial = MaterialsMother.hgMaterial("hgUrl", "dest");
MaterialRevision materialRevision = saveOneScmModification(hgMaterial, "user", "file");
PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(hgMaterial.config()), "dev");
MaterialRevisions materialRevisions = new MaterialRevisions(materialRevision);
Pipeline pipeline = instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(materialRevisions, Username.ANONYMOUS), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider());
GoCache spyGoCache = spy(goCache);
when(spyGoCache.get(any(String.class))).thenCallRealMethod();
Mockito.doCallRealMethod().when(spyGoCache).put(any(String.class), any(Object.class));
repo = new MaterialRepository(sessionFactory, spyGoCache, 2, transactionSynchronizationManager, materialConfigConverter, materialExpansionService, databaseStrategy);
pipelineSqlMapDao.save(pipeline);
MaterialRevisions revisions = new MaterialRevisions(new MaterialRevision(hgMaterial, materialRevision.getLatestModification()));
assertThat("should hit the db and cache it",
repo.hasPipelineEverRunWith("mingle", revisions), is(true));
assertThat("should have cached the result on the previous call",
repo.hasPipelineEverRunWith("mingle", revisions), is(true));
verify(spyGoCache, times(1)).put(any(String.class), eq(Boolean.TRUE));
}
@Test
public void shouldSavePipelineMaterialRevisions() throws Exception {
SvnMaterialConfig svnMaterialConfig = MaterialConfigsMother.svnMaterialConfig("gitUrl", "folder", "user", "pass", true, "*.doc");
assertCanLoadAndSaveMaterialRevisionsFor(svnMaterialConfig);
}
@Test
public void shouldSaveGitPipelineMaterialRevisions() throws Exception {
GitMaterialConfig gitMaterialConfig = MaterialConfigsMother.gitMaterialConfig("gitUrl", "submoduleFolder", "branch", false);
assertCanLoadAndSaveMaterialRevisionsFor(gitMaterialConfig);
}
@Test
public void shouldSaveHgPipelineMaterialRevisions() throws Exception {
HgMaterialConfig hgMaterialConfig = MaterialConfigsMother.hgMaterialConfig("hgUrl", "dest");
assertCanLoadAndSaveMaterialRevisionsFor(hgMaterialConfig);
}
@Test
public void shouldSaveP4PipelineMaterialRevisions() throws Exception {
P4MaterialConfig p4MaterialConfig = MaterialConfigsMother.p4MaterialConfig("serverAndPort", "user", "pwd", "view", true);
assertCanLoadAndSaveMaterialRevisionsFor(p4MaterialConfig);
}
@Test
public void shouldSaveDependencyPipelineMaterialRevisions() throws Exception {
DependencyMaterialConfig dependencyMaterialConfig = new DependencyMaterialConfig(new CaseInsensitiveString("pipeline"), new CaseInsensitiveString("stage"));
assertCanLoadAndSaveMaterialRevisionsFor(dependencyMaterialConfig);
}
@Test
public void shouldReturnModificationForASpecificRevision() throws Exception {
DependencyMaterial dependencyMaterial = new DependencyMaterial(new CaseInsensitiveString("blahPipeline"), new CaseInsensitiveString("blahStage"));
MaterialRevision originalRevision = saveOneDependencyModification(dependencyMaterial, "blahPipeline/3/blahStage/1");
Modification modification = repo.findModificationWithRevision(dependencyMaterial, "blahPipeline/3/blahStage/1");
assertThat(modification.getRevision(), is("blahPipeline/3/blahStage/1"));
assertEquals(originalRevision.getModification(0).getModifiedTime(), modification.getModifiedTime());
}
@Test
public void shouldPickupTheRightFromAndToForMaterialRevisions() throws Exception {
HgMaterial material = new HgMaterial("sdg", null);
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(modification("6")));
saveMaterialRev(firstRevision);
final MaterialRevision secondRevision = new MaterialRevision(material, new Modifications(modification("10"), modification("12"), modification("13")));
saveMaterialRev(secondRevision);
final Pipeline pipeline = createPipeline();
savePMR(secondRevision, pipeline);
List<Modification> modificationsSince = repo.findModificationsSince(material, firstRevision);
assertThat(modificationsSince.get(0).getRevision(), is("10"));
assertThat(modificationsSince.get(modificationsSince.size() - 1).getRevision(), is("13"));
}
@Test
public void shouldUseToAndFromAsRangeForSCMMaterialRevisionWhileSavingAndUpdating() throws Exception {
HgMaterial material = new HgMaterial("sdg", null);
final MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(modification("10"), modification("9"), modification("8")));
saveMaterialRev(firstRevision);
final Pipeline firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
MaterialRevisions revisionsFor11 = repo.findMaterialRevisionsForPipeline(firstPipeline.getId());
assertThat(revisionsFor11.getModifications(material).size(), is(3));
assertThat(revisionsFor11.getModifications(material).get(0).getRevision(), is("10"));
assertThat(revisionsFor11.getModifications(material).get(1).getRevision(), is("9"));
assertThat(revisionsFor11.getModifications(material).get(2).getRevision(), is("8"));
MaterialRevision secondRevision = new MaterialRevision(material, new Modifications(modification("11"), modification("10.5")));
saveMaterialRev(secondRevision);
Pipeline secondPipeline = createPipeline();
savePMR(secondRevision, secondPipeline);
MaterialRevisions revisionsFor12 = repo.findMaterialRevisionsForPipeline(secondPipeline.getId());
assertThat(revisionsFor12.getModifications(material).size(), is(2));
assertThat(revisionsFor12.getModifications(material).get(0).getRevision(), is("11"));
assertThat(revisionsFor12.getModifications(material).get(1).getRevision(), is("10.5"));
MaterialRevision thirdRevision = new MaterialRevision(material, new Modifications(modification("12")));
saveMaterialRev(thirdRevision);
Pipeline thirdPipeline = createPipeline();
savePMR(thirdRevision, thirdPipeline);
MaterialRevisions revisionsFor13 = repo.findMaterialRevisionsForPipeline(thirdPipeline.getId());
assertThat(revisionsFor13.getModifications(material).size(), is(1));
assertThat(revisionsFor13.getModifications(material).get(0).getRevision(), is("12"));
}
@Test
public void shouldFixToAsFromForDependencyMaterialRevisionWhileSavingAndUpdating() throws Exception {
Material material = new DependencyMaterial(new CaseInsensitiveString("pipeline_name"), new CaseInsensitiveString("stage_name"));
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(modification("pipeline_name/10/stage_name/1"), modification("pipeline_name/9/stage_name/2"), modification("pipeline_name/8/stage_name/2")));
saveMaterialRev(firstRevision);
Pipeline firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
MaterialRevisions revisionsFor11 = repo.findMaterialRevisionsForPipeline(firstPipeline.getId());
assertThat(revisionsFor11.getModifications(material).size(), is(1));
assertThat(revisionsFor11.getModifications(material).get(0).getRevision(), is("pipeline_name/10/stage_name/1"));
MaterialRevision secondRevision = new MaterialRevision(material, new Modifications(modification("pipeline_name/11/stage_name/2"), modification("pipeline_name/11/stage_name/1")));
saveMaterialRev(secondRevision);
Pipeline secondPipeline = createPipeline();
savePMR(secondRevision, secondPipeline);
MaterialRevisions revisionsFor12 = repo.findMaterialRevisionsForPipeline(secondPipeline.getId());
assertThat(revisionsFor12.getModifications(material).size(), is(1));
assertThat(revisionsFor12.getModifications(material).get(0).getRevision(), is("pipeline_name/11/stage_name/2"));
MaterialRevision thirdRevision = new MaterialRevision(material, new Modifications(modification("pipeline_name/12/stage_name/1")));
saveMaterialRev(thirdRevision);
Pipeline thirdPipeline = createPipeline();
savePMR(thirdRevision, thirdPipeline);
savePMR(thirdRevision, thirdPipeline);
MaterialRevisions revisionsFor13 = repo.findMaterialRevisionsForPipeline(thirdPipeline.getId());
assertThat(revisionsFor13.getModifications(material).size(), is(1));
assertThat(revisionsFor13.getModifications(material).get(0).getRevision(), is("pipeline_name/12/stage_name/1"));
}
@Test
public void shouldPersistActualFromRevisionSameAsFromForSCMMaterial() throws Exception {
HgMaterial material = new HgMaterial("sdg", null);
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(modification("10"), modification("9"), modification("8")));
saveMaterialRev(firstRevision);
Pipeline firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
List<PipelineMaterialRevision> pmrs = repo.findPipelineMaterialRevisions(firstPipeline.getId());
assertThat(pmrs.get(0).getActualFromRevisionId(), is(pmrs.get(0).getFromModification().getId()));
}
@Test
public void shouldPersistActualFromRevisionUsingTheRealFromForDependencyMaterial() throws Exception {
Material material = new DependencyMaterial(new CaseInsensitiveString("pipeline_name"), new CaseInsensitiveString("stage_name"));
Modification actualFrom = modification("pipeline_name/8/stage_name/2");
Modification from = modification("pipeline_name/10/stage_name/1");
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(from, modification("pipeline_name/9/stage_name/2"), actualFrom));
saveMaterialRev(firstRevision);
Pipeline firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
List<PipelineMaterialRevision> pmrs = repo.findPipelineMaterialRevisions(firstPipeline.getId());
assertThat(pmrs.get(0).getActualFromRevisionId(), is(actualFrom.getId()));
assertEquals(from, pmrs.get(0).getFromModification());
}
@Test
public void shouldUseTheFromIdAsActualFromIdWhenThePipelineIsBeingBuiltForTheFirstTime() throws Exception {
Material material = new DependencyMaterial(new CaseInsensitiveString("pipeline_name"), new CaseInsensitiveString("stage_name"));
Modification actualFrom = modification("pipeline_name/8/stage_name/2");
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(modification("pipeline_name/9/stage_name/2"), actualFrom));
saveMaterialRev(firstRevision);
HgMaterial hgMaterial = new HgMaterial("sdg", null);
MaterialRevision hgRevision = new MaterialRevision(hgMaterial, new Modifications(modification("10"), modification("9")));
saveMaterialRev(hgRevision);
Modification from = modification("pipeline_name/10/stage_name/1");
firstRevision = new MaterialRevision(material, new Modifications(from));
saveMaterialRev(firstRevision);
Pipeline firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
List<PipelineMaterialRevision> pmrs = repo.findPipelineMaterialRevisions(firstPipeline.getId());
assertThat(pmrs.get(0).getActualFromRevisionId(), is(from.getId()));
assertEquals(from, pmrs.get(0).getFromModification());
}
@Test
public void shouldPersistActualFromRevisionForSameRevisionOfDependencyMaterialModifications() throws Exception {
Material material = new DependencyMaterial(new CaseInsensitiveString("pipeline_name"), new CaseInsensitiveString("stage_name"));
Modification actualFrom = modification("pipeline_name/8/stage_name/2");
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(actualFrom));
saveMaterialRev(firstRevision);
Pipeline firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
firstPipeline = createPipeline();
savePMR(firstRevision, firstPipeline);
List<PipelineMaterialRevision> pmrs = repo.findPipelineMaterialRevisions(firstPipeline.getId());
assertThat(pmrs.get(0).getActualFromRevisionId(), is(actualFrom.getId()));
assertEquals(actualFrom, pmrs.get(0).getFromModification());
}
@Test
public void shouldUpdatePipelineMaterialRevisions() throws Exception {
HgMaterial material = new HgMaterial("sdg", null);
Modification first = modification("6");
Modification second = modification("7");
MaterialRevision firstRevision = new MaterialRevision(material, new Modifications(second, first));
saveMaterialRev(firstRevision);
material.setId(repo.findMaterialInstance(material).getId());
MaterialRevision secondRevision = new MaterialRevision(material, new Modifications(first));
Pipeline secondPipeline = createPipeline();
savePMR(secondRevision, secondPipeline);
MaterialRevisions materialRevisions = repo.findMaterialRevisionsForPipeline(secondPipeline.getId());
assertEquals(secondRevision, materialRevisions.getMaterialRevision(0));
List<PipelineMaterialRevision> pipelineMaterialRevisions = repo.findPipelineMaterialRevisions(secondPipeline.getId());
assertThat(pipelineMaterialRevisions.get(0).getMaterialId(), is(material.getId()));
}
@Test
public void shouldReturnMaterialRevisionsWithEmptyModificationsWhenNoModifications() throws Exception {
Material material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevisions materialRevisions = repo.findLatestRevisions(new MaterialConfigs(material.config()));
assertThat(materialRevisions.numberOfRevisions(), is(1));
MaterialRevision materialRevision = materialRevisions.getMaterialRevision(0);
assertThat(materialRevision.getMaterial(), is(material));
assertThat(materialRevision.getModifications().size(), is(0));
}
@Test
public void shouldReturnMatchedRevisionsForAGivenSearchString() throws Exception {
ScmMaterial material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision materialRevision = saveOneScmModification("40c95a3c41f54b5fb3107982cf2acd08783f102a", material, "pavan", "meet_you_in_hell.txt", "comment");
saveOneScmModification(material, "turn_her", "of_course_he_will_be_there_first.txt");
List<MatchedRevision> revisions = repo.findRevisionsMatching(material.config(), "pavan");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), materialRevision.getLatestShortRevision(), materialRevision.getLatestRevisionString(), "pavan", materialRevision.getDateOfLatestModification(), "comment");
}
@Test
public void shouldMatchPipelineLabelForDependencyModifications() throws Exception {
DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("pipeline-name"), new CaseInsensitiveString("stage-name"));
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision first = saveOneDependencyModification(material, "pipeline-name/1/stage-name/3", "my-random-label-123");
MaterialRevision second = saveOneDependencyModification(material, "pipeline-name/3/stage-name/1", "other-label-456");
List<MatchedRevision> revisions = repo.findRevisionsMatching(material.config(), "my-random");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), first.getLatestShortRevision(), first.getLatestRevisionString(), null, first.getDateOfLatestModification(), "my-random-label-123");
revisions = repo.findRevisionsMatching(material.config(), "other-label");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), second.getLatestShortRevision(), second.getLatestRevisionString(), null, second.getDateOfLatestModification(), "other-label-456");
revisions = repo.findRevisionsMatching(material.config(), "something-else");
assertThat(revisions.size(), is(0));
}
@Test
public void shouldMatchSearchStringAcrossColumn() throws Exception {
ScmMaterial material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision first = saveOneScmModification("40c95a3c41f54b5fb3107982cf2acd08783f102a", material, "pavan", "meet_you_in_hell.txt", "comment");
MaterialRevision second = saveOneScmModification("c30c471137f31a4bf735f653f888e799f6deec04", material, "turn_her", "of_course_he_will_be_there_first.txt", "comment");
List<MatchedRevision> revisions = repo.findRevisionsMatching(material.config(), "pavan co");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), first.getLatestShortRevision(), first.getLatestRevisionString(), "pavan", first.getDateOfLatestModification(), "comment");
revisions = repo.findRevisionsMatching(material.config(), "her co");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), second.getLatestShortRevision(), second.getLatestRevisionString(), "turn_her", second.getDateOfLatestModification(), "comment");
revisions = repo.findRevisionsMatching(material.config(), "of_curs");
assertThat(revisions.size(), is(0));
}
@Test
public void shouldMatchSearchStringInDecreasingOrder() throws Exception {
ScmMaterial material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision first = saveOneScmModification("40c95a3c41f54b5fb3107982cf2acd08783f102a", material, "pavan", "meet_you_in_hell.txt", "comment");
MaterialRevision second = saveOneScmModification("c30c471137f31a4bf735f653f888e799f6deec04", material, "turn_her", "of_course_he_will_be_there_first.txt", "comment");
List<MatchedRevision> revisions = repo.findRevisionsMatching(material.config(), "");
assertThat(revisions.size(), is(2));
assertMatchedRevision(revisions.get(0), second.getLatestShortRevision(), second.getLatestRevisionString(), "turn_her", second.getDateOfLatestModification(), "comment");
assertMatchedRevision(revisions.get(1), first.getLatestShortRevision(), first.getLatestRevisionString(), "pavan", first.getDateOfLatestModification(), "comment");
}
@Test
public void shouldConsiderFieldToBeEmptyWhenRevisionOrUsernameOrCommentIsNull() throws Exception {
ScmMaterial material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision userIsNullRevision = saveOneScmModification("40c95a3c41f54b5fb3107982cf2acd08783f102a", material, null, "meet_you_in_hell.txt", "bring it on!");
MaterialRevision commentIsNullRevision = saveOneScmModification("c30c471137f31a4bf735f653f888e799f6deec04", material, "turn_her", "lets_party_in_hell.txt", null);
List<MatchedRevision> revisions = repo.findRevisionsMatching(material.config(), "bring");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), userIsNullRevision.getLatestShortRevision(), userIsNullRevision.getLatestRevisionString(), null, userIsNullRevision.getDateOfLatestModification(), "bring it on!");
revisions = repo.findRevisionsMatching(material.config(), "c04 turn");
assertThat(revisions.size(), is(1));
assertMatchedRevision(revisions.get(0), commentIsNullRevision.getLatestShortRevision(), commentIsNullRevision.getLatestRevisionString(), "turn_her",
commentIsNullRevision.getDateOfLatestModification(), null);
revisions = repo.findRevisionsMatching(material.config(), "null");
assertThat(revisions.size(), is(0));
}
@Test
public void shouldFindLatestRevision() throws Exception {
ScmMaterial material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision first = saveOneScmModification("40c95a3c41f54b5fb3107982cf2acd08783f102a", material, "pavan", "meet_you_in_hell.txt", "comment");
MaterialRevision second = saveOneScmModification("c30c471137f31a4bf735f653f888e799f6deec04", material, "turn_her", "of_course_he_will_be_there_first.txt", "comment");
MaterialRevisions materialRevisions = repo.findLatestModification(material);
List<MaterialRevision> revisions = materialRevisions.getRevisions();
assertThat(revisions.size(), is(1));
MaterialRevision materialRevision = revisions.get(0);
assertThat(materialRevision.getLatestRevisionString(), is(second.getLatestRevisionString()));
}
@Test
public void shouldCacheModificationCountsForMaterialCorrectly() throws Exception {
ScmMaterial material = material();
MaterialInstance materialInstance = material.createMaterialInstance();
repo.saveOrUpdate(materialInstance);
saveOneScmModification("1", material, "user1", "1.txt", "comment1");
saveOneScmModification("2", material, "user2", "2.txt", "comment2");
saveOneScmModification("3", material, "user3", "3.txt", "comment3");
saveOneScmModification("4", material, "user4", "4.txt", "comment4");
saveOneScmModification("5", material, "user5", "5.txt", "comment5");
Long totalCount = repo.getTotalModificationsFor(materialInstance);
assertThat(totalCount, is(5L));
}
@Test
public void shouldCacheModificationsForMaterialCorrectly() throws Exception {
final ScmMaterial material = material();
MaterialInstance materialInstance = material.createMaterialInstance();
repo.saveOrUpdate(materialInstance);
saveOneScmModification("1", material, "user1", "1.txt", "comment1");
saveOneScmModification("2", material, "user2", "2.txt", "comment2");
saveOneScmModification("3", material, "user3", "3.txt", "comment3");
saveOneScmModification("4", material, "user4", "4.txt", "comment4");
saveOneScmModification("5", material, "user5", "5.txt", "comment5");
Long totalCount = repo.getTotalModificationsFor(materialInstance);
totalCount = (Long) goCache.get(repo.materialModificationCountKey(materialInstance));
final Modification modOne = new Modification("user", "comment", "email@gmail.com", new Date(), "123");
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
MaterialInstance foo = repo.findOrCreateFrom(material);
repo.saveModifications(foo, asList(modOne));
}
});
totalCount = (Long) goCache.get(repo.materialModificationCountKey(materialInstance));
assertThat(totalCount, is(nullValue()));
}
@Test
public void shouldGetPaginatedModificationsForMaterialCorrectly() throws Exception {
ScmMaterial material = material();
MaterialInstance materialInstance = material.createMaterialInstance();
repo.saveOrUpdate(materialInstance);
MaterialRevision first = saveOneScmModification("1", material, "user1", "1.txt", "comment1");
MaterialRevision second = saveOneScmModification("2", material, "user2", "2.txt", "comment2");
MaterialRevision third = saveOneScmModification("3", material, "user3", "3.txt", "comment3");
MaterialRevision fourth = saveOneScmModification("4", material, "user4", "4.txt", "comment4");
MaterialRevision fifth = saveOneScmModification("5", material, "user5", "5.txt", "comment5");
Modifications modifications = repo.getModificationsFor(materialInstance, Pagination.pageStartingAt(0, 5, 3));
assertThat(modifications.size(), is(3));
assertThat(modifications.get(0).getRevision(), is(fifth.getLatestRevisionString()));
assertThat(modifications.get(1).getRevision(), is(fourth.getLatestRevisionString()));
assertThat(modifications.get(2).getRevision(), is(third.getLatestRevisionString()));
modifications = repo.getModificationsFor(materialInstance, Pagination.pageStartingAt(3, 5, 3));
assertThat(modifications.size(), is(2));
assertThat(modifications.get(0).getRevision(), is(second.getLatestRevisionString()));
assertThat(modifications.get(1).getRevision(), is(first.getLatestRevisionString()));
}
@Test
public void shouldCachePaginatedModificationsForMaterialCorrectly() throws Exception {
final ScmMaterial material = material();
MaterialInstance materialInstance = material.createMaterialInstance();
repo.saveOrUpdate(materialInstance);
MaterialRevision first = saveOneScmModification("1", material, "user1", "1.txt", "comment1");
MaterialRevision second = saveOneScmModification("2", material, "user2", "2.txt", "comment2");
MaterialRevision third = saveOneScmModification("3", material, "user3", "3.txt", "comment3");
MaterialRevision fourth = saveOneScmModification("4", material, "user4", "4.txt", "comment4");
MaterialRevision fifth = saveOneScmModification("5", material, "user5", "5.txt", "comment5");
Pagination page = Pagination.pageStartingAt(0, 5, 3);
repo.getModificationsFor(materialInstance, page);
Modifications modificationsFromCache = (Modifications) goCache.get(repo.materialModificationsWithPaginationKey(materialInstance), repo.materialModificationsWithPaginationSubKey(page));
assertThat(modificationsFromCache.size(), is(3));
assertThat(modificationsFromCache.get(0).getRevision(), is(fifth.getLatestRevisionString()));
assertThat(modificationsFromCache.get(1).getRevision(), is(fourth.getLatestRevisionString()));
assertThat(modificationsFromCache.get(2).getRevision(), is(third.getLatestRevisionString()));
page = Pagination.pageStartingAt(1, 5, 3);
repo.getModificationsFor(materialInstance, page);
modificationsFromCache = (Modifications) goCache.get(repo.materialModificationsWithPaginationKey(materialInstance), repo.materialModificationsWithPaginationSubKey(page));
assertThat(modificationsFromCache.size(), is(3));
assertThat(modificationsFromCache.get(0).getRevision(), is(fourth.getLatestRevisionString()));
assertThat(modificationsFromCache.get(1).getRevision(), is(third.getLatestRevisionString()));
assertThat(modificationsFromCache.get(2).getRevision(), is(second.getLatestRevisionString()));
page = Pagination.pageStartingAt(3, 5, 3);
repo.getModificationsFor(materialInstance, page);
modificationsFromCache = (Modifications) goCache.get(repo.materialModificationsWithPaginationKey(materialInstance), repo.materialModificationsWithPaginationSubKey(page));
assertThat(modificationsFromCache.size(), is(2));
assertThat(modificationsFromCache.get(0).getRevision(), is(second.getLatestRevisionString()));
assertThat(modificationsFromCache.get(1).getRevision(), is(first.getLatestRevisionString()));
final Modification modOne = new Modification("user", "comment", "email@gmail.com", new Date(), "123");
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
MaterialInstance foo = repo.findOrCreateFrom(material);
repo.saveModifications(foo, asList(modOne));
}
});
modificationsFromCache = (Modifications) goCache.get(repo.materialModificationsWithPaginationKey(materialInstance), repo.materialModificationsWithPaginationSubKey(Pagination.pageStartingAt(0, 5, 3)));
assertThat(modificationsFromCache, is(nullValue()));
modificationsFromCache = (Modifications) goCache.get(repo.materialModificationsWithPaginationKey(materialInstance), repo.materialModificationsWithPaginationSubKey(Pagination.pageStartingAt(3, 5, 3)));
assertThat(modificationsFromCache, is(nullValue()));
}
@Test
public void shouldFindlatestModificationRunByPipeline() {
ScmMaterial material = material();
repo.saveOrUpdate(material.createMaterialInstance());
MaterialRevision first = saveOneScmModification("40c95a3c41f54b5fb3107982cf2acd08783f102a", material, "pavan", "meet_you_in_hell.txt", "comment");
MaterialRevision second = saveOneScmModification("c30c471137f31a4bf735f653f888e799f6deec04", material, "turn_her", "of_course_he_will_be_there_first.txt", "comment");
Pipeline pipeline = createPipeline();
savePMR(first, pipeline);
savePMR(second, pipeline);
Long latestModId = repo.latestModificationRunByPipeline(new CaseInsensitiveString(pipeline.getName()), material);
assertThat(latestModId, is(second.getLatestModification().getId()));
}
@Test
public void shouldFindModificationsForAStageIdentifier() {
DependencyMaterial material = new DependencyMaterial(new CaseInsensitiveString("P1"), new CaseInsensitiveString("S1"));
repo.saveOrUpdate(material.createMaterialInstance());
saveOneDependencyModification(material, "P1/1/S1/1");
saveOneDependencyModification(material, "P1/2/S1/1");
saveOneDependencyModification(material, "P1/1/S2/1");
saveOneDependencyModification(material, "P2/1/S1/1");
StageIdentifier stageIdentifier = new StageIdentifier("P1", 2, "2", "S1", "1");
List<Modification> modifications = repo.modificationFor(stageIdentifier);
assertThat(modifications.size(), is(1));
assertThat(modifications.get(0).getRevision(), is("P1/2/S1/1"));
assertThat(goCache.get(repo.cacheKeyForModificationsForStageLocator(stageIdentifier)), is(modifications));
StageIdentifier p2_s1_stageId = new StageIdentifier("P2", 1, "S1", "1");
List<Modification> mod_p2_s1 = repo.modificationFor(p2_s1_stageId);
assertThat(goCache.get(repo.cacheKeyForModificationsForStageLocator(p2_s1_stageId)), is(mod_p2_s1));
StageIdentifier p2_s1_3 = new StageIdentifier("P2", 1, "S1", "3");
assertThat(repo.modificationFor(p2_s1_3).isEmpty(), is(true));
assertThat(goCache.get(repo.cacheKeyForModificationsForStageLocator(p2_s1_3)), is(nullValue()));
}
@Test
public void shouldSavePackageMaterialInstance() {
PackageMaterial material = new PackageMaterial();
PackageRepository repository = PackageRepositoryMother.create("repo-id", "repo", "pluginid", "version", new Configuration(ConfigurationPropertyMother.create("k1", false, "v1")));
material.setPackageDefinition(PackageDefinitionMother.create("p-id", "name", new Configuration(ConfigurationPropertyMother.create("k2", false, "v2")), repository));
PackageMaterialInstance savedMaterialInstance = (PackageMaterialInstance) repo.findOrCreateFrom(material);
assertThat(savedMaterialInstance.getId() > 0, is(true));
assertThat(savedMaterialInstance.getFingerprint(), is(material.getFingerprint()));
assertThat(JsonHelper.fromJson(savedMaterialInstance.getConfiguration(), PackageMaterial.class).getPackageDefinition().getConfiguration(), is(material.getPackageDefinition().getConfiguration()));
assertThat(JsonHelper.fromJson(savedMaterialInstance.getConfiguration(), PackageMaterial.class).getPackageDefinition().getRepository().getPluginConfiguration().getId(), is(material.getPackageDefinition().getRepository().getPluginConfiguration().getId()));
assertThat(JsonHelper.fromJson(savedMaterialInstance.getConfiguration(), PackageMaterial.class).getPackageDefinition().getRepository().getConfiguration(), is(material.getPackageDefinition().getRepository().getConfiguration()));
}
@Test
public void shouldSavePluggableSCMMaterialInstance() {
PluggableSCMMaterial material = new PluggableSCMMaterial();
ConfigurationProperty k1 = ConfigurationPropertyMother.create("k1", false, "v1");
ConfigurationProperty k2 = ConfigurationPropertyMother.create("k2", true, "v2");
material.setSCMConfig(SCMMother.create("scm-id", "scm-name", "plugin-id", "1.0", new Configuration(k1, k2)));
PluggableSCMMaterialInstance savedMaterialInstance = (PluggableSCMMaterialInstance) repo.findOrCreateFrom(material);
assertThat(savedMaterialInstance.getId() > 0, is(true));
assertThat(savedMaterialInstance.getFingerprint(), is(material.getFingerprint()));
assertThat(JsonHelper.fromJson(savedMaterialInstance.getConfiguration(), PluggableSCMMaterial.class).getScmConfig().getConfiguration(), is(material.getScmConfig().getConfiguration()));
assertThat(JsonHelper.fromJson(savedMaterialInstance.getConfiguration(), PluggableSCMMaterial.class).getScmConfig().getPluginConfiguration().getId(), is(material.getScmConfig().getPluginConfiguration().getId()));
}
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldRemoveDuplicatesBeforeInsertingModifications() {
final MaterialInstance materialInstance = repo.findOrCreateFrom(new GitMaterial(UUID.randomUUID().toString(), "branch"));
final ArrayList<Modification> firstSetOfModifications = getModifications(3);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, firstSetOfModifications);
return null;
}
});
Modifications firstSetOfModificationsFromDb = repo.getModificationsFor(materialInstance, Pagination.pageByNumber(1, 10, 10));
assertThat(firstSetOfModificationsFromDb.size(), is(3));
for (Modification modification : firstSetOfModifications) {
assertThat(firstSetOfModificationsFromDb.containsRevisionFor(modification), is(true));
}
final ArrayList<Modification> secondSetOfModificationsContainingDuplicateRevisions = getModifications(4);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, secondSetOfModificationsContainingDuplicateRevisions);
return null;
}
});
Modifications secondSetOfModificationsFromDb = repo.getModificationsFor(materialInstance, Pagination.pageByNumber(1, 10, 10));
assertThat(secondSetOfModificationsFromDb.size(), is(4));
for (final Modification fromPreviousCycle : firstSetOfModificationsFromDb) {
Modification modification = ListUtil.find(secondSetOfModificationsFromDb, new ListUtil.Condition() {
@Override
public <T> boolean isMet(T item) {
Modification modification = (Modification) item;
return modification.getId() == fromPreviousCycle.getId();
}
});
assertThat(modification, is(notNullValue()));
}
for (Modification modification : secondSetOfModificationsContainingDuplicateRevisions) {
assertThat(secondSetOfModificationsFromDb.containsRevisionFor(modification), is(true));
}
}
@Test
public void shouldNotBlowUpReportErrorIfAnAttemptIsMadeToInsertOnlyDuplicateModificationsForAGivenMaterial() {
final MaterialInstance materialInstance = repo.findOrCreateFrom(new GitMaterial(UUID.randomUUID().toString(), "branch"));
final ArrayList<Modification> firstSetOfModifications = getModifications(3);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, firstSetOfModifications);
return null;
}
});
Modifications firstSetOfModificationsFromDb = repo.getModificationsFor(materialInstance, Pagination.pageByNumber(1, 10, 10));
assertThat(firstSetOfModificationsFromDb.size(), is(3));
for (Modification modification : firstSetOfModifications) {
assertThat(firstSetOfModificationsFromDb.containsRevisionFor(modification), is(true));
}
final ArrayList<Modification> secondSetOfModificationsContainingAllDuplicateRevisions = getModifications(3);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, secondSetOfModificationsContainingAllDuplicateRevisions);
return null;
}
});
}
@Test
public void shouldAllowSavingModificationsIfRevisionsAcrossDifferentMaterialsHappenToBeSame() {
final MaterialInstance materialInstance1 = repo.findOrCreateFrom(new GitMaterial(UUID.randomUUID().toString(), "branch"));
final MaterialInstance materialInstance2 = repo.findOrCreateFrom(new GitMaterial(UUID.randomUUID().toString(), "branch"));
final ArrayList<Modification> modificationsForFirstMaterial = getModifications(3);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance1, modificationsForFirstMaterial);
return null;
}
});
assertThat(repo.getModificationsFor(materialInstance1, Pagination.pageByNumber(1, 10, 10)).size(), is(3));
final ArrayList<Modification> modificationsForSecondMaterial = getModifications(3);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance2, modificationsForSecondMaterial);
return null;
}
});
Modifications modificationsFromDb = repo.getModificationsFor(materialInstance2, Pagination.pageByNumber(1, 10, 10));
assertThat(modificationsFromDb.size(), is(3));
for (Modification modification : modificationsForSecondMaterial) {
assertThat(modificationsFromDb.containsRevisionFor(modification), is(true));
}
}
@Test
public void shouldNotSaveAndClearCacheWhenThereAreNoNewModifications() {
final MaterialInstance materialInstance = repo.findOrCreateFrom(new GitMaterial(UUID.randomUUID().toString(), "branch"));
String key = repo.materialModificationsWithPaginationKey(materialInstance);
String subKey = repo.materialModificationsWithPaginationSubKey(Pagination.ONE_ITEM);
goCache.put(key, subKey, new Modifications(new Modification()));
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, new ArrayList<>());
return null;
}
});
assertThat(goCache.get(key, subKey), is(notNullValue()));
}
//Slow test - takes ~1 min to run. Will remove if it causes issues. - Jyoti
@Test
public void shouldBeAbleToHandleLargeNumberOfModifications() {
final MaterialInstance materialInstance = repo.findOrCreateFrom(new GitMaterial(UUID.randomUUID().toString(), "branch"));
int count = 10000;
final ArrayList<Modification> firstSetOfModifications = getModifications(count);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, firstSetOfModifications);
return null;
}
});
assertThat(repo.getTotalModificationsFor(materialInstance), is(new Long(count)));
final ArrayList<Modification> secondSetOfModifications = getModifications(count + 1);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveModifications(materialInstance, secondSetOfModifications);
return null;
}
});
assertThat(repo.getTotalModificationsFor(materialInstance), is(new Long(count+1)));
}
private ArrayList<Modification> getModifications(int count) {
final ArrayList<Modification> modifications = new ArrayList<>();
for (int i = 0; i < count; i++) {
modifications.add(new Modification("user", "comment", "email", new Date(), "r" + i));
}
return modifications;
}
private MaterialRevision saveOneDependencyModification(DependencyMaterial dependencyMaterial, String revision) {
return saveOneDependencyModification(dependencyMaterial, revision, "MOCK_LABEL-12");
}
private MaterialRevision saveOneDependencyModification(final DependencyMaterial dependencyMaterial, final String revision, final String label) {
return (MaterialRevision) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Modification modification = new Modification(new Date(), revision, label, null);
MaterialRevision originalRevision = new MaterialRevision(dependencyMaterial, modification);
repo.save(new MaterialRevisions(originalRevision));
return originalRevision;
}
});
}
private MaterialInstance saveMaterialRev(final MaterialRevision rev) {
return (MaterialInstance) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return repo.saveMaterialRevision(rev);
}
});
}
private Pipeline createPipeline() {
Pipeline pipeline = PipelineMother.pipeline("pipeline", StageMother.custom("stage"));
pipeline.getBuildCause().setMaterialRevisions(new MaterialRevisions());
return savePipeline(pipeline);
}
private void savePMR(final MaterialRevision revision, final Pipeline pipeline) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
repo.savePipelineMaterialRevision(pipeline, pipeline.getId(), revision);
}
});
}
private void assertMatchedRevision(MatchedRevision matchedRevision, String shortRevision, String longRevision, String user, Date checkinTime, String comment) {
assertThat("shortRevision", matchedRevision.getShortRevision(), is(shortRevision));
assertThat("longRevision", matchedRevision.getLongRevision(), is(longRevision));
assertThat("user", matchedRevision.getUser(), is(user));
assertEquals("checkinTime", checkinTime, matchedRevision.getCheckinTime());
assertThat("comment", matchedRevision.getComment(), is(comment));
}
private Modification modification(String revision) {
return new Modification("user1", "comment", "foo@bar", new Date(), revision);
}
private Material saveMaterialRevisions(final MaterialRevisions revs) {
Material hg = revs.getMaterialRevision(0).getMaterial();
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
for (MaterialRevision revision : revs) {
repo.saveMaterialRevision(revision);
}
return null;
}
});
return hg;
}
private DependencyMaterial savePipelineAndCreate_DMRs(Date d, MaterialRevisions hgMaterialRevisions, PipelineConfig config, int... dmrStageCounters) {
Pipeline pipeline = savePipeline(
instanceFactory.createPipelineInstance(config,
BuildCause.createWithModifications(hgMaterialRevisions, "Loser"),
new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5, new TimeProvider()));
CaseInsensitiveString stageName = config.get(0).name();
DependencyMaterial material = new DependencyMaterial(config.name(), stageName);
String label = pipeline.getLabel();
ArrayList<Modification> mods = new ArrayList<>();
for (int i = 0; i < dmrStageCounters.length; i++) {
int dmrStageCounter = dmrStageCounters[i];
StageIdentifier stageIdentifier = new StageIdentifier(pipeline.getIdentifier(), CaseInsensitiveString.str(stageName), String.valueOf(dmrStageCounter));
mods.add(new Modification(d, stageIdentifier.getStageLocator(), label, pipeline.getId()));
}
final MaterialRevision materialRevision = new MaterialRevision(material, mods);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
repo.saveMaterialRevision(materialRevision);
return null;
}
});
return material;
}
private void assertCanLoadAndSaveMaterialRevisionsFor(MaterialConfig materialConfig) {
final PipelineConfig pipelineConfig = PipelineMother.createPipelineConfig("mingle", new MaterialConfigs(materialConfig), "dev");
final MaterialRevisions materialRevisions = ModificationsMother.modifyOneFile(pipelineConfig);
MaterialRevision materialRevision = materialRevisions.getMaterialRevision(0);
final Pipeline[] pipeline = new Pipeline[1];
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
//assume that we have saved the materials
repo.save(materialRevisions);
PipelineConfig config = PipelineMother.withTwoStagesOneBuildEach("pipeline-name", "stage-1", "stage-2");
config.setMaterialConfigs(materialRevisions.getMaterials().convertToConfigs());
pipeline[0] = instanceFactory.createPipelineInstance(pipelineConfig, BuildCause.createManualForced(materialRevisions, Username.ANONYMOUS), new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5,
new TimeProvider());
//this should persist the materials
pipelineSqlMapDao.save(pipeline[0]);
}
});
assertMaterialRevisions(materialRevision, pipeline[0]);
}
private void assertMaterialRevisions(MaterialRevision materialRevision, Pipeline pipeline) {
assertThat(pipeline.getId(), greaterThan(0L));
MaterialRevisions actual = repo.findMaterialRevisionsForPipeline(pipeline.getId());
assertEquals(materialRevision.getMaterial(), actual.getMaterialRevision(0).getMaterial());
assertEquals(materialRevision.getLatestModification(), actual.getMaterialRevision(0).getLatestModification());
}
private MaterialRevision saveOneScmModification(ScmMaterial original, String user, String filename) {
return saveOneScmModification(ModificationsMother.nextRevision(), original, user, filename, "comment");
}
private MaterialRevision saveOneScmModification(final String revision, final Material original, final String user, final String filename, final String comment) {
return (MaterialRevision) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Modification modification = new Modification(user, comment, "email", new Date(), revision);
modification.createModifiedFile(filename, "folder1", ModifiedAction.added);
MaterialRevision originalRevision = new MaterialRevision(original, modification);
repo.save(new MaterialRevisions(originalRevision));
return originalRevision;
}
});
}
private PipelineMaterialRevision pipelineMaterialRevision() {
PipelineMaterialRevision pmr = mock(PipelineMaterialRevision.class);
when(pmr.getMaterial()).thenReturn(material());
when(pmr.getToModification()).thenReturn(new Modification(new Date(), "123", "MOCK_LABEL-12", null));
when(pmr.getFromModification()).thenReturn(new Modification(new Date(), "125", "MOCK_LABEL-12", null));
return pmr;
}
private HgMaterial material() {
return new HgMaterial("url", null);
}
}