From 7831763ae420324dd5ec20e3eaf966f67c2945af Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Tue, 2 May 2023 14:28:56 +0200 Subject: Use timer --- .../node/admin/container/ContainerOperations.java | 6 ++-- .../container/image/ContainerImagePruner.java | 10 +++---- .../node/admin/maintenance/StorageMaintainer.java | 12 ++++---- .../maintenance/coredump/CoredumpHandler.java | 14 +++++----- .../identity/AthenzCredentialsMaintainer.java | 14 +++++----- .../servicedump/VespaServiceDumperImpl.java | 20 +++++++------- .../hosted/node/admin/nodeadmin/NodeAdminImpl.java | 32 +++++++++++----------- .../admin/nodeagent/NodeAgentContextManager.java | 13 +++++---- .../hosted/node/admin/nodeagent/NodeAgentImpl.java | 22 +++++++-------- .../admin/container/ContainerOperationsTest.java | 4 ++- .../container/image/ContainerImagePrunerTest.java | 8 +++--- .../node/admin/integration/ContainerTester.java | 11 ++++---- .../admin/maintenance/StorageMaintainerTest.java | 8 +++--- .../maintenance/coredump/CoredumpHandlerTest.java | 10 +++---- .../servicedump/VespaServiceDumperImplTest.java | 19 ++++++------- .../node/admin/nodeadmin/NodeAdminImplTest.java | 16 ++++++----- .../nodeagent/NodeAgentContextManagerTest.java | 27 ++++++++++-------- .../node/admin/nodeagent/NodeAgentImplTest.java | 20 +++++++------- 18 files changed, 136 insertions(+), 130 deletions(-) (limited to 'node-admin') diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperations.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperations.java index b9e7ce56c53..264035b86a1 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperations.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperations.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.node.admin.container; import com.yahoo.config.provision.DockerImage; +import com.yahoo.jdisc.Timer; import com.yahoo.vespa.hosted.node.admin.cgroup.Cgroup; import com.yahoo.vespa.hosted.node.admin.component.TaskContext; import com.yahoo.vespa.hosted.node.admin.container.image.ContainerImageDownloader; @@ -13,7 +14,6 @@ import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandLine; import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandResult; import java.nio.file.FileSystem; -import java.time.Clock; import java.time.Duration; import java.util.List; import java.util.Objects; @@ -34,10 +34,10 @@ public class ContainerOperations { private final ContainerImagePruner imagePruner; private final ContainerStatsCollector containerStatsCollector; - public ContainerOperations(ContainerEngine containerEngine, Cgroup cgroup, FileSystem fileSystem) { + public ContainerOperations(ContainerEngine containerEngine, Cgroup cgroup, FileSystem fileSystem, Timer timer) { this.containerEngine = Objects.requireNonNull(containerEngine); this.imageDownloader = new ContainerImageDownloader(containerEngine); - this.imagePruner = new ContainerImagePruner(containerEngine, Clock.systemUTC()); + this.imagePruner = new ContainerImagePruner(containerEngine, timer); this.containerStatsCollector = new ContainerStatsCollector(containerEngine, cgroup, fileSystem); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePruner.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePruner.java index 8fcd7893f64..372b8522b0c 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePruner.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePruner.java @@ -2,11 +2,11 @@ package com.yahoo.vespa.hosted.node.admin.container.image; import com.yahoo.collections.Pair; +import com.yahoo.jdisc.Timer; import com.yahoo.vespa.hosted.node.admin.component.TaskContext; import com.yahoo.vespa.hosted.node.admin.container.ContainerEngine; import com.yahoo.vespa.hosted.node.admin.container.PartialContainer; -import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -51,14 +51,14 @@ public class ContainerImagePruner { private static final Logger LOG = Logger.getLogger(ContainerImagePruner.class.getName()); - private final Clock clock; + private final Timer timer; private final ContainerEngine containerEngine; private final Map lastTimeUsedByImageId = new ConcurrentHashMap<>(); - public ContainerImagePruner(ContainerEngine containerEngine, Clock clock) { + public ContainerImagePruner(ContainerEngine containerEngine, Timer timer) { this.containerEngine = Objects.requireNonNull(containerEngine); - this.clock = Objects.requireNonNull(clock); + this.timer = Objects.requireNonNull(timer); } /** @@ -112,7 +112,7 @@ public class ContainerImagePruner { } private Set updateRecentlyUsedImageIds(List images, List containers, Duration minImageAgeToDelete) { - final Instant now = clock.instant(); + final Instant now = timer.currentTime(); // Add any already downloaded image to the list once images.forEach(image -> lastTimeUsedByImageId.putIfAbsent(image.id(), now)); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java index f0182ae36e4..9a548fba431 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java @@ -5,6 +5,7 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.NodeType; +import com.yahoo.jdisc.Timer; import com.yahoo.vespa.hosted.node.admin.component.TaskContext; import com.yahoo.vespa.hosted.node.admin.container.Container; import com.yahoo.vespa.hosted.node.admin.container.ContainerName; @@ -27,7 +28,6 @@ import com.yahoo.vespa.hosted.node.admin.task.util.process.Terminal; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; -import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.time.ZoneOffset; @@ -55,7 +55,7 @@ public class StorageMaintainer { private final CoredumpHandler coredumpHandler; private final DiskCleanup diskCleanup; private final SyncClient syncClient; - private final Clock clock; + private final Timer timer; private final Path archiveContainerStoragePath; // We cache disk usage to avoid doing expensive disk operations so often @@ -65,12 +65,12 @@ public class StorageMaintainer { .build(); public StorageMaintainer(Terminal terminal, CoredumpHandler coredumpHandler, DiskCleanup diskCleanup, - SyncClient syncClient, Clock clock, Path archiveContainerStoragePath) { + SyncClient syncClient, Timer timer, Path archiveContainerStoragePath) { this.terminal = terminal; this.coredumpHandler = coredumpHandler; this.diskCleanup = diskCleanup; this.syncClient = syncClient; - this.clock = clock; + this.timer = timer; this.archiveContainerStoragePath = archiveContainerStoragePath; } @@ -138,7 +138,7 @@ public class StorageMaintainer { } private List createCleanupRules(NodeAgentContext context) { - Instant start = clock.instant(); + Instant start = timer.currentTime(); double oneMonthSeconds = Duration.ofDays(30).getSeconds(); Function monthNormalizer = instant -> Duration.between(instant, start).getSeconds() / oneMonthSeconds; List rules = new ArrayList<>(); @@ -176,7 +176,7 @@ public class StorageMaintainer { public void archiveNodeStorage(NodeAgentContext context) { ContainerPath logsDirInContainer = context.paths().underVespaHome("logs"); Path containerLogsInArchiveDir = archiveContainerStoragePath - .resolve(context.containerName().asString() + "_" + DATE_TIME_FORMATTER.format(clock.instant()) + logsDirInContainer.pathInContainer()); + .resolve(context.containerName().asString() + "_" + DATE_TIME_FORMATTER.format(timer.currentTime()) + logsDirInContainer.pathInContainer()); // Files.move() does not support moving non-empty directories across providers, move using host paths UnixPath containerLogsOnHost = new UnixPath(logsDirInContainer.pathOnHost()); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandler.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandler.java index 8c293fb40c9..af47f00a21e 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandler.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandler.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.node.admin.maintenance.coredump; import com.yahoo.config.provision.DockerImage; +import com.yahoo.jdisc.Timer; import com.yahoo.security.KeyId; import com.yahoo.security.SecretSharedKey; import com.yahoo.vespa.flags.FetchVector; @@ -28,7 +29,6 @@ import java.io.OutputStream; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.time.Clock; import java.util.Comparator; import java.util.List; import java.util.Optional; @@ -65,7 +65,7 @@ public class CoredumpHandler { private final String crashPatchInContainer; private final Path doneCoredumpsPath; private final Metrics metrics; - private final Clock clock; + private final Timer timer; private final Supplier coredumpIdSupplier; private final SecretSharedKeySupplier secretSharedKeySupplier; private final StringFlag coreEncryptionPublicKeyIdFlag; @@ -75,23 +75,23 @@ public class CoredumpHandler { * @param doneCoredumpsPath path on host where processed core dumps are stored */ public CoredumpHandler(CoreCollector coreCollector, Cores cores, - String crashPathInContainer, Path doneCoredumpsPath, Metrics metrics, + String crashPathInContainer, Path doneCoredumpsPath, Metrics metrics, Timer timer, SecretSharedKeySupplier secretSharedKeySupplier, FlagSource flagSource) { this(coreCollector, cores, crashPathInContainer, doneCoredumpsPath, - metrics, Clock.systemUTC(), () -> UUID.randomUUID().toString(), secretSharedKeySupplier, + metrics, timer, () -> UUID.randomUUID().toString(), secretSharedKeySupplier, flagSource); } CoredumpHandler(CoreCollector coreCollector, Cores cores, String crashPathInContainer, Path doneCoredumpsPath, Metrics metrics, - Clock clock, Supplier coredumpIdSupplier, + Timer timer, Supplier coredumpIdSupplier, SecretSharedKeySupplier secretSharedKeySupplier, FlagSource flagSource) { this.coreCollector = coreCollector; this.cores = cores; this.crashPatchInContainer = crashPathInContainer; this.doneCoredumpsPath = doneCoredumpsPath; this.metrics = metrics; - this.clock = clock; + this.timer = timer; this.coredumpIdSupplier = coredumpIdSupplier; this.secretSharedKeySupplier = secretSharedKeySupplier; this.coreEncryptionPublicKeyIdFlag = Flags.CORE_ENCRYPTION_PUBLIC_KEY_ID.bindTo(flagSource); @@ -276,7 +276,7 @@ public class CoredumpHandler { private boolean isReadyForProcessing(FileFinder.FileAttributes fileAttributes) { // Wait at least a minute until we start processing a core/heap dump to ensure that // kernel/JVM has finished writing it - return clock.instant().minusSeconds(60).isAfter(fileAttributes.lastModifiedTime()); + return timer.currentTime().minusSeconds(60).isAfter(fileAttributes.lastModifiedTime()); } void processAndReportSingleCoreDump(NodeAgentContext context, ContainerPath coreDumpDirectory, diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java index 503e69c8f66..f959d1a0ec4 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.node.admin.maintenance.identity; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.jdisc.Timer; import com.yahoo.security.KeyAlgorithm; import com.yahoo.security.KeyUtils; import com.yahoo.security.Pkcs10Csr; @@ -45,7 +46,6 @@ import java.nio.file.Path; import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.X509Certificate; -import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.List; @@ -76,7 +76,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { private final URI ztsEndpoint; private final Path ztsTrustStorePath; - private final Clock clock; + private final Timer timer; private final String certificateDnsSuffix; private final ServiceIdentityProvider hostIdentityProvider; private final IdentityDocumentClient identityDocumentClient; @@ -92,7 +92,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { String certificateDnsSuffix, ServiceIdentityProvider hostIdentityProvider, FlagSource flagSource, - Clock clock) { + Timer timer) { this.ztsEndpoint = ztsEndpoint; this.ztsTrustStorePath = ztsTrustStorePath; this.certificateDnsSuffix = certificateDnsSuffix; @@ -101,7 +101,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { configServerInfo.getLoadBalancerEndpoint(), hostIdentityProvider, new AthenzIdentityVerifier(Set.of(configServerInfo.getConfigServerIdentity()))); - this.clock = clock; + this.timer = timer; this.tenantServiceIdentityFlag = Flags.NODE_ADMIN_TENANT_SERVICE_REGISTRY.bindTo(flagSource); this.useNewIdentityDocumentLayout = Flags.NEW_IDDOC_LAYOUT.bindTo(flagSource); } @@ -144,7 +144,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { } X509Certificate certificate = readCertificateFromFile(certificateFile); - Instant now = clock.instant(); + Instant now = timer.currentTime(); Instant expiry = certificate.getNotAfter().toInstant(); var doc = EntityBindingsMapper.readSignedIdentityDocumentFromFile(identityDocumentFile); if (refreshIdentityDocument(doc, context)) { @@ -208,7 +208,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { private boolean shouldRefreshCertificate(NodeAgentContext context, ContainerPath certificatePath) throws IOException { var certificate = readCertificateFromFile(certificatePath); - var now = clock.instant(); + var now = timer.currentTime(); var shouldRefresh = now.isAfter(certificate.getNotAfter().toInstant()) || now.isBefore(certificate.getNotBefore().toInstant().plus(REFRESH_PERIOD)); return !shouldThrottleRefreshAttempts(context.containerName(), now) && @@ -256,7 +256,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { ContainerPath certificateFile = (ContainerPath) SiaUtils.getCertificateFile(containerSiaDirectory, context.identity()); try { X509Certificate certificate = readCertificateFromFile(certificateFile); - Instant now = clock.instant(); + Instant now = timer.currentTime(); Instant expiry = certificate.getNotAfter().toInstant(); return Duration.between(now, expiry); } catch (IOException e) { diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImpl.java index ea393979bf6..716e2f92e74 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImpl.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.node.admin.maintenance.servicedump; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.CloudName; +import com.yahoo.jdisc.Timer; import com.yahoo.text.Lowercase; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeAttributes; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; @@ -19,7 +20,6 @@ import com.yahoo.yolean.concurrent.Sleeper; import java.io.UncheckedIOException; import java.net.URI; -import java.time.Clock; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -44,20 +44,20 @@ public class VespaServiceDumperImpl implements VespaServiceDumper { private final ContainerOperations container; private final SyncClient syncClient; private final NodeRepository nodeRepository; - private final Clock clock; + private final Timer timer; private final ArtifactProducers artifactProducers; - public VespaServiceDumperImpl(ContainerOperations container, SyncClient syncClient, NodeRepository nodeRepository) { - this(ArtifactProducers.createDefault(Sleeper.DEFAULT), container, syncClient, nodeRepository, Clock.systemUTC()); + public VespaServiceDumperImpl(ContainerOperations container, SyncClient syncClient, NodeRepository nodeRepository, Timer timer) { + this(ArtifactProducers.createDefault(Sleeper.DEFAULT), container, syncClient, nodeRepository, timer); } // For unit testing VespaServiceDumperImpl(ArtifactProducers producers, ContainerOperations container, SyncClient syncClient, - NodeRepository nodeRepository, Clock clock) { + NodeRepository nodeRepository, Timer timer) { this.container = container; this.syncClient = syncClient; this.nodeRepository = nodeRepository; - this.clock = clock; + this.timer = timer; this.artifactProducers = producers; } @@ -65,7 +65,7 @@ public class VespaServiceDumperImpl implements VespaServiceDumper { public void processServiceDumpRequest(NodeAgentContext context) { if (context.zone().getCloudName().equals(CloudName.GCP)) return; - Instant startedAt = clock.instant(); + Instant startedAt = timer.currentTime(); NodeSpec nodeSpec = context.node(); ServiceDumpReport request; try { @@ -119,7 +119,7 @@ public class VespaServiceDumperImpl implements VespaServiceDumper { producedArtifacts.addAll(producer.produceArtifacts(producerCtx)); } uploadArtifacts(context, destination, producedArtifacts); - storeReport(context, ServiceDumpReport.createSuccessReport(request, startedAt, clock.instant(), destination)); + storeReport(context, ServiceDumpReport.createSuccessReport(request, startedAt, timer.currentTime(), destination)); } catch (Exception e) { handleFailure(context, request, startedAt, e, e.getMessage()); } finally { @@ -157,13 +157,13 @@ public class VespaServiceDumperImpl implements VespaServiceDumper { private void handleFailure(NodeAgentContext context, ServiceDumpReport requestOrNull, Instant startedAt, Exception failure, String message) { context.log(log, Level.WARNING, failure.toString(), failure); - ServiceDumpReport report = ServiceDumpReport.createErrorReport(requestOrNull, startedAt, clock.instant(), message); + ServiceDumpReport report = ServiceDumpReport.createErrorReport(requestOrNull, startedAt, timer.currentTime(), message); storeReport(context, report); } private void handleFailure(NodeAgentContext context, ServiceDumpReport requestOrNull, Instant startedAt, String message) { context.log(log, Level.WARNING, message); - ServiceDumpReport report = ServiceDumpReport.createErrorReport(requestOrNull, startedAt, clock.instant(), message); + ServiceDumpReport report = ServiceDumpReport.createErrorReport(requestOrNull, startedAt, timer.currentTime(), message); storeReport(context, report); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java index f168523a1ef..cd7eee8ba50 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.nodeadmin; +import com.yahoo.jdisc.Timer; import com.yahoo.vespa.hosted.node.admin.container.ContainerStats; import com.yahoo.vespa.hosted.node.admin.container.metrics.Counter; import com.yahoo.vespa.hosted.node.admin.container.metrics.Dimensions; @@ -13,7 +14,6 @@ import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentFactory; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentScheduler; import java.nio.file.FileSystem; -import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.HashSet; @@ -37,7 +37,7 @@ public class NodeAdminImpl implements NodeAdmin { private final NodeAgentWithSchedulerFactory nodeAgentWithSchedulerFactory; - private final Clock clock; + private final Timer timer; private final Duration freezeTimeout; private final Duration spread; private boolean previousWantFrozen; @@ -54,27 +54,27 @@ public class NodeAdminImpl implements NodeAdmin { private final Metrics metrics; private Dimensions previousMemoryOverheadDimensions = null; - public NodeAdminImpl(NodeAgentFactory nodeAgentFactory, Metrics metrics, Clock clock, FileSystem fileSystem) { - this(nodeAgentContext -> create(clock, nodeAgentFactory, nodeAgentContext), - metrics, clock, NODE_AGENT_FREEZE_TIMEOUT, NODE_AGENT_SPREAD, new ProcMeminfoReader(fileSystem)); + public NodeAdminImpl(NodeAgentFactory nodeAgentFactory, Metrics metrics, Timer timer, FileSystem fileSystem) { + this(nodeAgentContext -> create(timer, nodeAgentFactory, nodeAgentContext), + metrics, timer, NODE_AGENT_FREEZE_TIMEOUT, NODE_AGENT_SPREAD, new ProcMeminfoReader(fileSystem)); } public NodeAdminImpl(NodeAgentFactory nodeAgentFactory, Metrics metrics, - Clock clock, Duration freezeTimeout, Duration spread, ProcMeminfoReader procMeminfoReader) { - this(nodeAgentContext -> create(clock, nodeAgentFactory, nodeAgentContext), - metrics, clock, freezeTimeout, spread, procMeminfoReader); + Timer timer, Duration freezeTimeout, Duration spread, ProcMeminfoReader procMeminfoReader) { + this(nodeAgentContext -> create(timer, nodeAgentFactory, nodeAgentContext), + metrics, timer, freezeTimeout, spread, procMeminfoReader); } NodeAdminImpl(NodeAgentWithSchedulerFactory nodeAgentWithSchedulerFactory, - Metrics metrics, Clock clock, Duration freezeTimeout, Duration spread, + Metrics metrics, Timer timer, Duration freezeTimeout, Duration spread, ProcMeminfoReader procMeminfoReader) { this.nodeAgentWithSchedulerFactory = nodeAgentWithSchedulerFactory; - this.clock = clock; + this.timer = timer; this.freezeTimeout = freezeTimeout; this.spread = spread; this.previousWantFrozen = true; this.isFrozen = true; - this.startOfFreezeConvergence = clock.instant(); + this.startOfFreezeConvergence = timer.currentTime(); this.numberOfUnhandledExceptions = metrics.declareCounter("unhandled_exceptions", new Dimensions(Map.of("src", "node-agents"))); @@ -104,7 +104,7 @@ public class NodeAdminImpl implements NodeAdmin { }); Duration timeBetweenNodeAgents = spread.dividedBy(Math.max(nodeAgentContextsByHostname.size() - 1, 1)); - Instant nextAgentStart = clock.instant(); + Instant nextAgentStart = timer.currentTime(); // At this point, nodeAgentContextsByHostname and nodeAgentWithSchedulerByHostname should have the same keys for (Map.Entry entry : nodeAgentContextsByHostname.entrySet()) { nodeAgentWithSchedulerByHostname.get(entry.getKey()).scheduleTickWith(entry.getValue(), nextAgentStart); @@ -158,7 +158,7 @@ public class NodeAdminImpl implements NodeAdmin { public boolean setFrozen(boolean wantFrozen) { if (wantFrozen != previousWantFrozen) { if (wantFrozen) { - this.startOfFreezeConvergence = clock.instant(); + this.startOfFreezeConvergence = timer.currentTime(); } else { this.startOfFreezeConvergence = null; } @@ -188,7 +188,7 @@ public class NodeAdminImpl implements NodeAdmin { if (startOfFreezeConvergence == null) { return Duration.ZERO; } else { - return Duration.between(startOfFreezeConvergence, clock.instant()); + return Duration.between(startOfFreezeConvergence, timer.currentTime()); } } @@ -252,8 +252,8 @@ public class NodeAdminImpl implements NodeAdmin { NodeAgentWithScheduler create(NodeAgentContext context); } - private static NodeAgentWithScheduler create(Clock clock, NodeAgentFactory nodeAgentFactory, NodeAgentContext context) { - NodeAgentContextManager contextManager = new NodeAgentContextManager(clock, context); + private static NodeAgentWithScheduler create(Timer timer, NodeAgentFactory nodeAgentFactory, NodeAgentContext context) { + NodeAgentContextManager contextManager = new NodeAgentContextManager(timer, context); NodeAgent nodeAgent = nodeAgentFactory.create(contextManager, context); return new NodeAgentWithScheduler(nodeAgent, contextManager); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManager.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManager.java index 00fe7198667..54d59aac3c8 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManager.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManager.java @@ -1,7 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.nodeagent; -import java.time.Clock; +import com.yahoo.jdisc.Timer; + import java.time.Duration; import java.time.Instant; import java.util.Objects; @@ -14,7 +15,7 @@ import java.util.Objects; public class NodeAgentContextManager implements NodeAgentContextSupplier, NodeAgentScheduler { private final Object monitor = new Object(); - private final Clock clock; + private final Timer timer; private NodeAgentContext currentContext; private NodeAgentContext nextContext; @@ -24,8 +25,8 @@ public class NodeAgentContextManager implements NodeAgentContextSupplier, NodeAg private boolean interrupted = false; private boolean isWaitingForNextContext = false; - public NodeAgentContextManager(Clock clock, NodeAgentContext context) { - this.clock = clock; + public NodeAgentContextManager(Timer timer, NodeAgentContext context) { + this.timer = timer; this.currentContext = context; } @@ -48,8 +49,8 @@ public class NodeAgentContextManager implements NodeAgentContextSupplier, NodeAg boolean successful; long remainder; - long end = clock.instant().plus(timeout).toEpochMilli(); - while (!(successful = isFrozen == frozen) && (remainder = end - clock.millis()) > 0) { + long end = timer.currentTime().plus(timeout).toEpochMilli(); + while (!(successful = isFrozen == frozen) && (remainder = end - timer.currentTimeMillis()) > 0) { try { monitor.wait(remainder); // Wait with timeout until the supplier is has reached wanted frozen state } catch (InterruptedException ignored) { } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java index 025a04a15d6..64efeb85e63 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java @@ -7,6 +7,7 @@ import com.yahoo.config.provision.DockerImage; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.zone.ZoneApi; +import com.yahoo.jdisc.Timer; import com.yahoo.vespa.flags.DoubleFlag; import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.FlagSource; @@ -32,7 +33,6 @@ import com.yahoo.vespa.hosted.node.admin.maintenance.servicedump.VespaServiceDum import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException; import com.yahoo.vespa.hosted.node.admin.task.util.file.FileFinder; -import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -70,7 +70,7 @@ public class NodeAgentImpl implements NodeAgent { private final List credentialsMaintainers; private final Optional aclMaintainer; private final Optional healthChecker; - private final Clock clock; + private final Timer timer; private final Duration warmUpDuration; private final DoubleFlag containerCpuCap; private final VespaServiceDumper serviceDumper; @@ -109,10 +109,10 @@ public class NodeAgentImpl implements NodeAgent { Orchestrator orchestrator, ContainerOperations containerOperations, RegistryCredentialsProvider registryCredentialsProvider, StorageMaintainer storageMaintainer, FlagSource flagSource, List credentialsMaintainers, - Optional aclMaintainer, Optional healthChecker, Clock clock, + Optional aclMaintainer, Optional healthChecker, Timer timer, VespaServiceDumper serviceDumper, List wireguardTasks) { this(contextSupplier, nodeRepository, orchestrator, containerOperations, registryCredentialsProvider, - storageMaintainer, flagSource, credentialsMaintainers, aclMaintainer, healthChecker, clock, + storageMaintainer, flagSource, credentialsMaintainers, aclMaintainer, healthChecker, timer, DEFAULT_WARM_UP_DURATION, serviceDumper, wireguardTasks); } @@ -120,7 +120,7 @@ public class NodeAgentImpl implements NodeAgent { Orchestrator orchestrator, ContainerOperations containerOperations, RegistryCredentialsProvider registryCredentialsProvider, StorageMaintainer storageMaintainer, FlagSource flagSource, List credentialsMaintainers, - Optional aclMaintainer, Optional healthChecker, Clock clock, + Optional aclMaintainer, Optional healthChecker, Timer timer, Duration warmUpDuration, VespaServiceDumper serviceDumper, List wireguardTasks) { this.contextSupplier = contextSupplier; @@ -132,7 +132,7 @@ public class NodeAgentImpl implements NodeAgent { this.credentialsMaintainers = credentialsMaintainers; this.aclMaintainer = aclMaintainer; this.healthChecker = healthChecker; - this.clock = clock; + this.timer = timer; this.warmUpDuration = warmUpDuration; this.containerCpuCap = PermanentFlags.CONTAINER_CPU_CAP.bindTo(flagSource); this.serviceDumper = serviceDumper; @@ -232,7 +232,7 @@ public class NodeAgentImpl implements NodeAgent { Optional report = context.node().reports().getReport(DropDocumentsReport.reportId(), DropDocumentsReport.class); if (report.isPresent() && report.get().startedAt() == null && report.get().readiedAt() != null) { - newNodeAttributes.withReport(DropDocumentsReport.reportId(), report.get().withStartedAt(clock.millis()).toJsonNode()); + newNodeAttributes.withReport(DropDocumentsReport.reportId(), report.get().withStartedAt(timer.currentTimeMillis()).toJsonNode()); changed = true; } @@ -400,7 +400,7 @@ public class NodeAgentImpl implements NodeAgent { ContainerResources wantedContainerResources = getContainerResources(context); if (healthChecker.isPresent() && firstSuccessfulHealthCheckInstant - .map(clock.instant().minus(warmUpDuration(context))::isBefore) + .map(timer.currentTime().minus(warmUpDuration(context))::isBefore) .orElse(true)) return existingContainer; @@ -450,7 +450,7 @@ public class NodeAgentImpl implements NodeAgent { container.ifPresent(c -> removeContainer(context, c, List.of("Dropping documents"), true)); FileFinder.from(context.paths().underVespaHome("var/db/vespa/search")).deleteRecursively(context); nodeRepository.updateNodeAttributes(context.node().hostname(), - new NodeAttributes().withReport(DropDocumentsReport.reportId(), report.get().withDroppedAt(clock.millis()).toJsonNode())); + new NodeAttributes().withReport(DropDocumentsReport.reportId(), report.get().withDroppedAt(timer.currentTimeMillis()).toJsonNode())); } throw ConvergenceException.ofTransient("Documents already dropped, waiting for signal to start the container"); @@ -529,9 +529,9 @@ public class NodeAgentImpl implements NodeAgent { if (healthChecker.isPresent()) { healthChecker.get().verifyHealth(context); if (firstSuccessfulHealthCheckInstant.isEmpty()) - firstSuccessfulHealthCheckInstant = Optional.of(clock.instant()); + firstSuccessfulHealthCheckInstant = Optional.of(timer.currentTime()); - Duration timeLeft = Duration.between(clock.instant(), firstSuccessfulHealthCheckInstant.get().plus(warmUpDuration(context))); + Duration timeLeft = Duration.between(timer.currentTime(), firstSuccessfulHealthCheckInstant.get().plus(warmUpDuration(context))); if (!container.get().resources().equalsCpu(getContainerResources(context))) throw ConvergenceException.ofTransient("Refusing to resume until warm up period ends (" + (timeLeft.isNegative() ? "next tick" : "in " + timeLeft) + ")"); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperationsTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperationsTest.java index 09542c9c10a..567a23ed09d 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperationsTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/ContainerOperationsTest.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.node.admin.container; import com.yahoo.config.provision.DockerImage; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.hosted.node.admin.cgroup.Cgroup; import com.yahoo.vespa.hosted.node.admin.component.TestTaskContext; import com.yahoo.vespa.test.file.TestFileSystem; @@ -26,7 +27,8 @@ public class ContainerOperationsTest { private final TestTaskContext context = new TestTaskContext(); private final ContainerEngineMock containerEngine = new ContainerEngineMock(); private final FileSystem fileSystem = TestFileSystem.create(); - private final ContainerOperations containerOperations = new ContainerOperations(containerEngine, mock(Cgroup.class), fileSystem); + private final TestTimer timer = new TestTimer(); + private final ContainerOperations containerOperations = new ContainerOperations(containerEngine, mock(Cgroup.class), fileSystem, timer); @Test void no_managed_containers_running() { diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePrunerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePrunerTest.java index 2ef6780dff6..79701f59994 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePrunerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/container/image/ContainerImagePrunerTest.java @@ -2,7 +2,7 @@ package com.yahoo.vespa.hosted.node.admin.container.image; import com.yahoo.config.provision.DockerImage; -import com.yahoo.test.ManualClock; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.hosted.node.admin.component.TaskContext; import com.yahoo.vespa.hosted.node.admin.component.TestTaskContext; import com.yahoo.vespa.hosted.node.admin.container.Container; @@ -130,8 +130,8 @@ public class ContainerImagePrunerTest { private final ContainerEngineMock containerEngine = new ContainerEngineMock(); private final TaskContext context = new TestTaskContext(); - private final ManualClock clock = new ManualClock(); - private final ContainerImagePruner pruner = new ContainerImagePruner(containerEngine, clock); + private final TestTimer timer = new TestTimer(); + private final ContainerImagePruner pruner = new ContainerImagePruner(containerEngine, timer); private final Map removalCountByImageId = new HashMap<>(); private boolean initialized = false; @@ -165,7 +165,7 @@ public class ContainerImagePrunerTest { initialized = true; } - clock.advance(Duration.ofMinutes(minutesAfter)); + timer.advance(Duration.ofMinutes(minutesAfter)); pruner.removeUnusedImages(context, excludedRefs, Duration.ofHours(1).minusSeconds(1)); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java index 1fe6081f1b7..b0bcea01f79 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.node.admin.integration; import com.yahoo.config.provision.DockerImage; import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.NodeType; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.hosted.node.admin.cgroup.Cgroup; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec; @@ -30,9 +31,7 @@ import org.mockito.InOrder; import org.mockito.Mockito; import java.nio.file.FileSystem; -import java.time.Clock; import java.time.Duration; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.Phaser; @@ -60,7 +59,8 @@ public class ContainerTester implements AutoCloseable { private final ContainerEngineMock containerEngine = new ContainerEngineMock(); private final FileSystem fileSystem = TestFileSystem.create(); - final ContainerOperations containerOperations = spy(new ContainerOperations(containerEngine, mock(Cgroup.class), fileSystem)); + private final TestTimer timer = new TestTimer(); + final ContainerOperations containerOperations = spy(new ContainerOperations(containerEngine, mock(Cgroup.class), fileSystem, timer)); final NodeRepoMock nodeRepository = spy(new NodeRepoMock()); final Orchestrator orchestrator = mock(Orchestrator.class); final StorageMaintainer storageMaintainer = mock(StorageMaintainer.class); @@ -85,7 +85,6 @@ public class ContainerTester implements AutoCloseable { NodeSpec hostSpec = NodeSpec.Builder.testSpec(HOST_HOSTNAME.value()).type(NodeType.host).build(); nodeRepository.updateNodeSpec(hostSpec); - Clock clock = Clock.systemUTC(); Metrics metrics = new Metrics(); FileSystem fileSystem = TestFileSystem.create(); ProcMeminfoReader procMeminfoReader = mock(ProcMeminfoReader.class); @@ -94,7 +93,7 @@ public class ContainerTester implements AutoCloseable { NodeAgentFactory nodeAgentFactory = (contextSupplier, nodeContext) -> new NodeAgentImpl(contextSupplier, nodeRepository, orchestrator, containerOperations, () -> RegistryCredentials.none, storageMaintainer, flagSource, - Collections.emptyList(), Optional.empty(), Optional.empty(), clock, Duration.ofSeconds(-1), + List.of(), Optional.empty(), Optional.empty(), timer, Duration.ofSeconds(-1), VespaServiceDumper.DUMMY_INSTANCE, List.of()) { @Override public void converge(NodeAgentContext context) { super.converge(context); @@ -109,7 +108,7 @@ public class ContainerTester implements AutoCloseable { phaser.arriveAndDeregister(); } }; - nodeAdmin = new NodeAdminImpl(nodeAgentFactory, metrics, clock, Duration.ofMillis(10), Duration.ZERO, procMeminfoReader); + nodeAdmin = new NodeAdminImpl(nodeAgentFactory, metrics, timer, Duration.ofMillis(10), Duration.ZERO, procMeminfoReader); NodeAgentContextFactory nodeAgentContextFactory = (nodeSpec, acl) -> NodeAgentContextImpl.builder(nodeSpec).acl(acl).fileSystem(fileSystem).build(); nodeAdminStateUpdater = new NodeAdminStateUpdater(nodeAgentContextFactory, nodeRepository, orchestrator, diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java index daae19478ed..1b770788995 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java @@ -2,7 +2,7 @@ package com.yahoo.vespa.hosted.node.admin.maintenance; import com.yahoo.config.provision.NodeResources; -import com.yahoo.test.ManualClock; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec; import com.yahoo.vespa.hosted.node.admin.maintenance.coredump.CoredumpHandler; import com.yahoo.vespa.hosted.node.admin.maintenance.disk.DiskCleanup; @@ -44,9 +44,9 @@ public class StorageMaintainerTest { private final CoredumpHandler coredumpHandler = mock(CoredumpHandler.class); private final DiskCleanup diskCleanup = mock(DiskCleanup.class); private final SyncClient syncClient = mock(SyncClient.class); - private final ManualClock clock = new ManualClock(Instant.ofEpochSecond(1234567890)); + private final TestTimer timer = new TestTimer(Instant.ofEpochSecond(1234567890)); private final FileSystem fileSystem = TestFileSystem.create(); - private final StorageMaintainer storageMaintainer = new StorageMaintainer(terminal, coredumpHandler, diskCleanup, syncClient, clock, + private final StorageMaintainer storageMaintainer = new StorageMaintainer(terminal, coredumpHandler, diskCleanup, syncClient, timer, fileSystem.getPath("/data/vespa/storage/container-archive")); @Test @@ -87,7 +87,7 @@ public class StorageMaintainerTest { // Archive container-1 storageMaintainer.archiveNodeStorage(context1); - clock.advance(Duration.ofSeconds(3)); + timer.advance(Duration.ofSeconds(3)); storageMaintainer.archiveNodeStorage(context1); // container-1 should be gone from container-storage diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandlerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandlerTest.java index b0bd1b7b68f..061eef94c2b 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandlerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoredumpHandlerTest.java @@ -2,10 +2,10 @@ package com.yahoo.vespa.hosted.node.admin.maintenance.coredump; import com.yahoo.config.provision.DockerImage; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.security.KeyId; import com.yahoo.security.SealedSharedKey; import com.yahoo.security.SecretSharedKey; -import com.yahoo.test.ManualClock; import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.hosted.node.admin.configserver.cores.CoreDumpMetadata; @@ -63,14 +63,14 @@ public class CoredumpHandlerTest { private final CoreCollector coreCollector = mock(CoreCollector.class); private final Cores cores = mock(Cores.class); private final Metrics metrics = new Metrics(); - private final ManualClock clock = new ManualClock(); + private final TestTimer timer = new TestTimer(); @SuppressWarnings("unchecked") private final Supplier coredumpIdSupplier = mock(Supplier.class); private final SecretSharedKeySupplier secretSharedKeySupplier = mock(SecretSharedKeySupplier.class); private final InMemoryFlagSource flagSource = new InMemoryFlagSource(); private final CoredumpHandler coredumpHandler = new CoredumpHandler(coreCollector, cores, containerCrashPath.pathInContainer(), - doneCoredumpsPath, metrics, clock, coredumpIdSupplier, secretSharedKeySupplier, + doneCoredumpsPath, metrics, timer, coredumpIdSupplier, secretSharedKeySupplier, flagSource); @Test @@ -86,7 +86,7 @@ public class CoredumpHandlerTest { assertEquals(Optional.empty(), enqueuedPath); // bash.core.431 finished writing... and 2 more have since been written - clock.advance(Duration.ofMinutes(3)); + timer.advance(Duration.ofMinutes(3)); createFileAged(crashPath.resolve("vespa-proton.core.119"), Duration.ofMinutes(10)); createFileAged(crashPath.resolve("vespa-slobrok.core.673"), Duration.ofMinutes(5)); @@ -280,7 +280,7 @@ public class CoredumpHandlerTest { private Path createFileAged(Path path, Duration age) { return uncheck(() -> Files.setLastModifiedTime( Files.createFile(path), - FileTime.from(clock.instant().minus(age)))); + FileTime.from(timer.currentTime().minus(age)))); } private static byte[] bytesOf(String str) { diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java index 554a319f08b..cbe42c90a20 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java @@ -4,7 +4,7 @@ package com.yahoo.vespa.hosted.node.admin.maintenance.servicedump; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.yahoo.test.ManualClock; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeState; import com.yahoo.vespa.hosted.node.admin.container.ContainerOperations; @@ -26,7 +26,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.List; -import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -71,11 +70,11 @@ class VespaServiceDumperImplTest { .thenReturn(new CommandResult(null, 0, "")); SyncClient syncClient = createSyncClientMock(); NodeRepoMock nodeRepository = new NodeRepoMock(); - ManualClock clock = new ManualClock(Instant.ofEpochMilli(1600001000000L)); + TestTimer timer = new TestTimer(Instant.ofEpochMilli(1600001000000L)); NodeSpec nodeSpec = createNodeSpecWithDumpRequest(nodeRepository, List.of("perf-report"), new ServiceDumpReport.DumpOptions(true, 45.0, null)); VespaServiceDumper reporter = new VespaServiceDumperImpl( - ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, clock); + ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, timer); NodeAgentContextImpl context = NodeAgentContextImpl.builder(nodeSpec) .fileSystem(fileSystem) .build(); @@ -112,12 +111,12 @@ class VespaServiceDumperImplTest { .thenReturn(new CommandResult(null, 0, "name=host-admin success")); SyncClient syncClient = createSyncClientMock(); NodeRepoMock nodeRepository = new NodeRepoMock(); - ManualClock clock = new ManualClock(Instant.ofEpochMilli(1600001000000L)); + TestTimer timer = new TestTimer(Instant.ofEpochMilli(1600001000000L)); NodeSpec nodeSpec = createNodeSpecWithDumpRequest( nodeRepository, List.of("jvm-jfr"), new ServiceDumpReport.DumpOptions(null, null, null)); VespaServiceDumper reporter = new VespaServiceDumperImpl( - ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, clock); + ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, timer); NodeAgentContextImpl context = NodeAgentContextImpl.builder(nodeSpec) .fileSystem(fileSystem) .build(); @@ -156,11 +155,11 @@ class VespaServiceDumperImplTest { .thenReturn(new CommandResult(null, 0, "name=host-admin success")); SyncClient syncClient = createSyncClientMock(); NodeRepoMock nodeRepository = new NodeRepoMock(); - ManualClock clock = new ManualClock(Instant.ofEpochMilli(1600001000000L)); + TestTimer timer = new TestTimer(Instant.ofEpochMilli(1600001000000L)); NodeSpec nodeSpec = createNodeSpecWithDumpRequest(nodeRepository, List.of("perf-report", "jvm-jfr"), new ServiceDumpReport.DumpOptions(true, 20.0, null)); VespaServiceDumper reporter = new VespaServiceDumperImpl( - ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, clock); + ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, timer); NodeAgentContextImpl context = NodeAgentContextImpl.builder(nodeSpec) .fileSystem(fileSystem) .build(); @@ -179,7 +178,7 @@ class VespaServiceDumperImplTest { ContainerOperations operations = mock(ContainerOperations.class); SyncClient syncClient = createSyncClientMock(); NodeRepoMock nodeRepository = new NodeRepoMock(); - ManualClock clock = new ManualClock(Instant.ofEpochMilli(1600001000000L)); + TestTimer timer = new TestTimer(Instant.ofEpochMilli(1600001000000L)); JsonNodeFactory fac = new ObjectMapper().getNodeFactory(); ObjectNode invalidRequest = new ObjectNode(fac) .set("dumpOptions", new ObjectNode(fac).put("duration", "invalidDurationDataType")); @@ -189,7 +188,7 @@ class VespaServiceDumperImplTest { .build(); nodeRepository.updateNodeSpec(spec); VespaServiceDumper reporter = new VespaServiceDumperImpl( - ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, clock); + ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, timer); NodeAgentContextImpl context = NodeAgentContextImpl.builder(spec) .fileSystem(fileSystem) .build(); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImplTest.java index 96c18517bfe..7c58007a91a 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImplTest.java @@ -1,7 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.nodeadmin; -import com.yahoo.test.ManualClock; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.hosted.node.admin.container.metrics.Metrics; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContext; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContextImpl; @@ -17,7 +17,9 @@ import java.util.Set; import static com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminImpl.NodeAgentWithScheduler; import static com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminImpl.NodeAgentWithSchedulerFactory; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; @@ -34,10 +36,10 @@ import static org.mockito.Mockito.when; public class NodeAdminImplTest { private final NodeAgentWithSchedulerFactory nodeAgentWithSchedulerFactory = mock(NodeAgentWithSchedulerFactory.class); - private final ManualClock clock = new ManualClock(); + private final TestTimer timer = new TestTimer(); private final ProcMeminfoReader procMeminfoReader = mock(ProcMeminfoReader.class); private final NodeAdminImpl nodeAdmin = new NodeAdminImpl(nodeAgentWithSchedulerFactory, - new Metrics(), clock, Duration.ZERO, Duration.ZERO, procMeminfoReader); + new Metrics(), timer, Duration.ZERO, Duration.ZERO, procMeminfoReader); @Test void nodeAgentsAreProperlyLifeCycleManaged() { @@ -129,19 +131,19 @@ public class NodeAdminImplTest { // Initially everything is frozen to force convergence assertTrue(nodeAdmin.isFrozen()); assertTrue(nodeAdmin.subsystemFreezeDuration().isZero()); - clock.advance(Duration.ofSeconds(1)); + timer.advance(Duration.ofSeconds(1)); assertEquals(Duration.ofSeconds(1), nodeAdmin.subsystemFreezeDuration()); // Unfreezing floors freeze duration assertTrue(nodeAdmin.setFrozen(false)); // Unfreeze everything assertTrue(nodeAdmin.subsystemFreezeDuration().isZero()); - clock.advance(Duration.ofSeconds(1)); + timer.advance(Duration.ofSeconds(1)); assertTrue(nodeAdmin.subsystemFreezeDuration().isZero()); // Advancing time now will make freeze duration proceed according to clock assertTrue(nodeAdmin.setFrozen(true)); assertTrue(nodeAdmin.subsystemFreezeDuration().isZero()); - clock.advance(Duration.ofSeconds(1)); + timer.advance(Duration.ofSeconds(1)); assertEquals(Duration.ofSeconds(1), nodeAdmin.subsystemFreezeDuration()); } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManagerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManagerTest.java index 82c3f79f39f..a0a06f0fb1a 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManagerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextManagerTest.java @@ -1,11 +1,11 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.nodeagent; +import com.yahoo.jdisc.core.SystemTimer; import com.yahoo.vespa.test.file.TestFileSystem; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; -import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.Optional; @@ -13,7 +13,10 @@ import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import static com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContextSupplier.ContextSupplierInterruptedException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author freva @@ -22,15 +25,15 @@ public class NodeAgentContextManagerTest { private static final int TIMEOUT = 10_000; - private final Clock clock = Clock.systemUTC(); + private final SystemTimer timer = new SystemTimer(); private final NodeAgentContext initialContext = generateContext(); - private final NodeAgentContextManager manager = new NodeAgentContextManager(clock, initialContext); + private final NodeAgentContextManager manager = new NodeAgentContextManager(timer, initialContext); @Test @Timeout(TIMEOUT) void context_is_ignored_unless_scheduled_while_waiting() { NodeAgentContext context1 = generateContext(); - manager.scheduleTickWith(context1, clock.instant()); + manager.scheduleTickWith(context1, timer.currentTime()); assertSame(initialContext, manager.currentContext()); AsyncExecutor async = new AsyncExecutor<>(manager::nextContext); @@ -38,7 +41,7 @@ public class NodeAgentContextManagerTest { assertFalse(async.isCompleted()); NodeAgentContext context2 = generateContext(); - manager.scheduleTickWith(context2, clock.instant()); + manager.scheduleTickWith(context2, timer.currentTime()); assertSame(context2, async.awaitResult().response.get()); assertSame(context2, manager.currentContext()); @@ -51,13 +54,13 @@ public class NodeAgentContextManagerTest { manager.waitUntilWaitingForNextContext(); NodeAgentContext context1 = generateContext(); - Instant returnAt = clock.instant().plusMillis(500); + Instant returnAt = timer.currentTime().plusMillis(500); manager.scheduleTickWith(context1, returnAt); assertSame(context1, async.awaitResult().response.get()); assertSame(context1, manager.currentContext()); // Is accurate to a millisecond - assertFalse(clock.instant().plusMillis(1).isBefore(returnAt)); + assertFalse(timer.currentTime().plusMillis(1).isBefore(returnAt)); } @Test @@ -68,7 +71,7 @@ public class NodeAgentContextManagerTest { assertFalse(async.isCompleted()); NodeAgentContext context1 = generateContext(); - manager.scheduleTickWith(context1, clock.instant()); + manager.scheduleTickWith(context1, timer.currentTime()); async.awaitResult(); assertEquals(Optional.of(context1), async.response); @@ -98,7 +101,7 @@ public class NodeAgentContextManagerTest { NodeAgentContext context1 = generateContext(); AsyncExecutor async = new AsyncExecutor<>(manager::nextContext); manager.waitUntilWaitingForNextContext(); - manager.scheduleTickWith(context1, clock.instant()); + manager.scheduleTickWith(context1, timer.currentTime()); assertSame(context1, async.awaitResult().response.get()); assertTrue(manager.setFrozen(false, Duration.ZERO)); @@ -108,9 +111,9 @@ public class NodeAgentContextManagerTest { @Timeout(TIMEOUT) void setFrozen_blocks_at_least_for_duration_of_timeout() { long wantedDurationMillis = 100; - long start = clock.millis(); + long start = timer.currentTimeMillis(); assertFalse(manager.setFrozen(false, Duration.ofMillis(wantedDurationMillis))); - long actualDurationMillis = clock.millis() - start; + long actualDurationMillis = timer.currentTimeMillis() - start; assertTrue(actualDurationMillis >= wantedDurationMillis); } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java index 2db5314dbf2..0913e1d040a 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java @@ -6,7 +6,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.DockerImage; import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.NodeType; -import com.yahoo.test.ManualClock; +import com.yahoo.jdisc.test.TestTimer; import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.flags.PermanentFlags; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeAttributes; @@ -78,7 +78,7 @@ public class NodeAgentImplTest { private final HealthChecker healthChecker = mock(HealthChecker.class); private final CredentialsMaintainer credentialsMaintainer = mock(CredentialsMaintainer.class); private final InMemoryFlagSource flagSource = new InMemoryFlagSource(); - private final ManualClock clock = new ManualClock(Instant.now()); + private final TestTimer timer = new TestTimer(Instant.now()); private final FileSystem fileSystem = TestFileSystem.create(); @BeforeEach @@ -654,7 +654,7 @@ public class NodeAgentImplTest { } catch (ConvergenceException e) { assertEquals(healthCheckException, e); } - clock.advance(Duration.ofSeconds(30)); + timer.advance(Duration.ofSeconds(30)); } doNothing().when(healthChecker).verifyHealth(any()); @@ -669,7 +669,7 @@ public class NodeAgentImplTest { inOrder.verify(containerOperations, never()).updateContainer(any(), any(), any()); - clock.advance(Duration.ofSeconds(31)); + timer.advance(Duration.ofSeconds(31)); nodeAgent.doConverge(context); inOrder.verify(orchestrator, never()).suspend(any()); @@ -739,7 +739,7 @@ public class NodeAgentImplTest { inOrder.verify(containerOperations, never()).updateContainer(any(), any(), any()); - clock.advance(Duration.ofSeconds(31)); + timer.advance(Duration.ofSeconds(31)); nodeAgent.doConverge(context); inOrder.verify(orchestrator, times(1)).resume(eq(hostName)); } @@ -767,7 +767,7 @@ public class NodeAgentImplTest { nodeAgent.converge(context); verify(containerOperations).removeContainer(eq(context), any()); assertFalse(indexPath.exists()); - inOrder.verify(nodeRepository).updateNodeAttributes(eq(hostName), eq(new NodeAttributes().withReport(DropDocumentsReport.reportId(), new DropDocumentsReport(1L, clock.millis(), null, null).toJsonNode()))); + inOrder.verify(nodeRepository).updateNodeAttributes(eq(hostName), eq(new NodeAttributes().withReport(DropDocumentsReport.reportId(), new DropDocumentsReport(1L, timer.currentTimeMillis(), null, null).toJsonNode()))); inOrder.verifyNoMoreInteractions(); // After droppedAt and before readiedAt are set, we cannot proceed @@ -784,13 +784,13 @@ public class NodeAgentImplTest { inOrder.verifyNoMoreInteractions(); mockGetContainer(dockerImage, ContainerResources.from(0, 2, 16), true); - clock.advance(Duration.ofSeconds(31)); + timer.advance(Duration.ofSeconds(31)); nodeAgent.converge(context); verify(containerOperations, times(1)).startContainer(eq(context)); verify(containerOperations, never()).removeContainer(eq(context), any()); inOrder.verify(nodeRepository).updateNodeAttributes(eq(hostName), eq(new NodeAttributes() .withRebootGeneration(0) - .withReport(DropDocumentsReport.reportId(), new DropDocumentsReport(1L, 2L, 3L, clock.millis()).toJsonNode()))); + .withReport(DropDocumentsReport.reportId(), new DropDocumentsReport(1L, 2L, 3L, timer.currentTimeMillis()).toJsonNode()))); inOrder.verifyNoMoreInteractions(); } @@ -844,7 +844,7 @@ public class NodeAgentImplTest { return new NodeAgentImpl(contextSupplier, nodeRepository, orchestrator, containerOperations, () -> RegistryCredentials.none, storageMaintainer, flagSource, List.of(credentialsMaintainer), Optional.of(aclMaintainer), Optional.of(healthChecker), - clock, warmUpDuration, VespaServiceDumper.DUMMY_INSTANCE, List.of()); + timer, warmUpDuration, VespaServiceDumper.DUMMY_INSTANCE, List.of()); } private void mockGetContainer(DockerImage dockerImage, boolean isRunning) { @@ -860,7 +860,7 @@ public class NodeAgentImplTest { Optional.of(new Container( containerId, ContainerName.fromHostname(hostName), - clock.instant(), + timer.currentTime(), isRunning ? Container.State.running : Container.State.exited, "image-id-1", dockerImage, -- cgit v1.2.3