7
原来测试代码,可以写得这么简单!!!
source link: https://www.continuousdelivery20.com/blog/testcaseexample/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
原来测试代码,可以写得这么简单!!!
由 乔梁 | 2009-04-14
写单元测试应该非常简单,
简单到只需要 3、5 行代码,就是一个完整的测试用例,
如果做不到,
那么,9 行代码也就够了。
下面是 goCD 的快速单元测试,即: FastUnitTest
。
你可以从 https://github.com/gocd/gocd
拷贝一份代码库。
通过执行命令 ./gradlew clean server:FastUnitTest
来运行。
FastUnitTest 一共有 12000 多条 case,在我的笔记本上执行,需要 15 分钟。
其实,里面有一些不是单元测试的测试用例。例如:
- 数据库结构的升级
- 外部工具(Git/P4/SVN/HG)的交互
下面是 AgentInstanceTest 的代码,用于测试 Agent 对自身状态的检测,例如 Agent 上的磁盘存储空间是否超限。
对,你没有看错,的确是叫“FastUnitTest”,但也的确会访问文件系统。
对 AgentInstance
的测试用例包括:
文件的详细内容如下
可以看到,每一个测试用例都很简短,且没有很多逻辑计算。
平铺直叙,直接表达测试意图。
/*
* Copyright 2022 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.domain;
public class AgentInstanceTest {
private SystemEnvironment systemEnvironment;
public Agent agent;
private AgentBuildingInfo defaultBuildingInfo;
private static final String DEFAULT_IP_ADDRESS = "10.18.5.1";
private AgentStatusChangeListener agentStatusChangeListener;
private TimeProvider timeProvider;
@BeforeEach
void setUp() {
systemEnvironment = new SystemEnvironment();
agent = new Agent("uuid2", "CCeDev01", DEFAULT_IP_ADDRESS);
defaultBuildingInfo = new AgentBuildingInfo("pipeline", "buildLocator");
agentStatusChangeListener = mock(AgentStatusChangeListener.class);
timeProvider = mock(TimeProvider.class);
}
@AfterEach
void tearDown() throws Exception {
FileUtils.deleteQuietly(new File("config/agentkeystore"));
new SystemEnvironment().setProperty("agent.connection.timeout", "300");
new SystemEnvironment().clearProperty(SystemEnvironment.AGENT_SIZE_LIMIT);
}
@Test
void shouldReturnBuildLocator() {
AgentInstance building = building("buildLocator");
assertThat(building.getBuildLocator()).isEqualTo("buildLocator");
}
@Test
void shouldReturnEmptyStringForNullOperatingSystem() {
AgentInstance building = AgentInstanceMother.missing();
assertThat(building.getOperatingSystem()).isEqualTo("");
}
@Test
void shouldReturnHumanReadableUsableSpace() {
assertThat(AgentInstanceMother.updateUsableSpace(AgentInstanceMother.pending(), 2 * 1024 * 1024 * 1024L).freeDiskSpace().toString()).isEqualTo("2.0 GB");
assertThat(AgentInstanceMother.updateUsableSpace(AgentInstanceMother.pending(), null).freeDiskSpace().toString()).isEqualTo(DiskSpace.UNKNOWN_DISK_SPACE);
}
@Test
void shouldReturnUnknownUsableSpaceForMissingOrLostContactAgent() {
assertThat(AgentInstanceMother.missing().freeDiskSpace().toString()).isEqualTo(DiskSpace.UNKNOWN_DISK_SPACE);
assertThat(AgentInstanceMother.lostContact().freeDiskSpace().toString()).isEqualTo(DiskSpace.UNKNOWN_DISK_SPACE);
}
@Test
void shouldNotifyAgentChangeListenerOnUpdate() {
AgentInstance idleAgent = AgentInstance.createFromAgent(agent("abc"), new SystemEnvironment(), agentStatusChangeListener);
idleAgent.update(buildingRuntimeInfo());
verify(agentStatusChangeListener).onAgentStatusChange(idleAgent);
}
@Test
void shouldNotifyAgentChangeListenerOnAgentBuilding() {
AgentInstance idleAgent = AgentInstance.createFromAgent(agent("abc"), new SystemEnvironment(), agentStatusChangeListener);
idleAgent.building(new AgentBuildingInfo("running pipeline/stage/build", "buildLocator"));
verify(agentStatusChangeListener).onAgentStatusChange(idleAgent);
}
@Test
void shouldNotifyAgentChangeListenerOnCancel() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent("abc"), new SystemEnvironment(), agentStatusChangeListener);
agentInstance.cancel();
verify(agentStatusChangeListener).onAgentStatusChange(agentInstance);
}
@Test
void shouldNotifyAgentChangeListenerOnRefreshAndMarkedMissing() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent("abc"), new SystemEnvironment(), agentStatusChangeListener);
agentInstance.idle();
agentInstance.refresh();
assertThat(agentInstance.getStatus()).isEqualTo(AgentStatus.Missing);
verify(agentStatusChangeListener, times(2)).onAgentStatusChange(agentInstance);
}
@Test
void shouldNotifyAgentChangeListenerOnRefreshAndMarkedLostContact() {
AgentInstance instance = AgentInstance.createFromAgent(agent, new SystemEnvironment() {
@Override
public int getAgentConnectionTimeout() {
return -1;
}
}, agentStatusChangeListener);
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Missing);
instance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
instance.refresh();
assertThat(instance.getStatus()).isEqualTo(AgentStatus.LostContact);
verify(agentStatusChangeListener, times(2)).onAgentStatusChange(instance);
}
@Test
void shouldNotifyAgentChangeListenerOnEnablingAgent() {
AgentInstance instance = AgentInstanceMother.disabled();
AgentInstance disabledAgent = new AgentInstance(instance.agent, instance.getType(), systemEnvironment, agentStatusChangeListener);
disabledAgent.enable();
verify(agentStatusChangeListener).onAgentStatusChange(disabledAgent);
}
@Test
void shouldNotifyAgentChangeListenerOnDisablingAgent() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent("abc"), new SystemEnvironment(), agentStatusChangeListener);
agentInstance.deny();
verify(agentStatusChangeListener).onAgentStatusChange(agentInstance);
}
@Test
void shouldNotifyAgentChangeListenerOnConfigSync() {
AgentInstance instance = AgentInstanceMother.disabled();
AgentInstance agentInstance = new AgentInstance(instance.agent, instance.getType(), systemEnvironment, agentStatusChangeListener);
agentInstance.syncAgentFrom(agent);
verify(agentStatusChangeListener).onAgentStatusChange(agentInstance);
}
@Test
void shouldUpdateAgentBackToIdleAfterCancelledTaskFinishes() {
AgentInstance cancelledAgentInstance = cancelled();
AgentRuntimeInfo fromAgent = new AgentRuntimeInfo(cancelledAgentInstance.getAgent().getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
fromAgent.idle();
cancelledAgentInstance.update(fromAgent);
assertThat(cancelledAgentInstance.getStatus()).isEqualTo(AgentStatus.Idle);
}
@Test
void shouldClearAllCancelledStateIfAgentSetToIdle() throws InvalidAgentInstructionException {
Date currentTime = mock(Date.class);
AgentInstance agentInstance = buildingWithTimeProvider(timeProvider);
when(timeProvider.currentTime()).thenReturn(currentTime);
agentInstance.cancel();
agentInstance.killRunningTasks();
assertThat(agentInstance.cancelledAt()).isEqualTo(currentTime);
AgentRuntimeInfo fromAgent = new AgentRuntimeInfo(agentInstance.getAgent().getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
fromAgent.idle();
agentInstance.update(fromAgent);
assertThat(agentInstance.getStatus()).isEqualTo(AgentStatus.Idle);
assertThat(agentInstance.cancelledAt()).isNull();
assertThat(agentInstance.shouldKillRunningTasks()).isFalse();
}
@Test
void shouldUpdateTheInstallLocation() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
String installPath = "/var/lib/GoServer";
AgentRuntimeInfo newRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
newRuntimeInfo.setLocation(installPath);
agentInstance.update(newRuntimeInfo);
assertThat(agentInstance.getLocation()).isEqualTo(installPath);
}
@Test
void shouldUpdateTheUsableSpace() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo newRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
newRuntimeInfo.setUsableSpace(1000L);
assertThat(agentInstance.getUsableSpace()).isNotEqualTo(newRuntimeInfo.getUsableSpace());
agentInstance.update(newRuntimeInfo);
assertThat(agentInstance.getUsableSpace()).isEqualTo(newRuntimeInfo.getUsableSpace());
}
@Test
void shouldAssignCertificateToApprovedAgent() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
assertThat(agentInstance.assignCertification()).isTrue();
}
@Test
void shouldNotAssignCertificateToPendingAgent() {
AgentRuntimeInfo agentRuntimeInfo = AgentRuntimeInfo.fromServer(agent, false, "/var/lib", 0L, "linux");
AgentInstance agentInstance = createFromLiveAgent(agentRuntimeInfo, systemEnvironment,
mock(AgentStatusChangeListener.class));
assertThat(agentInstance.assignCertification()).isFalse();
}
@Test
void shouldInitializeTheLastHeardTimeWhenFirstPing() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
Date time = agentInstance.getLastHeardTime();
assertThat(time).isNull();
agentInstance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
time = agentInstance.getLastHeardTime();
assertThat(time).isNotNull();
}
@Test
void shouldUpdateTheLastHeardTime() throws Exception {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
Date time = agentInstance.getLastHeardTime();
Thread.sleep(1000);
agentInstance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
Date newtime = agentInstance.getLastHeardTime();
assertThat(newtime.after(time)).isTrue();
}
@Test
void shouldUpdateSupportBuildCommandProtocolFlag() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
agentInstance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
}
@Test
void shouldUpdateIPForPhysicalMachineWhenUpChanged() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.update(new AgentRuntimeInfo(new AgentIdentifier("ccedev01", "10.18.7.52", "uuid"), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
assertThat(agentInstance.getAgent().getIpaddress()).isEqualTo("10.18.7.52");
}
@Test
void shouldCleanBuildingInfoWhenAgentIsIdle() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.update(buildingRuntimeInfo());
agentInstance.update(idleRuntimeInfo());
assertThat(agentInstance.getBuildingInfo()).isEqualTo(AgentBuildingInfo.NOT_BUILDING);
}
private AgentRuntimeInfo idleRuntimeInfo() {
AgentRuntimeInfo agentRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
agentRuntimeInfo.idle();
return agentRuntimeInfo;
}
@Test
void shouldUpdateBuildingInfoWhenAgentIsBuilding() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo agentRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
AgentBuildingInfo buildingInfo = new AgentBuildingInfo("running pipeline/stage/build", "buildLocator");
agentRuntimeInfo.busy(buildingInfo);
agentInstance.update(agentRuntimeInfo);
assertThat(agentInstance.getBuildingInfo()).isEqualTo(buildingInfo);
}
@Test
void shouldUpdateBuildingInfoWhenAgentIsBuildingWhenCancelled() {
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.update(buildingRuntimeInfo());
agentInstance.update(cancelRuntimeInfo());
assertThat(agentInstance.getBuildingInfo()).isEqualTo(defaultBuildingInfo);
assertThat(agentInstance.getStatus()).isEqualTo(AgentStatus.Cancelled);
}
private AgentRuntimeInfo cancelRuntimeInfo() {
AgentRuntimeInfo agentRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
agentRuntimeInfo.busy(defaultBuildingInfo);
agentRuntimeInfo.cancel();
return agentRuntimeInfo;
}
@Test
void shouldNotChangePendingAgentIpAddress() {
AgentInstance pending = createFromLiveAgent(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"),
systemEnvironment, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo info = new AgentRuntimeInfo(new AgentIdentifier("ccedev01", "10.18.7.52", "uuid"), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
assertThat(pending.isIpChangeRequired(info.getIpAdress())).isFalse();
}
@Test
void shouldChangeIpWhenSameAgentIpChanged() {
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo info = new AgentRuntimeInfo(new AgentIdentifier("ccedev01", "10.18.7.52", "uuid"), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
assertThat(instance.isIpChangeRequired(info.getIpAdress())).isTrue();
}
@Test
void shouldNotChangeIpWhenIpNotChanged() {
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
assertThat(instance.isIpChangeRequired(DEFAULT_IP_ADDRESS)).isFalse();
}
@Test
void shouldDefaultToMissingStatusWhenSyncAnApprovedAgent() {
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
instance.syncAgentFrom(agent);
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Missing);
}
@Test
void pendingAgentshouldNotBeRegistered() {
AgentRuntimeInfo agentRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
AgentInstance instance = createFromLiveAgent(agentRuntimeInfo, systemEnvironment,
mock(AgentStatusChangeListener.class));
assertThat(instance.isRegistered()).isFalse();
}
@Test
void deniedAgentshouldBeRegistered() {
agent.disable();
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
assertThat(instance.isRegistered()).isTrue();
}
@Test
void shouldBeRegisteredForIdleAgent() {
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
instance.update(idleRuntimeInfo());
assertThat(instance.isRegistered()).isTrue();
}
@Test
void shouldBecomeIdleAfterApprove() {
AgentInstance instance = createFromLiveAgent(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"),
systemEnvironment, mock(AgentStatusChangeListener.class));
instance.enable();
instance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Idle);
}
@Test
void shouldBeMissingWhenNeverHeardFromAnyAgent() {
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Missing);
instance.refresh();
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Missing);
}
@Test
void shouldBeLostContactWhenLastHeardTimeExeedTimeOut() {
AgentInstance instance = AgentInstance.createFromAgent(agent, new SystemEnvironment() {
@Override
public int getAgentConnectionTimeout() {
return -1;
}
}, mock(AgentStatusChangeListener.class));
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Missing);
instance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
instance.refresh();
assertThat(instance.getStatus()).isEqualTo(AgentStatus.LostContact);
}
@Test
void shouldRefreshDisabledAgent() {
agent.disable();
AgentInstance instance = AgentInstance.createFromAgent(agent, new SystemEnvironment() {
@Override
public int getAgentConnectionTimeout() {
return -1;
}
}, mock(AgentStatusChangeListener.class));
instance.update(new AgentRuntimeInfo(agent.getAgentIdentifier(), Building, currentWorkingDirectory(), "cookie"));
instance.refresh();
assertThat(instance.getRuntimeStatus()).isEqualTo(AgentRuntimeStatus.LostContact);
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Disabled);
}
@Test
void shouldDenyPendingAgent() {
AgentRuntimeInfo agentRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
AgentInstance instance = createFromLiveAgent(agentRuntimeInfo, systemEnvironment,
mock(AgentStatusChangeListener.class));
instance.deny();
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Disabled);
}
@Test
void shouldBeLiveStatus() {
AgentInstance instance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
instance.update(idleRuntimeInfo());
instance.refresh();
assertThat(instance.getStatus()).isEqualTo(AgentStatus.Idle);
}
@Test
void shouldSyncIPWithConfig() {
AgentInstance originalAgentInstance = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
originalAgentInstance.update(new AgentRuntimeInfo(new AgentIdentifier("CCeDev01", "10.18.5.2", "uuid2"), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie"));
assertThat(originalAgentInstance.getAgent()).isEqualTo(new Agent("uuid2", "CCeDev01", "10.18.5.2"));
}
@Test
void shouldKeepOriginalStatusWhenAgentIsNotDenied() {
AgentInstance original = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
original.update(buildingRuntimeInfo(agent));
original.syncAgentFrom(agent);
assertThat(original.getStatus()).isEqualTo(AgentStatus.Building);
}
@Test
void shouldDenyAgentWhenAgentIsDeniedInConfigFile() {
AgentInstance original = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
original.update(buildingRuntimeInfo());
Agent newAgent = new Agent(agent.getUuid(), agent.getHostname(), agent.getIpaddress());
newAgent.disable();
original.syncAgentFrom(newAgent);
assertThat(original.getStatus()).isEqualTo(AgentStatus.Disabled);
}
@Test
void shouldDenyAgentWhenItIsNotBuilding() {
AgentInstance original = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
original.update(idleRuntimeInfo());
original.deny();
assertThat(agent.isDisabled()).isTrue();
assertThat(original.getStatus()).isEqualTo(AgentStatus.Disabled);
}
@Test
void shouldReturnFalseWhenAgentHasEnoughSpace() {
AgentInstance original = AgentInstance.createFromAgent(agent, new SystemEnvironment() {
@Override
public long getAgentSizeLimit() {
return 100 * 1024 * 1024;
}
}, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo newRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
long is110M = 110 * 1024 * 1024;
newRuntimeInfo.setUsableSpace(is110M);
original.update(newRuntimeInfo);
assertThat(original.isLowDiskSpace()).isFalse();
}
@Test
void shouldReturnTrueWhenFreeDiskOnAgentIsLow() {
AgentInstance original = AgentInstance.createFromAgent(agent, new SystemEnvironment() {
@Override
public long getAgentSizeLimit() {
return 100 * 1024 * 1024;
}
}, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo newRuntimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
long is90M = 90 * 1024 * 1024;
newRuntimeInfo.setUsableSpace(is90M);
original.update(newRuntimeInfo);
assertThat(original.isLowDiskSpace()).isTrue();
}
@Test
void shouldBeAbleToDenyAgentWhenItIsBuilding() {
AgentInstance original = AgentInstance.createFromAgent(agent, systemEnvironment, mock(AgentStatusChangeListener.class));
AgentRuntimeInfo runtimeInfo = buildingRuntimeInfo();
original.update(runtimeInfo);
assertThat(original.canDisable()).isTrue();
original.deny();
assertThat(agent.isDisabled()).isTrue();
assertThat(original.getStatus()).isEqualTo(AgentStatus.Disabled);
assertThat(original.getBuildingInfo()).isEqualTo(runtimeInfo.getBuildingInfo());
}
@Test
void shouldOrderByHostname() {
AgentInstance agentA = new AgentInstance(new Agent("UUID", "A", "127.0.0.1"), LOCAL, systemEnvironment, null);
AgentInstance agentB = new AgentInstance(new Agent("UUID", "B", "127.0.0.2"), LOCAL, systemEnvironment, null);
assertThat(agentA.compareTo(agentA)).isEqualTo(0);
assertThat(agentA.compareTo(agentB)).isLessThan(0);
assertThat(agentB.compareTo(agentA)).isGreaterThan(0);
}
@Test
void shouldNotBeEqualIfUuidIsNotEqual() {
AgentInstance agentA = new AgentInstance(new Agent("UUID", "A", "127.0.0.1"), LOCAL, systemEnvironment, null);
AgentInstance copyOfAgentA = new AgentInstance(new Agent("UUID", "A", "127.0.0.1"),
LOCAL, systemEnvironment, null);
AgentInstance agentB = new AgentInstance(new Agent("UUID", "B", "127.0.0.2"), LOCAL, systemEnvironment, null);
assertThat(agentA).isNotEqualTo(agentB);
assertThat(agentB).isNotEqualTo(agentA);
assertThat(agentA).isEqualTo(copyOfAgentA);
}
@Test
void shouldBeAbleToDenyAgentThatIsRunningCancelledJob() {
Agent agent = new Agent("UUID", "A", "127.0.0.1");
AgentInstance agentInstance = new AgentInstance(agent, LOCAL, systemEnvironment, mock(AgentStatusChangeListener.class));
agentInstance.cancel();
AgentBuildingInfo cancelled = agentInstance.getBuildingInfo();
assertThat(agentInstance.canDisable()).isTrue();
agentInstance.deny();
assertThat(agent.isDisabled()).isTrue();
assertThat(agentInstance.getStatus()).isEqualTo(AgentStatus.Disabled);
assertThat(agentInstance.getBuildingInfo()).isEqualTo(cancelled);
}
@Test
void shouldReturnNullWhenNoMatchingJobs() {
AgentInstance agentInstance = new AgentInstance(agent("linux, mercurial"), LOCAL, systemEnvironment, null);
JobPlan matchingJob = agentInstance.firstMatching(new ArrayList<>());
assertThat(matchingJob).isNull();
}
@Test
void shouldReturnFirstMatchingJobPlan() {
AgentInstance agentInstance = new AgentInstance(agent("linux, mercurial"), LOCAL, systemEnvironment, null);
List<JobPlan> plans = jobPlans("linux, svn", "linux, mercurial");
JobPlan matchingJob = agentInstance.firstMatching(plans);
assertThat(matchingJob).isEqualTo(plans.get(1));
}
@Test
void shouldReturnAJobPlanWithMatchingUuidSet() {
Agent agent = agent("linux, mercurial");
AgentInstance agentInstance = new AgentInstance(agent, LOCAL, systemEnvironment, null);
final JobPlan job = jobPlan("pipeline-name", "job-name", "resource", agent.getUuid());
JobPlan matchingJob = agentInstance.firstMatching(new ArrayList<JobPlan>() {{
add(job);
}});
assertThat(matchingJob).isEqualTo(job);
}
@Test
void shouldNotReturnAJobWithMismatchedUuid() {
Agent agent = agent("linux, mercurial");
AgentInstance agentInstance = new AgentInstance(agent, LOCAL, systemEnvironment, null);
final JobPlan job = jobPlan("pipeline-name", "job-name", "linux", agent.getUuid() + "-ensure-doesn't-match");
JobPlan matchingJob = agentInstance.firstMatching(new ArrayList<JobPlan>() {{
add(job);
}});
assertThat(matchingJob).isNull();
}
@Test
void shouldSetAgentToIdleWhenItIsApproved() {
AgentInstance pendingAgentInstance = AgentInstanceMother.pending();
Agent agent = new Agent(pendingAgentInstance.getUuid(), pendingAgentInstance.getHostname(), pendingAgentInstance.getIpAddress());
pendingAgentInstance.syncAgentFrom(agent);
AgentStatus status = pendingAgentInstance.getStatus();
assertThat(status).isEqualTo(AgentStatus.Idle);
}
@Test
void syncConfigShouldUpdateElasticAgentRuntimeInfo() {
AgentInstance agentInstance = AgentInstanceMother.idle();
Agent agent = new Agent(agentInstance.getUuid(), agentInstance.getHostname(), agentInstance.getIpAddress());
agent.setElasticAgentId("i-123456");
agent.setElasticPluginId("com.example.aws");
assertThat(agentInstance.isElastic()).isFalse();
agentInstance.syncAgentFrom(agent);
assertThat(agentInstance.isElastic()).isTrue();
assertThat(agentInstance.elasticAgentMetadata().elasticAgentId()).isEqualTo("i-123456");
assertThat(agentInstance.elasticAgentMetadata().elasticPluginId()).isEqualTo("com.example.aws");
}
@Test
void shouldReturnFreeDiskSpace() {
assertThat(AgentInstanceMother.updateRuntimeStatus(AgentInstanceMother.updateUsableSpace(AgentInstanceMother.idle(new Date(), "CCeDev01"), 1024L), AgentRuntimeStatus.Missing).freeDiskSpace()).isEqualTo(DiskSpace.unknownDiskSpace());
assertThat(AgentInstanceMother.updateRuntimeStatus(AgentInstanceMother.updateUsableSpace(AgentInstanceMother.idle(new Date(), "CCeDev01"), 1024L), AgentRuntimeStatus.LostContact).freeDiskSpace()).isEqualTo(DiskSpace.unknownDiskSpace());
assertThat(AgentInstanceMother.updateRuntimeStatus(AgentInstanceMother.updateUsableSpace(AgentInstanceMother.idle(new Date(), "CCeDev01"), 1024L), AgentRuntimeStatus.Idle).freeDiskSpace()).isEqualTo(new DiskSpace(1024L));
assertThat(AgentInstanceMother.updateRuntimeStatus(AgentInstanceMother.updateUsableSpace(AgentInstanceMother.idle(new Date(), "CCeDev01"), null), AgentRuntimeStatus.Idle).freeDiskSpace()).isEqualTo(DiskSpace.unknownDiskSpace());
}
@Test
void shouldReturnAppropriateMissingStatus() {
AgentInstance missing = AgentInstanceMother.missing();
assertThat(missing.isMissing()).isTrue();
AgentInstance building = building();
assertThat(building.isMissing()).isFalse();
}
@Test
void shouldNotMatchJobPlanIfJobRequiresElasticAgent_MatchingIsManagedByBuildAssignmentService() {
Agent agent = new Agent("uuid");
agent.setElasticAgentId("elastic-agent-id-1");
String elasticPluginId = "elastic-plugin-id-1";
agent.setElasticPluginId(elasticPluginId);
AgentInstance agentInstance = new AgentInstance(agent, REMOTE, mock(SystemEnvironment.class), null);
DefaultJobPlan jobPlan1 = new DefaultJobPlan();
jobPlan1.setElasticProfile(new ElasticProfile("foo", "prod-cluster"));
List<JobPlan> jobPlans = asList(jobPlan1, new DefaultJobPlan());
assertThat(agentInstance.firstMatching(jobPlans)).isNull();
}
@Test
void shouldNotMatchJobPlanIfTheAgentWasLaunchedByADifferentPluginFromThatConfiguredForTheJob() {
Agent agent = new Agent("uuid");
agent.setElasticAgentId("elastic-agent-id-1");
String elasticPluginId = "elastic-plugin-id-1";
agent.setElasticPluginId(elasticPluginId);
AgentInstance agentInstance = new AgentInstance(agent, REMOTE, mock(SystemEnvironment.class), null);
DefaultJobPlan jobPlan1 = new DefaultJobPlan();
jobPlan1.setElasticProfile(new ElasticProfile("foo", "prod-cluster"));
List<JobPlan> jobPlans = asList(jobPlan1, new DefaultJobPlan());
assertThat(agentInstance.firstMatching(jobPlans)).isNull();
}
@Test
void shouldNotMatchJobPlanIfTheAgentIsElasticAndJobHasResourcesDefined() {
Agent agent = new Agent("uuid", "hostname", "11.1.1.1", singletonList("r1"));
agent.setElasticAgentId("elastic-agent-id-1");
String elasticPluginId = "elastic-plugin-id-1";
agent.setElasticPluginId(elasticPluginId);
AgentInstance agentInstance = new AgentInstance(agent, REMOTE, mock(SystemEnvironment.class), null);
DefaultJobPlan jobPlan1 = new DefaultJobPlan();
jobPlan1.setResources(asList(new Resource("r1")));
List<JobPlan> jobPlans = asList(jobPlan1, new DefaultJobPlan());
assertThat(agentInstance.firstMatching(jobPlans)).isNull();
}
@Test
void lostContact() {
AgentInstance agentInstance = building();
agentInstance.lostContact();
assertThat(agentInstance.getStatus()).isEqualTo(AgentStatus.LostContact);
AgentInstance pendingInstance = AgentInstanceMother.pending();
pendingInstance.lostContact();
assertThat(pendingInstance.getStatus()).isEqualTo(AgentStatus.Pending);
AgentInstance disabledInstance = AgentInstanceMother.disabled();
disabledInstance.lostContact();
assertThat(disabledInstance.getStatus()).isEqualTo(AgentStatus.Disabled);
}
@Test
void shouldNotRefreshWhenAgentStatusIsPending() {
AgentInstance agentInstance = AgentInstanceMother.pendingInstance();
agentInstance.refresh();
assertThat(agentInstance.getStatus()).isEqualTo(AgentStatus.Pending);
}
@Test
void shouldMarkAgentAsMissingWhenLastHeardTimeIsNull() {
Agent agent = new Agent("1234", "localhost", "192.168.0.1");
AgentInstance agentInstance = AgentInstance.createFromAgent(agent, new SystemEnvironment(), mock(AgentStatusChangeListener.class));
agentInstance.refresh();
assertThat(agentInstance.getRuntimeStatus()).isEqualTo(AgentRuntimeStatus.Missing);
assertThat(agentInstance.getLastHeardTime()).isNotNull();
}
@Test
void shouldNotRefreshAgentStateWhenAgentIsMissingAndLostContactDurationHasNotExceeded() {
AgentInstance agentInstance = AgentInstanceMother.missing();
agentInstance.refresh();
assertThat(agentInstance.getRuntimeStatus()).isEqualTo(AgentRuntimeStatus.Missing);
}
@Test
void shouldChangeAgentStatusToLostContactWhenLostAgentTimeoutHasExceeded() throws IllegalAccessException {
AgentInstance agentInstance = AgentInstanceMother.missing();
int agentConnectionTimeoutInMillis = systemEnvironment.getAgentConnectionTimeout() * 1000;
Date timeLoggedForMissingStatus = new Date(new Date().getTime() - agentConnectionTimeoutInMillis);
FieldUtils.writeField(agentInstance, "lastHeardTime", timeLoggedForMissingStatus, true);
agentInstance.refresh();
assertThat(agentInstance.getRuntimeStatus()).isEqualTo(AgentRuntimeStatus.LostContact);
}
@Test
void buildingMethodShouldUpdateAgentRuntimeStatusToBuildingAndSetSpecifiedBuildInfoInItsRuntimeInfo(){
Agent mockAgent = mock(Agent.class);
AgentRuntimeInfo mockAgentRuntimeInfo = mock(AgentRuntimeInfo.class);
AgentBuildingInfo mockAgentBuildingInfo = mock(AgentBuildingInfo.class);
SystemEnvironment mockSysEnv = mock(SystemEnvironment.class);
AgentStatusChangeListener mockAgentStatusChangeListener = mock(AgentStatusChangeListener.class);
when(mockAgent.isFromLocalHost()).thenReturn(true);
when(mockAgentRuntimeInfo.agent()).thenReturn(mockAgent);
when(mockSysEnv.isAutoRegisterLocalAgentEnabled()).thenReturn(true);
when(mockAgentRuntimeInfo.isCancelled()).thenReturn(false);
doNothing().when(mockAgentRuntimeInfo).busy(mockAgentBuildingInfo);
AgentInstance agentInstance = createFromLiveAgent(mockAgentRuntimeInfo, mockSysEnv, mockAgentStatusChangeListener);
agentInstance.building(mockAgentBuildingInfo);
verify(mockAgentRuntimeInfo, atLeastOnce()).getRuntimeStatus();
verify(mockAgentRuntimeInfo).setRuntimeStatus(Building);
verify(mockAgentRuntimeInfo).busy(mockAgentBuildingInfo);
verify(mockAgentStatusChangeListener).onAgentStatusChange(agentInstance);
}
@Test
void shouldGetAgentAndBootstrapperVersions() {
AgentInstance agentInstance = AgentInstanceMother.idle();
AgentRuntimeInfo newRuntimeInfo = new AgentRuntimeInfo(agentInstance.getAgentIdentifier(), agentInstance.getRuntimeStatus(), "some-location", "some-cookie");
newRuntimeInfo.updateBootstrapperVersion("20.3.0-1234").updateAgentVersion("20.5.0-2345");
agentInstance.update(newRuntimeInfo);
assertThat(agentInstance.getAgentBootstrapperVersion()).isEqualTo("20.3.0-1234");
assertThat(agentInstance.getAgentVersion()).isEqualTo("20.5.0-2345");
}
@Nested
class Matches {
@Test
void shouldReturnTrueIfMatchesTheFilter() {
AgentInstance pending = AgentInstanceMother.pending();
assertThat(pending.matches(Pending)).isTrue();
Agent pendingAgent = pending.getAgent();
pendingAgent.setElasticAgentId("elastic-agent-id");
pendingAgent.setElasticPluginId("elastic-plugin-id");
pending.syncAgentFrom(pendingAgent);
assertThat(pending.matches(Elastic)).isTrue();
AgentInstance nullInstance = AgentInstanceMother.nullInstance();
assertThat(nullInstance.matches(Null)).isTrue();
}
@Test
void shouldReturnFalseIfDoesNotMatchTheFilter() {
AgentInstance building = building();
assertThat(building.matches(Pending)).isFalse();
assertThat(building.matches(Elastic)).isFalse();
AgentInstance pending = AgentInstanceMother.pending();
assertThat(pending.matches(Elastic)).isFalse();
assertThat(pending.matches(Null)).isFalse();
AgentInstance idle = AgentInstanceMother.idle();
Agent idleAgent = idle.getAgent();
idleAgent.setElasticAgentId("elastic-agent-id");
idleAgent.setElasticPluginId("elastic-plugin-id");
idle.syncAgentFrom(idleAgent);
assertThat(idle.matches(Pending)).isFalse();
assertThat(idle.matches(Null)).isFalse();
}
}
@Nested
class killRunningTasks {
@Test
void shouldAddAKillRunningTasksInstructionToAgent() throws InvalidAgentInstructionException {
AgentInstance agentInstance = cancelled();
agentInstance.killRunningTasks();
assertThat(agentInstance.shouldKillRunningTasks()).isTrue();
}
@Test
void shouldErrorOutIfAddingKillRunningTasksInstructionIfAgentRuntimeStatusIsNotCancelled() {
AgentInstance agentInstance = building();
assertThatExceptionOfType(InvalidAgentInstructionException.class)
.isThrownBy(() -> agentInstance.killRunningTasks())
.withMessage("The agent should be in cancelled state before attempting to kill running tasks. Current Agent state is: 'Building'");
}
@Test
void shouldErrorOutIfMakingMultipleRequestsToKillRunningTasks() throws InvalidAgentInstructionException {
AgentInstance agentInstance = cancelled();
agentInstance.killRunningTasks();
assertThatExceptionOfType(InvalidAgentInstructionException.class)
.isThrownBy(() -> agentInstance.killRunningTasks())
.withMessage("There is a pending request to kill running task.");
}
}
@Nested
class cancel {
@Test
void shouldKeepStatusAsCancelled() {
AgentInstance buildingAgentInstance = building("buildLocator");
buildingAgentInstance.cancel();
buildingAgentInstance.update(buildingRuntimeInfo(buildingAgentInstance.getAgent()));
assertThat(buildingAgentInstance.getStatus()).isEqualTo(AgentStatus.Cancelled);
}
@Test
void shouldRecordTheTimeWhenAgentIsMovedToCancelState() {
Date currentTime = mock(Date.class);
TimeProvider timeProvider = mock(TimeProvider.class);
AgentInstance agentInstance = buildingWithTimeProvider(timeProvider);
when(timeProvider.currentTime()).thenReturn(currentTime);
agentInstance.cancel();
assertThat(agentInstance.cancelledAt()).isEqualTo(currentTime);
}
}
@Nested
class agentInstruction {
@Test
void shouldBeToDoNothingIfJobNotCancelled() {
AgentInstance agentInstance = building("buildLocator");
assertThat(agentInstance.agentInstruction()).isEqualTo(NONE);
}
@Test
void shouldBeToCancelIfJobCancelled() {
AgentInstance agentInstance = building();
agentInstance.cancel();
assertThat(agentInstance.agentInstruction()).isEqualTo(CANCEL);
}
@Test
void shouldBeToKillRunningTasks() throws InvalidAgentInstructionException {
AgentInstance agentInstance = building();
agentInstance.cancel();
agentInstance.killRunningTasks();
assertThat(agentInstance.agentInstruction()).isEqualTo(KILL_RUNNING_TASKS);
}
}
@Nested
class isStuckInCancel {
@Test
void shouldBeTrueIfIsInCancelledStateForMoreThan10Mins() {
Date currentTime = new Date();
Date after10Mins = new Date(currentTime.getTime() + 600001);
TimeProvider timeProvider = mock(TimeProvider.class);
AgentInstance agentInstance = buildingWithTimeProvider(timeProvider);
when(timeProvider.currentTime()).thenReturn(currentTime, after10Mins);
agentInstance.cancel();
assertThat(agentInstance.isStuckInCancel()).isTrue();
}
@Test
void shouldNotBeTrueForAgentsWhichAreNotCancelled() {
AgentInstance agentInstance = buildingWithTimeProvider(timeProvider);
assertThat(agentInstance.isStuckInCancel()).isFalse();
}
}
private List<JobPlan> jobPlans(String... resources) {
ArrayList<JobPlan> plans = new ArrayList<>();
int count = 1;
for (String resource : resources) {
plans.add(jobPlan("pipeline" + count, "job" + count, resource, null));
count++;
}
return plans;
}
private DefaultJobPlan jobPlan(String pipelineName, String jobName, String resource, String uuid) {
JobIdentifier jobIdentifier = new JobIdentifier(pipelineName, 1, "1", "stage1", "1", jobName, 1L);
DefaultJobPlan plan = new DefaultJobPlan(new Resources(resource), new ArrayList<>(), 100, jobIdentifier, null, new EnvironmentVariables(), new EnvironmentVariables(), null, null);
plan.setAgentUuid(uuid);
return plan;
}
private Agent agent(String resources) {
return new Agent("UUID", "A", "127.0.0.1", commaSeparatedStrToList(resources));
}
private AgentRuntimeInfo buildingRuntimeInfo() {
return buildingRuntimeInfo(agent);
}
private AgentRuntimeInfo buildingRuntimeInfo(Agent agent) {
AgentRuntimeInfo runtimeInfo = new AgentRuntimeInfo(agent.getAgentIdentifier(), AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie");
runtimeInfo.busy(defaultBuildingInfo);
return runtimeInfo;
}
public static AgentInstance buildingWithTimeProvider(TimeProvider timeProvider) {
Agent idleAgentConfig = new Agent("uuid2", "localhost", "10.18.5.1");
AgentRuntimeInfo agentRuntimeInfo = new AgentRuntimeInfo(idleAgentConfig.getAgentIdentifier(), Building, currentWorkingDirectory(), "cookie");
agentRuntimeInfo.setLocation("/var/lib/foo");
agentRuntimeInfo.idle();
agentRuntimeInfo.setUsableSpace(10 * 1024l);
AgentInstance agentInstance = new AgentInstance(idleAgentConfig, LOCAL, new SystemEnvironment(), mock(AgentStatusChangeListener.class), timeProvider);
agentInstance.enable();
return agentInstance;
}
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK