diff options
author | Jon Bratseth <bratseth@gmail.com> | 2023-02-15 13:52:23 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2023-02-15 13:52:23 +0100 |
commit | 4c9206d8119d1131e248419c7e1ba669c396b89b (patch) | |
tree | 414dfdc40c088e06c108e28a7f050bf375ce9d3b /node-repository | |
parent | b9b7e3cf8529e6f7e9904c1013174e37c0460696 (diff) |
Exchange BCP info WIP
Diffstat (limited to 'node-repository')
11 files changed, 186 insertions, 72 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/BcpGroupInfo.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/BcpGroupInfo.java index 6b0ea8532be..e9f3303c9cb 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/BcpGroupInfo.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/BcpGroupInfo.java @@ -27,7 +27,7 @@ public class BcpGroupInfo { this.cpuCostPerQuery = cpuCostPerQuery; } - /** Returns the average query rate (queries/second) of the other clusters in the group this belongs to. */ + /** Returns the max peak query rate (queries/second) of the other clusters in the group this belongs to. */ public double queryRate() { return queryRate; } /** Returns the average growth rate headroom of the other clusters in the group this belongs to. */ diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java index ebab2efbaa6..fd769ec913d 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java @@ -1,6 +1,7 @@ package com.yahoo.vespa.hosted.provision.autoscale; import com.yahoo.config.provision.ClusterResources; +import io.questdb.Metrics; import java.time.Instant; import java.util.Objects; @@ -19,15 +20,17 @@ public class Autoscaling { private final Instant at; private final Load peak; private final Load ideal; + private final Metrics metrics; public Autoscaling(Status status, String description, Optional<ClusterResources> resources, Instant at, - Load peak, Load ideal) { + Load peak, Load ideal, Metrics metrics) { this.status = status; this.description = description; this.resources = resources; this.at = at; this.peak = peak; this.ideal = ideal; + this.metrics = metrics; } public Status status() { return status; } @@ -48,8 +51,10 @@ public class Autoscaling { /** Returns the ideal load the cluster in question should have. */ public Load ideal() { return ideal; } + public Metrics metrics() { return metrics; } + public Autoscaling with(Status status, String description) { - return new Autoscaling(status, description, resources, at, peak, ideal); + return new Autoscaling(status, description, resources, at, peak, ideal, metrics); } /** Converts this autoscaling into an ideal one at the completion of it. */ @@ -59,7 +64,8 @@ public class Autoscaling { Optional.empty(), at, peak, - ideal); + ideal, + metrics); } public boolean isEmpty() { return this.equals(empty()); } @@ -73,12 +79,13 @@ public class Autoscaling { if ( ! this.at.equals(other.at)) return false; if ( ! this.peak.equals(other.peak)) return false; if ( ! this.ideal.equals(other.ideal)) return false; + if ( ! this.metrics.equals(other.metrics)) return false; return true; } @Override public int hashCode() { - return Objects.hash(status, description, at, peak, ideal); + return Objects.hash(status, description, at, peak, ideal, metrics); } @Override @@ -93,7 +100,8 @@ public class Autoscaling { Optional.empty(), Instant.EPOCH, Load.zero(), - Load.zero()); + Load.zero(), + Metrics.zero()); } /** Creates an autoscaling conclusion which does not change the current allocation for a specified reason. */ @@ -103,7 +111,8 @@ public class Autoscaling { Optional.empty(), clusterModel.at(), clusterModel.peakLoad(), - clusterModel.idealLoad()); + clusterModel.idealLoad(), + clusterModel.metrics()); } /** Creates an autoscaling conclusion to scale. */ @@ -113,7 +122,8 @@ public class Autoscaling { Optional.of(target), clusterModel.at(), clusterModel.peakLoad(), - clusterModel.idealLoad()); + clusterModel.idealLoad(), + clusterModel.metrics()); } public enum Status { @@ -133,6 +143,15 @@ public class Autoscaling { /** Rescaling of this cluster has been scheduled */ rescaling - }; + } + + // Used to create BcpGroupInfo + public record Metrics(double queryRate, double growthRateHeadroom, double cpuCostPerQuery) { + + public static Metrics zero() { + return new Metrics(0, 0, 0); + } + + } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java index 4edcdbd3fa5..d122f719eff 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterModel.java @@ -126,14 +126,6 @@ public class ClusterModel { return adjustment; } - public OptionalDouble cpuCostPerQuery() { - if (averageQueryRate().isEmpty()) return OptionalDouble.empty(); - // TODO: Query rate should generally be sampled at the time where we see the peak resource usage - int fanOut = clusterSpec.type().isContainer() ? 1 : groupSize(); - return OptionalDouble.of(peakLoad().cpu() * queryCpuFraction() * fanOut * nodes.not().retired().first().get().resources().vcpu() - / averageQueryRate().getAsDouble() / groupCount()); - } - public boolean isStable(NodeRepository nodeRepository) { // An autoscaling decision was recently made if (hasScaledIn(Duration.ofMinutes(5))) @@ -216,9 +208,23 @@ public class ClusterModel { return ideal; } + public Autoscaling.Metrics metrics() { + return new Autoscaling.Metrics(averageQueryRate().orElse(0), + growthRateHeadroom(), + cpuCostPerQuery().orElse(0)); + } + /** Returns the instant this model was created. */ public Instant at() { return at;} + private OptionalDouble cpuCostPerQuery() { + if (averageQueryRate().isEmpty()) return OptionalDouble.empty(); + // TODO: Query rate should generally be sampled at the time where we see the peak resource usage + int fanOut = clusterSpec.type().isContainer() ? 1 : groupSize(); + return OptionalDouble.of(peakLoad().cpu() * queryCpuFraction() * fanOut * nodes.not().retired().first().get().resources().vcpu() + / averageQueryRate().getAsDouble() / groupCount()); + } + private Load adjustQueryDependentIdealLoadByBcpGroupInfo(Load ideal) { double currentClusterTotalVcpuPerGroup = nodes.not().retired().first().get().resources().vcpu() * groupSize(); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java index 1b73dee8b6c..38675ba3758 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java @@ -64,10 +64,10 @@ public class ApplicationSerializer { private static final String groupsKey = "groups"; private static final String nodeResourcesKey = "resources"; private static final String scalingEventsKey = "scalingEvents"; - private static final String autoscalingStatusObjectKey = "autoscalingStatusObject"; private static final String descriptionKey = "description"; private static final String peakKey = "peak"; private static final String idealKey = "ideal"; + private static final String metricsKey = "metrics"; private static final String cpuKey = "cpu"; private static final String memoryKey = "memory"; private static final String diskKey = "disk"; @@ -146,8 +146,8 @@ public class ApplicationSerializer { clusterResourcesFromSlime(clusterObject.field(maxResourcesKey)), intRangeFromSlime(clusterObject.field(groupSizeKey)), clusterObject.field(requiredKey).asBool(), - autoscalingFromSlime(clusterObject.field(suggestedKey), clusterObject.field("nonExisting")), - autoscalingFromSlime(clusterObject.field(targetKey), clusterObject.field(autoscalingStatusObjectKey)), + autoscalingFromSlime(clusterObject.field(suggestedKey)), + autoscalingFromSlime(clusterObject.field(targetKey)), bcpGroupInfoFromSlime(clusterObject.field(bcpGroupInfoKey)), scalingEventsFromSlime(clusterObject.field(scalingEventsKey))); } @@ -159,6 +159,7 @@ public class ApplicationSerializer { autoscalingObject.setLong(atKey, autoscaling.at().toEpochMilli()); toSlime(autoscaling.peak(), autoscalingObject.setObject(peakKey)); toSlime(autoscaling.ideal(), autoscalingObject.setObject(idealKey)); + toSlime(autoscaling.metrics(), autoscalingObject.setObject(metricsKey)); } private static void toSlime(ClusterResources resources, Cursor clusterResourcesObject) { @@ -200,34 +201,28 @@ public class ApplicationSerializer { loadObject.field(diskKey).asDouble()); } - private static Autoscaling autoscalingFromSlime(Inspector autoscalingObject, - Inspector legacyAutoscalingStatusObject) { - if ( ! autoscalingObject.valid()) return Autoscaling.empty(); + private static void toSlime(Autoscaling.Metrics metrics, Cursor metricsObject) { + metricsObject.setDouble(queryRateKey, metrics.queryRate()); + metricsObject.setDouble(growthRateHeadroomKey, metrics.growthRateHeadroom()); + metricsObject.setDouble(cpuCostPerQueryKey, metrics.cpuCostPerQuery()); + } - if ( ! autoscalingObject.field(atKey).valid()) { // TODO: Remove after January 2023 - return new Autoscaling(fromAutoscalingStatusCode(legacyAutoscalingStatusObject.field(statusKey).asString()), - legacyAutoscalingStatusObject.field(descriptionKey).asString(), - optionalClusterResourcesFromSlime(autoscalingObject), - Instant.EPOCH, - Load.zero(), - Load.zero()); - } + private static Autoscaling.Metrics metricsFromSlime(Inspector metricsObject) { + return new Autoscaling.Metrics(metricsObject.field(queryRateKey).asDouble(), + metricsObject.field(growthRateHeadroomKey).asDouble(), + metricsObject.field(cpuCostPerQueryKey).asDouble()); + } - if (legacyAutoscalingStatusObject.valid()) { // TODO: Remove after January 2023 - return new Autoscaling(fromAutoscalingStatusCode(legacyAutoscalingStatusObject.field(statusKey).asString()), - legacyAutoscalingStatusObject.field(descriptionKey).asString(), - optionalClusterResourcesFromSlime(autoscalingObject.field(resourcesKey)), - Instant.ofEpochMilli(autoscalingObject.field(atKey).asLong()), - loadFromSlime(autoscalingObject.field(peakKey)), - loadFromSlime(autoscalingObject.field(idealKey))); - } + private static Autoscaling autoscalingFromSlime(Inspector autoscalingObject) { + if ( ! autoscalingObject.valid()) return Autoscaling.empty(); return new Autoscaling(fromAutoscalingStatusCode(autoscalingObject.field(statusKey).asString()), autoscalingObject.field(descriptionKey).asString(), optionalClusterResourcesFromSlime(autoscalingObject.field(resourcesKey)), Instant.ofEpochMilli(autoscalingObject.field(atKey).asLong()), loadFromSlime(autoscalingObject.field(peakKey)), - loadFromSlime(autoscalingObject.field(idealKey))); + loadFromSlime(autoscalingObject.field(idealKey)), + metricsFromSlime(autoscalingObject.field(metricsKey))); } private static void toSlime(BcpGroupInfo bcpGroupInfo, Cursor bcpGroupInfoObject) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcher.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcher.java index 871f30570f5..f4022570a9b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcher.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcher.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.provision.restapi; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.io.IOUtils; import com.yahoo.slime.Inspector; import com.yahoo.slime.SlimeUtils; @@ -9,11 +10,14 @@ import com.yahoo.slime.Type; import com.yahoo.transaction.Mutex; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.applications.Application; +import com.yahoo.vespa.hosted.provision.applications.BcpGroupInfo; +import com.yahoo.vespa.hosted.provision.applications.Cluster; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.time.Duration; +import java.util.Optional; /** * A class which can take a partial JSON node/v2 application JSON structure and apply it to an application object. @@ -47,13 +51,9 @@ public class ApplicationPatcher implements AutoCloseable { /** Applies the json to the application and returns it. */ public Application apply() { - inspector.traverse((String name, Inspector value) -> { - try { - application = applyField(application, name, value); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Could not set field '" + name + "'", e); - } - }); + inspector.field("currentReadShare").ifValid(v -> application = application.with(application.status().withCurrentReadShare(asDouble(v)))); + inspector.field("maxReadShare").ifValid(v -> application = application.with(application.status().withMaxReadShare(asDouble(v)))); + inspector.field("clusters").ifValid(cluster -> application = applyClustersField(cluster)); return application; } @@ -67,13 +67,20 @@ public class ApplicationPatcher implements AutoCloseable { lock.close(); } - private Application applyField(Application application, String name, Inspector value) { - return switch (name) { - case "currentReadShare" -> application.with(application.status().withCurrentReadShare(asDouble(value))); - case "maxReadShare" -> application.with(application.status().withMaxReadShare(asDouble(value))); - default -> throw new IllegalArgumentException("Could not apply field '" + name + - "' on an application: No such modifiable field"); - }; + private Application applyClustersField(Inspector clusters) { + clusters.traverse((String key, Inspector cluster) -> application = applyClusterField(key, cluster)); + return application; + } + + private Application applyClusterField(String id, Inspector clusterObject) { + Optional<Cluster> cluster = application.cluster(ClusterSpec.Id.from(id)); + if (cluster.isEmpty()) return application; + Inspector bcpGroupInfoObject = clusterObject.field("bcpGroupInfo"); + if ( ! bcpGroupInfoObject.valid()) return application; + double queryRate = bcpGroupInfoObject.field("queryRate").asDouble(); + double growthRateHeadroom = bcpGroupInfoObject.field("growthRateHeadroom").asDouble(); + double cpuCostPerQuery = bcpGroupInfoObject.field("cpuCostPerQuery").asDouble(); + return application.with(cluster.get().with(new BcpGroupInfo(queryRate, growthRateHeadroom, cpuCostPerQuery))); } private Double asDouble(Inspector field) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java index 8a82069c2b6..7cf284eca3b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java @@ -80,6 +80,7 @@ public class ApplicationSerializer { autoscalingObject.setLong("at", autoscaling.at().toEpochMilli()); toSlime(autoscaling.peak(), autoscalingObject.setObject("peak")); toSlime(autoscaling.ideal(), autoscalingObject.setObject("ideal")); + toSlime(autoscaling.metrics(), autoscalingObject.setObject("metrics")); } private static void toSlime(ClusterResources resources, Cursor clusterResourcesObject) { @@ -93,10 +94,16 @@ public class ApplicationSerializer { range.to().ifPresent(to -> rangeObject.setLong("to", range.to().getAsInt())); } - private static void toSlime(Load load, Cursor utilizationObject) { - utilizationObject.setDouble("cpu", load.cpu()); - utilizationObject.setDouble("memory", load.memory()); - utilizationObject.setDouble("disk", load.disk()); + private static void toSlime(Load load, Cursor loadObject) { + loadObject.setDouble("cpu", load.cpu()); + loadObject.setDouble("memory", load.memory()); + loadObject.setDouble("disk", load.disk()); + } + + private static void toSlime(Autoscaling.Metrics metrics, Cursor metricsObject) { + metricsObject.setDouble("queryRate", metrics.queryRate()); + metricsObject.setDouble("growthRateHeadroom", metrics.growthRateHeadroom()); + metricsObject.setDouble("cpuCostPerQuery", metrics.cpuCostPerQuery()); } private static void scalingEventsToSlime(List<ScalingEvent> scalingEvents, Cursor scalingEventsArray) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java index 7127cd401e8..d27bd3aea4a 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java @@ -216,14 +216,16 @@ public class MockNodeRepository extends NodeRepository { new NodeResources(3, 20, 100, 1))), clock().instant(), Load.zero(), - Load.zero())); + Load.zero(), + Autoscaling.Metrics.zero())); cluster1 = cluster1.withTarget(new Autoscaling(Autoscaling.Status.unavailable, "", Optional.of(new ClusterResources(4, 1, new NodeResources(3, 16, 100, 1))), clock().instant(), - Load.zero(), - Load.zero())); + new Load(0.1, 0.2, 0.3), + new Load(0.4, 0.5, 0.6), + new Autoscaling.Metrics(0.7, 0.8, 0.9))); try (Mutex lock = applications().lock(app1Id)) { applications().put(app1.with(cluster1), lock); } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java index c8dc0d97320..d04fe1bdda2 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java @@ -55,14 +55,16 @@ public class ApplicationSerializerTest { new NodeResources(0.5, 4, 14, 16))), Instant.ofEpochMilli(1234L), new Load(0.1, 0.2, 0.3), - new Load(0.4, 0.5, 0.6)), + new Load(0.4, 0.5, 0.6), + new Autoscaling.Metrics(0.7, 0.8, 0.9)), new Autoscaling(Autoscaling.Status.insufficient, "Autoscaling status", Optional.of(new ClusterResources(10, 5, new NodeResources(2, 4, 14, 16))), Instant.ofEpochMilli(5678L), Load.zero(), - Load.one()), + Load.one(), + Autoscaling.Metrics.zero()), new BcpGroupInfo(0.1, 0.2, 0.3), List.of(new ScalingEvent(new ClusterResources(10, 5, minResources), new ClusterResources(12, 6, minResources), diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcherTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcherTest.java index 79722a747e2..200187ea5d6 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcherTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationPatcherTest.java @@ -2,14 +2,20 @@ package com.yahoo.vespa.hosted.provision.restapi; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.vespa.hosted.provision.NodeRepository; +import com.yahoo.config.provision.Capacity; +import com.yahoo.config.provision.ClusterResources; +import com.yahoo.config.provision.ClusterSpec; +import com.yahoo.config.provision.NodeResources; import com.yahoo.vespa.hosted.provision.NodeRepositoryTester; import com.yahoo.vespa.hosted.provision.applications.Application; +import com.yahoo.vespa.hosted.provision.applications.BcpGroupInfo; +import com.yahoo.vespa.hosted.provision.applications.Cluster; import org.junit.Test; import java.io.ByteArrayInputStream; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * @author bratseth @@ -26,8 +32,63 @@ public class ApplicationPatcherTest { application.id(), tester.nodeRepository()); Application patched = patcher.apply(); - assertEquals(0.4, patcher.application().status().currentReadShare(), 0.0000001); - assertEquals(1.0, patcher.application().status().maxReadShare(), 0.0000001); + assertEquals(0.4, patched.status().currentReadShare(), 0.0000001); + assertEquals(1.0, patched.status().maxReadShare(), 0.0000001); + patcher.close(); + } + + @Test + public void testPatchingWithBcpGroupInfo() { + var c1 = ClusterSpec.Id.from("c1"); + var c2 = ClusterSpec.Id.from("c2"); + var capacity = Capacity.from(new ClusterResources(10, 1, new NodeResources(1.0, 10.0, 100.0, 3.0))); + NodeRepositoryTester tester = new NodeRepositoryTester(); + Application application = Application.empty(ApplicationId.from("t1", "a1", "i1")); + application = application.with(Cluster.create(c1, false, capacity)); + application = application.with(Cluster.create(c2, false, capacity)); + tester.nodeRepository().applications().put(application, tester.nodeRepository().applications().lock(application.id())); + + String patch = """ + { + "currentReadShare": 0.4, + "maxReadShare": 1.0, + "clusters": { + "c1": { + "bcpGroupInfo": { + "queryRate": 0.1, + "growthRateHeadroom": 0.2, + "cpuCostPerQuery": 0.3 + } + }, + "c2": { + "bcpGroupInfo": { + "queryRate": 1, + "growthRateHeadroom": 2, + "cpuCostPerQuery": 3 + } + }, + "ignored": { + "bcpGroupInfo": { + "queryRate": 1, + "growthRateHeadroom": 2, + "cpuCostPerQuery": 3 + } + } + } + } + """; + + ApplicationPatcher patcher = new ApplicationPatcher(new ByteArrayInputStream(patch.getBytes()), + application.id(), + tester.nodeRepository()); + Application patched = patcher.apply(); + assertEquals(0.4, patched.status().currentReadShare(), 0.0000001); + assertEquals(1.0, patched.status().maxReadShare(), 0.0000001); + assertEquals(new BcpGroupInfo(0.1, 0.2, 0.3), + patched.cluster(c1).get().bcpGroupInfo()); + assertEquals(new BcpGroupInfo(1.0, 2.0, 3.0), + patched.cluster(c2).get().bcpGroupInfo()); + assertTrue(patched.cluster(ClusterSpec.Id.from("ignored")).isEmpty()); patcher.close(); } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json index c9046998e91..4c18b614075 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json @@ -69,6 +69,11 @@ "cpu" : 0.0, "memory" : 0.0, "disk" : 0.0 + }, + "metrics" : { + "queryRate" : 0.0, + "growthRateHeadroom" : 0.0, + "cpuCostPerQuery" : 0.0 } }, "target" : { @@ -89,14 +94,19 @@ }, "at" : 123, "peak" : { - "cpu" : 0.0, - "memory" : 0.0, - "disk" : 0.0 + "cpu" : 0.1, + "memory" : 0.2, + "disk" : 0.3 }, "ideal" : { - "cpu" : 0.0, - "memory" : 0.0, - "disk" : 0.0 + "cpu" : 0.4, + "memory" : 0.5, + "disk" : 0.6 + }, + "metrics" : { + "queryRate" : 0.7, + "growthRateHeadroom" : 0.8, + "cpuCostPerQuery" : 0.9 } }, "scalingEvents" : [ diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json index 4166d20ad8d..ea4d5e01ebc 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json @@ -56,6 +56,11 @@ "cpu" : 0.0, "memory" : 0.0, "disk" : 0.0 + }, + "metrics" : { + "queryRate" : 0.0, + "growthRateHeadroom" : 0.0, + "cpuCostPerQuery" : 0.0 } }, "scalingEvents" : [ |